readProgramSizeFromDWARF reads the source location for each line of code and each variable in the program, as far as this is stored in the DWARF debug information.
(data *dwarf.Data, codeOffset, codeAlignment uint64, skipTombstone bool)
| 168 | // each variable in the program, as far as this is stored in the DWARF debug |
| 169 | // information. |
| 170 | func readProgramSizeFromDWARF(data *dwarf.Data, codeOffset, codeAlignment uint64, skipTombstone bool) ([]addressLine, error) { |
| 171 | r := data.Reader() |
| 172 | var lines []*dwarf.LineFile |
| 173 | var addresses []addressLine |
| 174 | for { |
| 175 | e, err := r.Next() |
| 176 | if err != nil { |
| 177 | return nil, err |
| 178 | } |
| 179 | if e == nil { |
| 180 | break |
| 181 | } |
| 182 | switch e.Tag { |
| 183 | case dwarf.TagCompileUnit: |
| 184 | // Found a compile unit. |
| 185 | // We can read the .debug_line section using it, which contains a |
| 186 | // mapping for most instructions to their file/line/column - even |
| 187 | // for inlined functions! |
| 188 | lr, err := data.LineReader(e) |
| 189 | if err != nil { |
| 190 | return nil, err |
| 191 | } |
| 192 | lines = lr.Files() |
| 193 | var lineEntry = dwarf.LineEntry{ |
| 194 | EndSequence: true, |
| 195 | } |
| 196 | |
| 197 | // Line tables are organized as sequences of line entries until an |
| 198 | // end sequence. A single line table can contain multiple such |
| 199 | // sequences. The last line entry is an EndSequence to indicate the |
| 200 | // end. |
| 201 | for { |
| 202 | // Read the next .debug_line entry. |
| 203 | prevLineEntry := lineEntry |
| 204 | err := lr.Next(&lineEntry) |
| 205 | if err != nil { |
| 206 | if err == io.EOF { |
| 207 | break |
| 208 | } |
| 209 | return nil, err |
| 210 | } |
| 211 | |
| 212 | if prevLineEntry.EndSequence && lineEntry.Address == 0 && skipTombstone { |
| 213 | // Tombstone value. This symbol has been removed, for |
| 214 | // example by the --gc-sections linker flag. It is still |
| 215 | // here in the debug information because the linker can't |
| 216 | // just remove this reference. |
| 217 | // Read until the next EndSequence so that this sequence is |
| 218 | // skipped. |
| 219 | // For more details, see (among others): |
| 220 | // https://reviews.llvm.org/D84825 |
| 221 | // The value 0 can however really occur in object files, |
| 222 | // that typically start at address 0. So don't skip |
| 223 | // tombstone values in object files (like when parsing MachO |
| 224 | // files). |
| 225 | for { |
| 226 | err := lr.Next(&lineEntry) |
| 227 | if err != nil { |
no test coverage detected