Convert an address in the binary to a source address location.
(executable string, address uint64)
| 294 | |
| 295 | // Convert an address in the binary to a source address location. |
| 296 | func addressToLine(executable string, address uint64) (token.Position, error) { |
| 297 | data, err := readDWARF(executable) |
| 298 | if err != nil { |
| 299 | return token.Position{}, err |
| 300 | } |
| 301 | r := data.Reader() |
| 302 | |
| 303 | for { |
| 304 | e, err := r.Next() |
| 305 | if err != nil { |
| 306 | return token.Position{}, err |
| 307 | } |
| 308 | if e == nil { |
| 309 | break |
| 310 | } |
| 311 | switch e.Tag { |
| 312 | case dwarf.TagCompileUnit: |
| 313 | r.SkipChildren() |
| 314 | lr, err := data.LineReader(e) |
| 315 | if err != nil { |
| 316 | return token.Position{}, err |
| 317 | } |
| 318 | var lineEntry = dwarf.LineEntry{ |
| 319 | EndSequence: true, |
| 320 | } |
| 321 | for { |
| 322 | // Read the next .debug_line entry. |
| 323 | prevLineEntry := lineEntry |
| 324 | err := lr.Next(&lineEntry) |
| 325 | if err != nil { |
| 326 | if err == io.EOF { |
| 327 | break |
| 328 | } |
| 329 | return token.Position{}, err |
| 330 | } |
| 331 | |
| 332 | if prevLineEntry.EndSequence && lineEntry.Address == 0 { |
| 333 | // Tombstone value. This symbol has been removed, for |
| 334 | // example by the --gc-sections linker flag. It is still |
| 335 | // here in the debug information because the linker can't |
| 336 | // just remove this reference. |
| 337 | // Read until the next EndSequence so that this sequence is |
| 338 | // skipped. |
| 339 | // For more details, see (among others): |
| 340 | // https://reviews.llvm.org/D84825 |
| 341 | for { |
| 342 | err := lr.Next(&lineEntry) |
| 343 | if err != nil { |
| 344 | return token.Position{}, err |
| 345 | } |
| 346 | if lineEntry.EndSequence { |
| 347 | break |
| 348 | } |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | if !prevLineEntry.EndSequence { |
| 353 | // The chunk describes the code from prevLineEntry to |