Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // -*- mode: C++ -*- | 1 // -*- mode: C++ -*- |
| 2 | 2 |
| 3 // Copyright (c) 2010 Google Inc. All Rights Reserved. | 3 // Copyright (c) 2010 Google Inc. All Rights Reserved. |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 #ifndef COMMON_DWARF_DWARF2READER_H__ | 40 #ifndef COMMON_DWARF_DWARF2READER_H__ |
| 41 #define COMMON_DWARF_DWARF2READER_H__ | 41 #define COMMON_DWARF_DWARF2READER_H__ |
| 42 | 42 |
| 43 #include <stdint.h> | 43 #include <stdint.h> |
| 44 | 44 |
| 45 #include <list> | 45 #include <list> |
| 46 #include <map> | 46 #include <map> |
| 47 #include <string> | 47 #include <string> |
| 48 #include <utility> | 48 #include <utility> |
| 49 #include <vector> | 49 #include <vector> |
| 50 #include <memory> | |
| 50 | 51 |
| 51 #include "common/dwarf/bytereader.h" | 52 #include "common/dwarf/bytereader.h" |
| 52 #include "common/dwarf/dwarf2enums.h" | 53 #include "common/dwarf/dwarf2enums.h" |
| 53 #include "common/dwarf/types.h" | 54 #include "common/dwarf/types.h" |
| 54 #include "common/using_std_string.h" | 55 #include "common/using_std_string.h" |
| 56 #include "common/dwarf/elf_reader.h" | |
| 55 | 57 |
| 56 namespace dwarf2reader { | 58 namespace dwarf2reader { |
| 57 struct LineStateMachine; | 59 struct LineStateMachine; |
| 58 class Dwarf2Handler; | 60 class Dwarf2Handler; |
| 59 class LineInfoHandler; | 61 class LineInfoHandler; |
| 62 class DwpReader; | |
| 60 | 63 |
| 61 // This maps from a string naming a section to a pair containing a | 64 // This maps from a string naming a section to a pair containing a |
| 62 // the data for the section, and the size of the section. | 65 // the data for the section, and the size of the section. |
| 63 typedef std::map<string, std::pair<const uint8_t *, uint64> > SectionMap; | 66 typedef std::map<string, std::pair<const uint8_t *, uint64> > SectionMap; |
| 64 typedef std::list<std::pair<enum DwarfAttribute, enum DwarfForm> > | 67 typedef std::list<std::pair<enum DwarfAttribute, enum DwarfForm> > |
| 65 AttributeList; | 68 AttributeList; |
| 66 typedef AttributeList::iterator AttributeIterator; | 69 typedef AttributeList::iterator AttributeIterator; |
| 67 typedef AttributeList::const_iterator ConstAttributeIterator; | 70 typedef AttributeList::const_iterator ConstAttributeIterator; |
| 68 | 71 |
| 69 struct LineInfoHeader { | 72 struct LineInfoHeader { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 // Called when the line info reader has a new line, address pair | 180 // Called when the line info reader has a new line, address pair |
| 178 // ready for us. ADDRESS is the address of the code, LENGTH is the | 181 // ready for us. ADDRESS is the address of the code, LENGTH is the |
| 179 // length of its machine code in bytes, FILE_NUM is the file number | 182 // length of its machine code in bytes, FILE_NUM is the file number |
| 180 // containing the code, LINE_NUM is the line number in that file for | 183 // containing the code, LINE_NUM is the line number in that file for |
| 181 // the code, and COLUMN_NUM is the column number the code starts at, | 184 // the code, and COLUMN_NUM is the column number the code starts at, |
| 182 // if we know it (0 otherwise). | 185 // if we know it (0 otherwise). |
| 183 virtual void AddLine(uint64 address, uint64 length, | 186 virtual void AddLine(uint64 address, uint64 length, |
| 184 uint32 file_num, uint32 line_num, uint32 column_num) { } | 187 uint32 file_num, uint32 line_num, uint32 column_num) { } |
| 185 }; | 188 }; |
| 186 | 189 |
| 190 | |
|
vapier
2016/04/14 22:48:48
just one blank line here
yunlian
2016/04/18 21:20:52
Done.
| |
| 191 // This class is the main interface between the reader and the | |
| 192 // client. The virtual functions inside this get called for | |
| 193 // interesting events that happen during DWARF2 reading. | |
| 194 // The default implementation skips everything. | |
| 195 | |
| 196 class Dwarf2Handler { | |
| 197 public: | |
| 198 Dwarf2Handler() { } | |
| 199 | |
| 200 virtual ~Dwarf2Handler() { } | |
| 201 | |
| 202 // Start to process a compilation unit at OFFSET from the beginning of the | |
| 203 // .debug_info section. Return false if you would like to skip this | |
| 204 // compilation unit. | |
| 205 virtual bool StartCompilationUnit(uint64 offset, uint8 address_size, | |
| 206 uint8 offset_size, uint64 cu_length, | |
| 207 uint8 dwarf_version) { return false; } | |
| 208 | |
| 209 // When processing a skeleton compilation unit, resulting from a split | |
| 210 // DWARF compilation, once the skeleton debug info has been read, | |
| 211 // the reader will call this function to ask the client if it needs | |
| 212 // the full debug info from the .dwo or .dwp file. Return true if | |
| 213 // you need it, or false to skip processing the split debug info. | |
| 214 virtual bool NeedSplitDebugInfo() { return true; } | |
| 215 | |
| 216 // Start to process a split compilation unit at OFFSET from the beginning of | |
| 217 // the debug_info section in the .dwp/.dwo file. Return false if you would | |
| 218 // like to skip this compilation unit. | |
| 219 virtual bool StartSplitCompilationUnit(uint64 offset, | |
| 220 uint64 cu_length) { return false; } | |
| 221 | |
| 222 // Start to process a DIE at OFFSET from the beginning of the .debug_info | |
| 223 // section. Return false if you would like to skip this DIE. | |
| 224 virtual bool StartDIE(uint64 offset, enum DwarfTag tag) { return false; } | |
| 225 | |
| 226 // Called when we have an attribute with unsigned data to give to our | |
| 227 // handler. The attribute is for the DIE at OFFSET from the beginning of the | |
| 228 // .debug_info section. Its name is ATTR, its form is FORM, and its value is | |
| 229 // DATA. | |
| 230 virtual void ProcessAttributeUnsigned(uint64 offset, | |
| 231 enum DwarfAttribute attr, | |
| 232 enum DwarfForm form, | |
| 233 uint64 data) { } | |
| 234 | |
| 235 // Called when we have an attribute with signed data to give to our handler. | |
| 236 // The attribute is for the DIE at OFFSET from the beginning of the | |
| 237 // .debug_info section. Its name is ATTR, its form is FORM, and its value is | |
| 238 // DATA. | |
| 239 virtual void ProcessAttributeSigned(uint64 offset, | |
| 240 enum DwarfAttribute attr, | |
| 241 enum DwarfForm form, | |
| 242 int64 data) { } | |
| 243 | |
| 244 // Called when we have an attribute whose value is a reference to | |
| 245 // another DIE. The attribute belongs to the DIE at OFFSET from the | |
| 246 // beginning of the .debug_info section. Its name is ATTR, its form | |
| 247 // is FORM, and the offset of the DIE being referred to from the | |
| 248 // beginning of the .debug_info section is DATA. | |
| 249 virtual void ProcessAttributeReference(uint64 offset, | |
| 250 enum DwarfAttribute attr, | |
| 251 enum DwarfForm form, | |
| 252 uint64 data) { } | |
| 253 | |
| 254 // Called when we have an attribute with a buffer of data to give to our | |
| 255 // handler. The attribute is for the DIE at OFFSET from the beginning of the | |
| 256 // .debug_info section. Its name is ATTR, its form is FORM, DATA points to | |
| 257 // the buffer's contents, and its length in bytes is LENGTH. The buffer is | |
| 258 // owned by the caller, not the callee, and may not persist for very long. | |
| 259 // If you want the data to be available later, it needs to be copied. | |
| 260 virtual void ProcessAttributeBuffer(uint64 offset, | |
| 261 enum DwarfAttribute attr, | |
| 262 enum DwarfForm form, | |
| 263 const uint8_t *data, | |
| 264 uint64 len) { } | |
| 265 | |
| 266 // Called when we have an attribute with string data to give to our handler. | |
| 267 // The attribute is for the DIE at OFFSET from the beginning of the | |
| 268 // .debug_info section. Its name is ATTR, its form is FORM, and its value is | |
| 269 // DATA. | |
| 270 virtual void ProcessAttributeString(uint64 offset, | |
| 271 enum DwarfAttribute attr, | |
| 272 enum DwarfForm form, | |
| 273 const string& data) { } | |
| 274 | |
| 275 // Called when we have an attribute whose value is the 64-bit signature | |
| 276 // of a type unit in the .debug_types section. OFFSET is the offset of | |
| 277 // the DIE whose attribute we're reporting. ATTR and FORM are the | |
| 278 // attribute's name and form. SIGNATURE is the type unit's signature. | |
| 279 virtual void ProcessAttributeSignature(uint64 offset, | |
| 280 enum DwarfAttribute attr, | |
| 281 enum DwarfForm form, | |
| 282 uint64 signature) { } | |
| 283 | |
| 284 // Called when finished processing the DIE at OFFSET. | |
| 285 // Because DWARF2/3 specifies a tree of DIEs, you may get starts | |
| 286 // before ends of the previous DIE, as we process children before | |
| 287 // ending the parent. | |
| 288 virtual void EndDIE(uint64 offset) { } | |
| 289 | |
| 290 }; | |
| 291 | |
| 292 | |
| 293 | |
|
vapier
2016/04/14 22:48:47
just one blank line here
yunlian
2016/04/18 21:20:52
Done.
| |
| 187 // The base of DWARF2/3 debug info is a DIE (Debugging Information | 294 // The base of DWARF2/3 debug info is a DIE (Debugging Information |
| 188 // Entry. | 295 // Entry. |
| 189 // DWARF groups DIE's into a tree and calls the root of this tree a | 296 // DWARF groups DIE's into a tree and calls the root of this tree a |
| 190 // "compilation unit". Most of the time, there is one compilation | 297 // "compilation unit". Most of the time, there is one compilation |
| 191 // unit in the .debug_info section for each file that had debug info | 298 // unit in the .debug_info section for each file that had debug info |
| 192 // generated. | 299 // generated. |
| 193 // Each DIE consists of | 300 // Each DIE consists of |
| 194 | 301 |
| 195 // 1. a tag specifying a thing that is being described (ie | 302 // 1. a tag specifying a thing that is being described (ie |
| 196 // DW_TAG_subprogram for functions, DW_TAG_variable for variables, etc | 303 // DW_TAG_subprogram for functions, DW_TAG_variable for variables, etc |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 218 // units, such as base types, etc. GCC 3.4+ support this with | 325 // units, such as base types, etc. GCC 3.4+ support this with |
| 219 // -feliminate-dwarf2-dups. Other toolchains will sometimes do | 326 // -feliminate-dwarf2-dups. Other toolchains will sometimes do |
| 220 // duplicate elimination in the linker. | 327 // duplicate elimination in the linker. |
| 221 | 328 |
| 222 class CompilationUnit { | 329 class CompilationUnit { |
| 223 public: | 330 public: |
| 224 | 331 |
| 225 // Initialize a compilation unit. This requires a map of sections, | 332 // Initialize a compilation unit. This requires a map of sections, |
| 226 // the offset of this compilation unit in the .debug_info section, a | 333 // the offset of this compilation unit in the .debug_info section, a |
| 227 // ByteReader, and a Dwarf2Handler class to call callbacks in. | 334 // ByteReader, and a Dwarf2Handler class to call callbacks in. |
| 228 CompilationUnit(const SectionMap& sections, uint64 offset, | 335 CompilationUnit(const string& path, const SectionMap& sections, uint64 offset, |
| 229 ByteReader* reader, Dwarf2Handler* handler); | 336 ByteReader* reader, Dwarf2Handler* handler); |
| 230 virtual ~CompilationUnit() { | 337 virtual ~CompilationUnit() { |
| 231 if (abbrevs_) delete abbrevs_; | 338 if (abbrevs_) delete abbrevs_; |
| 232 } | 339 } |
| 233 | 340 |
| 341 // Initialize a compilation unit from a .dwo or .dwp file. | |
| 342 // In this case, we need the .debug_addr section from the | |
| 343 // executable file that contains the corresponding skeleton | |
| 344 // compilation unit. We also inherit the Dwarf2Handler from | |
| 345 // the executable file, and call it as if we were still | |
| 346 // processing the original compilation unit. | |
| 347 void SetSplitDwarf(const uint8_t* addr_buffer, uint64 addr_buffer_length, | |
| 348 uint64 addr_base, uint64 ranges_base, uint64 dwo_id); | |
| 349 | |
| 234 // Begin reading a Dwarf2 compilation unit, and calling the | 350 // Begin reading a Dwarf2 compilation unit, and calling the |
| 235 // callbacks in the Dwarf2Handler | 351 // callbacks in the Dwarf2Handler |
| 236 | 352 |
| 237 // Return the full length of the compilation unit, including | 353 // Return the full length of the compilation unit, including |
| 238 // headers. This plus the starting offset passed to the constructor | 354 // headers. This plus the starting offset passed to the constructor |
| 239 // is the offset of the end of the compilation unit --- and the | 355 // is the offset of the end of the compilation unit --- and the |
| 240 // start of the next compilation unit, if there is one. | 356 // start of the next compilation unit, if there is one. |
| 241 uint64 Start(); | 357 uint64 Start(); |
| 242 | 358 |
| 243 private: | 359 private: |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 274 const uint8_t *start, | 390 const uint8_t *start, |
| 275 const Abbrev& abbrev); | 391 const Abbrev& abbrev); |
| 276 | 392 |
| 277 // Processes a single attribute and return a new pointer just past the | 393 // Processes a single attribute and return a new pointer just past the |
| 278 // end of it | 394 // end of it |
| 279 const uint8_t *ProcessAttribute(uint64 dieoffset, | 395 const uint8_t *ProcessAttribute(uint64 dieoffset, |
| 280 const uint8_t *start, | 396 const uint8_t *start, |
| 281 enum DwarfAttribute attr, | 397 enum DwarfAttribute attr, |
| 282 enum DwarfForm form); | 398 enum DwarfForm form); |
| 283 | 399 |
| 400 // Called when we have an attribute with unsigned data to give to | |
| 401 // our handler. The attribute is for the DIE at OFFSET from the | |
| 402 // beginning of compilation unit, has a name of ATTR, a form of | |
| 403 // FORM, and the actual data of the attribute is in DATA. | |
| 404 // If we see a DW_AT_GNU_dwo_id attribute, save the value so that | |
| 405 // we can find the debug info in a .dwo or .dwp file. | |
| 406 void ProcessAttributeUnsigned(uint64 offset, | |
| 407 enum DwarfAttribute attr, | |
| 408 enum DwarfForm form, | |
| 409 uint64 data) { | |
| 410 if (attr == DW_AT_GNU_dwo_id) | |
| 411 dwo_id_ = data; | |
| 412 else if (attr == DW_AT_GNU_addr_base) | |
| 413 addr_base_ = data; | |
| 414 else if (attr == DW_AT_GNU_ranges_base) | |
| 415 ranges_base_ = data; | |
| 416 // TODO(ccoutant): When we add DW_AT_ranges_base from DWARF-5, | |
| 417 // that base will apply to DW_AT_ranges attributes in the | |
| 418 // skeleton CU as well as in the .dwo/.dwp files. | |
| 419 else if (attr == DW_AT_ranges && is_split_dwarf_) | |
| 420 data += ranges_base_; | |
| 421 handler_->ProcessAttributeUnsigned(offset, attr, form, data); | |
| 422 } | |
| 423 | |
| 424 // Called when we have an attribute with signed data to give to | |
| 425 // our handler. The attribute is for the DIE at OFFSET from the | |
| 426 // beginning of compilation unit, has a name of ATTR, a form of | |
| 427 // FORM, and the actual data of the attribute is in DATA. | |
| 428 void ProcessAttributeSigned(uint64 offset, | |
| 429 enum DwarfAttribute attr, | |
| 430 enum DwarfForm form, | |
| 431 int64 data) { | |
| 432 handler_->ProcessAttributeSigned(offset, attr, form, data); | |
| 433 } | |
| 434 | |
| 435 // Called when we have an attribute with a buffer of data to give to | |
| 436 // our handler. The attribute is for the DIE at OFFSET from the | |
| 437 // beginning of compilation unit, has a name of ATTR, a form of | |
| 438 // FORM, and the actual data of the attribute is in DATA, and the | |
| 439 // length of the buffer is LENGTH. | |
| 440 void ProcessAttributeBuffer(uint64 offset, | |
| 441 enum DwarfAttribute attr, | |
| 442 enum DwarfForm form, | |
| 443 const uint8_t* data, | |
| 444 uint64 len) { | |
| 445 handler_->ProcessAttributeBuffer(offset, attr, form, data, len); | |
| 446 } | |
| 447 | |
| 448 // Called when we have an attribute with string data to give to | |
| 449 // our handler. The attribute is for the DIE at OFFSET from the | |
| 450 // beginning of compilation unit, has a name of ATTR, a form of | |
| 451 // FORM, and the actual data of the attribute is in DATA. | |
| 452 // If we see a DW_AT_GNU_dwo_name attribute, save the value so | |
| 453 // that we can find the debug info in a .dwo or .dwp file. | |
| 454 void ProcessAttributeString(uint64 offset, | |
| 455 enum DwarfAttribute attr, | |
| 456 enum DwarfForm form, | |
| 457 const char* data) { | |
| 458 if (attr == DW_AT_GNU_dwo_name) | |
| 459 dwo_name_ = data; | |
| 460 handler_->ProcessAttributeString(offset, attr, form, data); | |
| 461 } | |
| 462 | |
| 284 // Processes all DIEs for this compilation unit | 463 // Processes all DIEs for this compilation unit |
| 285 void ProcessDIEs(); | 464 void ProcessDIEs(); |
| 286 | 465 |
| 287 // Skips the die with attributes specified in ABBREV starting at | 466 // Skips the die with attributes specified in ABBREV starting at |
| 288 // START, and return the new place to position the stream to. | 467 // START, and return the new place to position the stream to. |
| 289 const uint8_t *SkipDIE(const uint8_t *start, const Abbrev& abbrev); | 468 const uint8_t *SkipDIE(const uint8_t *start, const Abbrev& abbrev); |
| 290 | 469 |
| 291 // Skips the attribute starting at START, with FORM, and return the | 470 // Skips the attribute starting at START, with FORM, and return the |
| 292 // new place to position the stream to. | 471 // new place to position the stream to. |
| 293 const uint8_t *SkipAttribute(const uint8_t *start, enum DwarfForm form); | 472 const uint8_t *SkipAttribute(const uint8_t *start, enum DwarfForm form); |
| 294 | 473 |
| 474 // Process the actual debug information in a split DWARF file. | |
| 475 void ProcessSplitDwarf(); | |
| 476 | |
| 477 // Read the debug sections from a .dwo file. | |
| 478 void ReadDebugSectionsFromDwo(ElfReader* elf_reader, | |
| 479 SectionMap* sections); | |
| 480 | |
| 481 // Path of the file containing the debug information. | |
| 482 const string path_; | |
| 483 | |
| 295 // Offset from section start is the offset of this compilation unit | 484 // Offset from section start is the offset of this compilation unit |
| 296 // from the beginning of the .debug_info section. | 485 // from the beginning of the .debug_info section. |
| 297 uint64 offset_from_section_start_; | 486 uint64 offset_from_section_start_; |
| 298 | 487 |
| 299 // buffer is the buffer for our CU, starting at .debug_info + offset | 488 // buffer is the buffer for our CU, starting at .debug_info + offset |
| 300 // passed in from constructor. | 489 // passed in from constructor. |
| 301 // after_header points to right after the compilation unit header. | 490 // after_header points to right after the compilation unit header. |
| 302 const uint8_t *buffer_; | 491 const uint8_t *buffer_; |
| 303 uint64 buffer_length_; | 492 uint64 buffer_length_; |
| 304 const uint8_t *after_header_; | 493 const uint8_t *after_header_; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 315 // Set of DWARF2/3 abbreviations for this compilation unit. Indexed | 504 // Set of DWARF2/3 abbreviations for this compilation unit. Indexed |
| 316 // by abbreviation number, which means that abbrevs_[0] is not | 505 // by abbreviation number, which means that abbrevs_[0] is not |
| 317 // valid. | 506 // valid. |
| 318 std::vector<Abbrev>* abbrevs_; | 507 std::vector<Abbrev>* abbrevs_; |
| 319 | 508 |
| 320 // String section buffer and length, if we have a string section. | 509 // String section buffer and length, if we have a string section. |
| 321 // This is here to avoid doing a section lookup for strings in | 510 // This is here to avoid doing a section lookup for strings in |
| 322 // ProcessAttribute, which is in the hot path for DWARF2 reading. | 511 // ProcessAttribute, which is in the hot path for DWARF2 reading. |
| 323 const uint8_t *string_buffer_; | 512 const uint8_t *string_buffer_; |
| 324 uint64 string_buffer_length_; | 513 uint64 string_buffer_length_; |
| 514 | |
| 515 // String offsets section buffer and length, if we have a string offsets | |
| 516 // section (.debug_str_offsets or .debug_str_offsets.dwo). | |
| 517 const uint8_t* str_offsets_buffer_; | |
| 518 uint64 str_offsets_buffer_length_; | |
| 519 | |
| 520 // Address section buffer and length, if we have an address section | |
| 521 // (.debug_addr). | |
| 522 const uint8_t * addr_buffer_; | |
|
vapier
2016/04/14 22:48:47
omit the space before the *
yunlian
2016/04/18 21:20:52
Done.
| |
| 523 uint64 addr_buffer_length_; | |
| 524 | |
| 525 // Flag indicating whether this compilation unit is part of a .dwo | |
| 526 // or .dwp file. If true, we are reading this unit because a | |
| 527 // skeleton compilation unit in an executable file had a | |
| 528 // DW_AT_GNU_dwo_name or DW_AT_GNU_dwo_id attribute. | |
| 529 // In a .dwo file, we expect the string offsets section to | |
| 530 // have a ".dwo" suffix, and we will use the ".debug_addr" section | |
| 531 // associated with the skeleton compilation unit. | |
| 532 bool is_split_dwarf_; | |
| 533 | |
| 534 // The value of the DW_AT_GNU_dwo_id attribute, if any. | |
| 535 uint64 dwo_id_; | |
| 536 | |
| 537 // The value of the DW_AT_GNU_dwo_name attribute, if any. | |
| 538 const char* dwo_name_; | |
| 539 | |
| 540 // If this is a split DWARF CU, the value of the DW_AT_GNU_dwo_id attribute | |
| 541 // from the skeleton CU. | |
| 542 uint64 skeleton_dwo_id_; | |
| 543 | |
| 544 // The value of the DW_AT_GNU_ranges_base attribute, if any. | |
| 545 uint64 ranges_base_; | |
| 546 | |
| 547 // The value of the DW_AT_GNU_addr_base attribute, if any. | |
| 548 uint64 addr_base_; | |
| 549 | |
| 550 // True if we have already looked for a .dwp file. | |
| 551 bool have_checked_for_dwp_; | |
| 552 | |
| 553 // Path to the .dwp file. | |
| 554 string dwp_path_; | |
| 555 | |
| 556 // ByteReader for the DWP file. | |
| 557 std::unique_ptr<ByteReader> dwp_byte_reader_; | |
| 558 | |
| 559 // DWP reader. | |
| 560 std::unique_ptr<DwpReader> dwp_reader_; | |
| 325 }; | 561 }; |
| 326 | 562 |
| 327 // This class is the main interface between the reader and the | 563 // A Reader for a .dwp file. Supports the fetching of DWARF debug |
| 328 // client. The virtual functions inside this get called for | 564 // info for a given dwo_id. |
| 329 // interesting events that happen during DWARF2 reading. | 565 // |
| 330 // The default implementation skips everything. | 566 // There are two versions of .dwp files. In both versions, the |
| 567 // .dwp file is an ELF file containing only debug sections. | |
| 568 // In Version 1, the file contains many copies of each debug | |
| 569 // section, one for each .dwo file that is packaged in the .dwp | |
| 570 // file, and the .debug_cu_index section maps from the dwo_id | |
| 571 // to a set of section indexes. In Version 2, the file contains | |
| 572 // one of each debug section, and the .debug_cu_index section | |
| 573 // maps from the dwo_id to a set of offsets and lengths that | |
| 574 // identify each .dwo file's contribution to the larger sections. | |
| 331 | 575 |
| 332 class Dwarf2Handler { | 576 class DwpReader { |
| 333 public: | 577 public: |
| 334 Dwarf2Handler() { } | 578 DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader); |
| 335 | 579 |
| 336 virtual ~Dwarf2Handler() { } | 580 ~DwpReader(); |
| 337 | 581 |
| 338 // Start to process a compilation unit at OFFSET from the beginning of the | 582 // Read the CU index and initialize data members. |
| 339 // .debug_info section. Return false if you would like to skip this | 583 void Initialize(); |
| 340 // compilation unit. | |
| 341 virtual bool StartCompilationUnit(uint64 offset, uint8 address_size, | |
| 342 uint8 offset_size, uint64 cu_length, | |
| 343 uint8 dwarf_version) { return false; } | |
| 344 | 584 |
| 345 // Start to process a DIE at OFFSET from the beginning of the .debug_info | 585 // Read the debug sections for the given dwo_id. |
| 346 // section. Return false if you would like to skip this DIE. | 586 void ReadDebugSectionsForCU(uint64 dwo_id, SectionMap* sections); |
| 347 virtual bool StartDIE(uint64 offset, enum DwarfTag tag) { return false; } | |
| 348 | 587 |
| 349 // Called when we have an attribute with unsigned data to give to our | 588 private: |
| 350 // handler. The attribute is for the DIE at OFFSET from the beginning of the | 589 // Search a v1 hash table for "dwo_id". Returns the slot index |
| 351 // .debug_info section. Its name is ATTR, its form is FORM, and its value is | 590 // where the dwo_id was found, or -1 if it was not found. |
| 352 // DATA. | 591 int LookupCU(uint64 dwo_id); |
| 353 virtual void ProcessAttributeUnsigned(uint64 offset, | |
| 354 enum DwarfAttribute attr, | |
| 355 enum DwarfForm form, | |
| 356 uint64 data) { } | |
| 357 | 592 |
| 358 // Called when we have an attribute with signed data to give to our handler. | 593 // Search a v2 hash table for "dwo_id". Returns the row index |
| 359 // The attribute is for the DIE at OFFSET from the beginning of the | 594 // in the offsets and sizes tables, or 0 if it was not found. |
| 360 // .debug_info section. Its name is ATTR, its form is FORM, and its value is | 595 uint32 LookupCUv2(uint64 dwo_id); |
| 361 // DATA. | |
| 362 virtual void ProcessAttributeSigned(uint64 offset, | |
| 363 enum DwarfAttribute attr, | |
| 364 enum DwarfForm form, | |
| 365 int64 data) { } | |
| 366 | 596 |
| 367 // Called when we have an attribute whose value is a reference to | 597 // The ELF reader for the .dwp file. |
| 368 // another DIE. The attribute belongs to the DIE at OFFSET from the | 598 ElfReader* elf_reader_; |
| 369 // beginning of the .debug_info section. Its name is ATTR, its form | |
| 370 // is FORM, and the offset of the DIE being referred to from the | |
| 371 // beginning of the .debug_info section is DATA. | |
| 372 virtual void ProcessAttributeReference(uint64 offset, | |
| 373 enum DwarfAttribute attr, | |
| 374 enum DwarfForm form, | |
| 375 uint64 data) { } | |
| 376 | 599 |
| 377 // Called when we have an attribute with a buffer of data to give to our | 600 // The ByteReader for the .dwp file. |
| 378 // handler. The attribute is for the DIE at OFFSET from the beginning of the | 601 const ByteReader& byte_reader_; |
| 379 // .debug_info section. Its name is ATTR, its form is FORM, DATA points to | |
| 380 // the buffer's contents, and its length in bytes is LENGTH. The buffer is | |
| 381 // owned by the caller, not the callee, and may not persist for very long. | |
| 382 // If you want the data to be available later, it needs to be copied. | |
| 383 virtual void ProcessAttributeBuffer(uint64 offset, | |
| 384 enum DwarfAttribute attr, | |
| 385 enum DwarfForm form, | |
| 386 const uint8_t *data, | |
| 387 uint64 len) { } | |
| 388 | 602 |
| 389 // Called when we have an attribute with string data to give to our handler. | 603 // Pointer to the .debug_cu_index section. |
| 390 // The attribute is for the DIE at OFFSET from the beginning of the | 604 const char* cu_index_; |
| 391 // .debug_info section. Its name is ATTR, its form is FORM, and its value is | |
| 392 // DATA. | |
| 393 virtual void ProcessAttributeString(uint64 offset, | |
| 394 enum DwarfAttribute attr, | |
| 395 enum DwarfForm form, | |
| 396 const string& data) { } | |
| 397 | 605 |
| 398 // Called when we have an attribute whose value is the 64-bit signature | 606 // Size of the .debug_cu_index section. |
| 399 // of a type unit in the .debug_types section. OFFSET is the offset of | 607 size_t cu_index_size_; |
| 400 // the DIE whose attribute we're reporting. ATTR and FORM are the | |
| 401 // attribute's name and form. SIGNATURE is the type unit's signature. | |
| 402 virtual void ProcessAttributeSignature(uint64 offset, | |
| 403 enum DwarfAttribute attr, | |
| 404 enum DwarfForm form, | |
| 405 uint64 signature) { } | |
| 406 | 608 |
| 407 // Called when finished processing the DIE at OFFSET. | 609 // Pointer to the .debug_str.dwo section. |
| 408 // Because DWARF2/3 specifies a tree of DIEs, you may get starts | 610 const char* string_buffer_; |
| 409 // before ends of the previous DIE, as we process children before | |
| 410 // ending the parent. | |
| 411 virtual void EndDIE(uint64 offset) { } | |
| 412 | 611 |
| 612 // Size of the .debug_str.dwo section. | |
| 613 size_t string_buffer_size_; | |
| 614 | |
| 615 // Version of the .dwp file. We support versions 1 and 2 currently. | |
| 616 int version_; | |
| 617 | |
| 618 // Number of columns in the section tables (version 2). | |
| 619 unsigned int ncolumns_; | |
| 620 | |
| 621 // Number of units in the section tables (version 2). | |
| 622 unsigned int nunits_; | |
| 623 | |
| 624 // Number of slots in the hash table. | |
| 625 unsigned int nslots_; | |
| 626 | |
| 627 // Pointer to the beginning of the hash table. | |
| 628 const char* phash_; | |
| 629 | |
| 630 // Pointer to the beginning of the index table. | |
| 631 const char* pindex_; | |
| 632 | |
| 633 // Pointer to the beginning of the section index pool (version 1). | |
| 634 const char* shndx_pool_; | |
| 635 | |
| 636 // Pointer to the beginning of the section offset table (version 2). | |
| 637 const char* offset_table_; | |
| 638 | |
| 639 // Pointer to the beginning of the section size table (version 2). | |
| 640 const char* size_table_; | |
| 641 | |
| 642 // Contents of the sections of interest (version 2). | |
| 643 const char* abbrev_data_; | |
| 644 size_t abbrev_size_; | |
| 645 const char* info_data_; | |
| 646 size_t info_size_; | |
| 647 const char* str_offsets_data_; | |
| 648 size_t str_offsets_size_; | |
| 413 }; | 649 }; |
| 414 | 650 |
| 415 // This class is a reader for DWARF's Call Frame Information. CFI | 651 // This class is a reader for DWARF's Call Frame Information. CFI |
| 416 // describes how to unwind stack frames --- even for functions that do | 652 // describes how to unwind stack frames --- even for functions that do |
| 417 // not follow fixed conventions for saving registers, whose frame size | 653 // not follow fixed conventions for saving registers, whose frame size |
| 418 // varies as they execute, etc. | 654 // varies as they execute, etc. |
| 419 // | 655 // |
| 420 // CFI describes, at each machine instruction, how to compute the | 656 // CFI describes, at each machine instruction, how to compute the |
| 421 // stack frame's base address, how to find the return address, and | 657 // stack frame's base address, how to find the return address, and |
| 422 // where to find the saved values of the caller's registers (if the | 658 // where to find the saved values of the caller's registers (if the |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1043 // The name of the file whose CFI we're reading. | 1279 // The name of the file whose CFI we're reading. |
| 1044 string filename_; | 1280 string filename_; |
| 1045 | 1281 |
| 1046 // The name of the CFI section in that file. | 1282 // The name of the CFI section in that file. |
| 1047 string section_; | 1283 string section_; |
| 1048 }; | 1284 }; |
| 1049 | 1285 |
| 1050 } // namespace dwarf2reader | 1286 } // namespace dwarf2reader |
| 1051 | 1287 |
| 1052 #endif // UTIL_DEBUGINFO_DWARF2READER_H__ | 1288 #endif // UTIL_DEBUGINFO_DWARF2READER_H__ |
| OLD | NEW |