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