Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: src/common/dwarf/dwarf2reader.cc

Issue 1884283002: Add debug fission support. (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 Google Inc. All Rights Reserved. 1 // Copyright (c) 2010 Google Inc. All Rights Reserved.
2 // 2 //
3 // Redistribution and use in source and binary forms, with or without 3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are 4 // modification, are permitted provided that the following conditions are
5 // met: 5 // met:
6 // 6 //
7 // * Redistributions of source code must retain the above copyright 7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer. 8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above 9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer 10 // copyright notice, this list of conditions and the following disclaimer
(...skipping 26 matching lines...) Expand all
37 #include <stdint.h> 37 #include <stdint.h>
38 #include <stdio.h> 38 #include <stdio.h>
39 #include <string.h> 39 #include <string.h>
40 40
41 #include <map> 41 #include <map>
42 #include <memory> 42 #include <memory>
43 #include <stack> 43 #include <stack>
44 #include <string> 44 #include <string>
45 #include <utility> 45 #include <utility>
46 46
47 #include <sys/stat.h>
48
47 #include "common/dwarf/bytereader-inl.h" 49 #include "common/dwarf/bytereader-inl.h"
48 #include "common/dwarf/bytereader.h" 50 #include "common/dwarf/bytereader.h"
49 #include "common/dwarf/line_state_machine.h" 51 #include "common/dwarf/line_state_machine.h"
50 #include "common/using_std_string.h" 52 #include "common/using_std_string.h"
51 53
52 namespace dwarf2reader { 54 namespace dwarf2reader {
53 55
54 CompilationUnit::CompilationUnit(const SectionMap& sections, uint64 offset, 56 CompilationUnit::CompilationUnit(const string& path,
57 const SectionMap& sections, uint64 offset,
55 ByteReader* reader, Dwarf2Handler* handler) 58 ByteReader* reader, Dwarf2Handler* handler)
56 : offset_from_section_start_(offset), reader_(reader), 59 : path_(path), offset_from_section_start_(offset), reader_(reader),
57 sections_(sections), handler_(handler), abbrevs_(NULL), 60 sections_(sections), handler_(handler), abbrevs_(),
58 string_buffer_(NULL), string_buffer_length_(0) {} 61 string_buffer_(NULL), string_buffer_length_(0),
62 str_offsets_buffer_(NULL), str_offsets_buffer_length_(0),
63 addr_buffer_(NULL), addr_buffer_length_(0),
64 is_split_dwarf_(false), dwo_id_(0), dwo_name_(),
65 skeleton_dwo_id_(0), ranges_base_(0), addr_base_(0),
66 have_checked_for_dwp_(false), dwp_path_(),
67 dwp_byte_reader_(), dwp_reader_() {}
68
69 // Initialize a compilation unit from a .dwo or .dwp file.
70 // In this case, we need the .debug_addr section from the
71 // executable file that contains the corresponding skeleton
72 // compilation unit. We also inherit the Dwarf2Handler from
73 // the executable file, and call it as if we were still
74 // processing the original compilation unit.
75
76 void CompilationUnit::SetSplitDwarf(const uint8_t* addr_buffer,
77 uint64 addr_buffer_length,
78 uint64 addr_base,
79 uint64 ranges_base,
80 uint64 dwo_id) {
81 is_split_dwarf_ = true;
82 addr_buffer_ = addr_buffer;
83 addr_buffer_length_ = addr_buffer_length;
84 addr_base_ = addr_base;
85 ranges_base_ = ranges_base;
86 skeleton_dwo_id_ = dwo_id;
87 }
59 88
60 // Read a DWARF2/3 abbreviation section. 89 // Read a DWARF2/3 abbreviation section.
61 // Each abbrev consists of a abbreviation number, a tag, a byte 90 // Each abbrev consists of a abbreviation number, a tag, a byte
62 // specifying whether the tag has children, and a list of 91 // specifying whether the tag has children, and a list of
63 // attribute/form pairs. 92 // attribute/form pairs.
64 // The list of forms is terminated by a 0 for the attribute, and a 93 // The list of forms is terminated by a 0 for the attribute, and a
65 // zero for the form. The entire abbreviation section is terminated 94 // zero for the form. The entire abbreviation section is terminated
66 // by a zero for the code. 95 // by a zero for the code.
67 96
68 void CompilationUnit::ReadAbbrevs() { 97 void CompilationUnit::ReadAbbrevs() {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 case DW_FORM_data4: 196 case DW_FORM_data4:
168 return start + 4; 197 return start + 4;
169 case DW_FORM_ref8: 198 case DW_FORM_ref8:
170 case DW_FORM_data8: 199 case DW_FORM_data8:
171 case DW_FORM_ref_sig8: 200 case DW_FORM_ref_sig8:
172 return start + 8; 201 return start + 8;
173 case DW_FORM_string: 202 case DW_FORM_string:
174 return start + strlen(reinterpret_cast<const char *>(start)) + 1; 203 return start + strlen(reinterpret_cast<const char *>(start)) + 1;
175 case DW_FORM_udata: 204 case DW_FORM_udata:
176 case DW_FORM_ref_udata: 205 case DW_FORM_ref_udata:
206 case DW_FORM_GNU_str_index:
207 case DW_FORM_GNU_addr_index:
177 reader_->ReadUnsignedLEB128(start, &len); 208 reader_->ReadUnsignedLEB128(start, &len);
178 return start + len; 209 return start + len;
179 210
180 case DW_FORM_sdata: 211 case DW_FORM_sdata:
181 reader_->ReadSignedLEB128(start, &len); 212 reader_->ReadSignedLEB128(start, &len);
182 return start + len; 213 return start + len;
183 case DW_FORM_addr: 214 case DW_FORM_addr:
184 return start + reader_->AddressSize(); 215 return start + reader_->AddressSize();
185 case DW_FORM_ref_addr: 216 case DW_FORM_ref_addr:
186 // DWARF2 and 3/4 differ on whether ref_addr is address size or 217 // DWARF2 and 3/4 differ on whether ref_addr is address size or
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 // recommended in the DWARF spec, and used on Linux; "__debug_str" 320 // recommended in the DWARF spec, and used on Linux; "__debug_str"
290 // is the name used in Mac OS X Mach-O files. 321 // is the name used in Mac OS X Mach-O files.
291 iter = sections_.find(".debug_str"); 322 iter = sections_.find(".debug_str");
292 if (iter == sections_.end()) 323 if (iter == sections_.end())
293 iter = sections_.find("__debug_str"); 324 iter = sections_.find("__debug_str");
294 if (iter != sections_.end()) { 325 if (iter != sections_.end()) {
295 string_buffer_ = iter->second.first; 326 string_buffer_ = iter->second.first;
296 string_buffer_length_ = iter->second.second; 327 string_buffer_length_ = iter->second.second;
297 } 328 }
298 329
330 // Set the string offsets section if we have one.
331 iter = sections_.find(".debug_str_offsets");
332 if (iter != sections_.end()) {
333 str_offsets_buffer_ = iter->second.first;
334 str_offsets_buffer_length_ = iter->second.second;
335 }
336
337 // Set the address section if we have one.
338 iter = sections_.find(".debug_addr");
339 if (iter != sections_.end()) {
340 addr_buffer_ = iter->second.first;
341 addr_buffer_length_ = iter->second.second;
342 }
343
299 // Now that we have our abbreviations, start processing DIE's. 344 // Now that we have our abbreviations, start processing DIE's.
300 ProcessDIEs(); 345 ProcessDIEs();
301 346
347 // If this is a skeleton compilation unit generated with split DWARF,
348 // and the client needs the full debug info, we need to find the full
349 // compilation unit in a .dwo or .dwp file.
350 if (!is_split_dwarf_
351 && dwo_name_ != NULL
352 && handler_->NeedSplitDebugInfo())
353 ProcessSplitDwarf();
354
302 return ourlength; 355 return ourlength;
303 } 356 }
304 357
305 // If one really wanted, you could merge SkipAttribute and 358 // If one really wanted, you could merge SkipAttribute and
306 // ProcessAttribute 359 // ProcessAttribute
307 // This is all boring data manipulation and calling of the handler. 360 // This is all boring data manipulation and calling of the handler.
308 const uint8_t *CompilationUnit::ProcessAttribute( 361 const uint8_t *CompilationUnit::ProcessAttribute(
309 uint64 dieoffset, const uint8_t *start, enum DwarfAttribute attr, 362 uint64 dieoffset, const uint8_t *start, enum DwarfAttribute attr,
310 enum DwarfForm form) { 363 enum DwarfForm form) {
311 size_t len; 364 size_t len;
312 365
313 switch (form) { 366 switch (form) {
314 // DW_FORM_indirect is never used because it is such a space 367 // DW_FORM_indirect is never used because it is such a space
315 // waster. 368 // waster.
316 case DW_FORM_indirect: 369 case DW_FORM_indirect:
317 form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start, 370 form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
318 &len)); 371 &len));
319 start += len; 372 start += len;
320 return ProcessAttribute(dieoffset, start, attr, form); 373 return ProcessAttribute(dieoffset, start, attr, form);
321 374
322 case DW_FORM_flag_present: 375 case DW_FORM_flag_present:
323 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 1); 376 ProcessAttributeUnsigned(dieoffset, attr, form, 1);
324 return start; 377 return start;
325 case DW_FORM_data1: 378 case DW_FORM_data1:
326 case DW_FORM_flag: 379 case DW_FORM_flag:
327 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 380 ProcessAttributeUnsigned(dieoffset, attr, form,
328 reader_->ReadOneByte(start)); 381 reader_->ReadOneByte(start));
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change
yunlian 2016/04/18 21:20:52 Done.
329 return start + 1; 382 return start + 1;
330 case DW_FORM_data2: 383 case DW_FORM_data2:
331 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 384 ProcessAttributeUnsigned(dieoffset, attr, form,
332 reader_->ReadTwoBytes(start)); 385 reader_->ReadTwoBytes(start));
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change
yunlian 2016/04/18 21:20:52 Done.
333 return start + 2; 386 return start + 2;
334 case DW_FORM_data4: 387 case DW_FORM_data4:
335 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 388 ProcessAttributeUnsigned(dieoffset, attr, form,
336 reader_->ReadFourBytes(start)); 389 reader_->ReadFourBytes(start));
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change
yunlian 2016/04/18 21:20:52 Done.
337 return start + 4; 390 return start + 4;
338 case DW_FORM_data8: 391 case DW_FORM_data8:
339 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 392 ProcessAttributeUnsigned(dieoffset, attr, form,
340 reader_->ReadEightBytes(start)); 393 reader_->ReadEightBytes(start));
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change
yunlian 2016/04/18 21:20:51 Done.
341 return start + 8; 394 return start + 8;
342 case DW_FORM_string: { 395 case DW_FORM_string: {
343 const char *str = reinterpret_cast<const char *>(start); 396 const char *str = reinterpret_cast<const char *>(start);
344 handler_->ProcessAttributeString(dieoffset, attr, form, 397 ProcessAttributeString(dieoffset, attr, form,
345 str); 398 str);
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change -- j
yunlian 2016/04/18 21:20:51 Done.
346 return start + strlen(str) + 1; 399 return start + strlen(str) + 1;
347 } 400 }
348 case DW_FORM_udata: 401 case DW_FORM_udata:
349 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 402 ProcessAttributeUnsigned(dieoffset, attr, form,
350 reader_->ReadUnsignedLEB128(start, 403 reader_->ReadUnsignedLEB128(start,
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change
yunlian 2016/04/18 21:20:52 Done.
351 &len)); 404 &len));
352 return start + len; 405 return start + len;
353 406
354 case DW_FORM_sdata: 407 case DW_FORM_sdata:
355 handler_->ProcessAttributeSigned(dieoffset, attr, form, 408 ProcessAttributeSigned(dieoffset, attr, form,
356 reader_->ReadSignedLEB128(start, &len)); 409 reader_->ReadSignedLEB128(start, &len));
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change
yunlian 2016/04/18 21:20:52 Done.
357 return start + len; 410 return start + len;
358 case DW_FORM_addr: 411 case DW_FORM_addr:
359 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 412 ProcessAttributeUnsigned(dieoffset, attr, form,
360 reader_->ReadAddress(start)); 413 reader_->ReadAddress(start));
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change
yunlian 2016/04/18 21:20:52 Done.
361 return start + reader_->AddressSize(); 414 return start + reader_->AddressSize();
362 case DW_FORM_sec_offset: 415 case DW_FORM_sec_offset:
363 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 416 ProcessAttributeUnsigned(dieoffset, attr, form,
364 reader_->ReadOffset(start)); 417 reader_->ReadOffset(start));
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change
yunlian 2016/04/18 21:20:51 Done.
365 return start + reader_->OffsetSize(); 418 return start + reader_->OffsetSize();
366 419
367 case DW_FORM_ref1: 420 case DW_FORM_ref1:
368 handler_->ProcessAttributeReference(dieoffset, attr, form, 421 handler_->ProcessAttributeReference(dieoffset, attr, form,
369 reader_->ReadOneByte(start) 422 reader_->ReadOneByte(start)
370 + offset_from_section_start_); 423 + offset_from_section_start_);
371 return start + 1; 424 return start + 1;
372 case DW_FORM_ref2: 425 case DW_FORM_ref2:
373 handler_->ProcessAttributeReference(dieoffset, attr, form, 426 handler_->ProcessAttributeReference(dieoffset, attr, form,
374 reader_->ReadTwoBytes(start) 427 reader_->ReadTwoBytes(start)
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 datalen); 487 datalen);
435 return start + datalen + len; 488 return start + datalen + len;
436 } 489 }
437 case DW_FORM_strp: { 490 case DW_FORM_strp: {
438 assert(string_buffer_ != NULL); 491 assert(string_buffer_ != NULL);
439 492
440 const uint64 offset = reader_->ReadOffset(start); 493 const uint64 offset = reader_->ReadOffset(start);
441 assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_); 494 assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_);
442 495
443 const char *str = reinterpret_cast<const char *>(string_buffer_ + offset); 496 const char *str = reinterpret_cast<const char *>(string_buffer_ + offset);
444 handler_->ProcessAttributeString(dieoffset, attr, form, 497 ProcessAttributeString(dieoffset, attr, form,
445 str); 498 str);
vapier 2016/04/14 22:48:47 line wrapping is broken now after this change -- j
yunlian 2016/04/18 21:20:52 Done.
446 return start + reader_->OffsetSize(); 499 return start + reader_->OffsetSize();
447 } 500 }
501
502 case DW_FORM_GNU_str_index: {
503 uint64 str_index = reader_->ReadUnsignedLEB128(start, &len);
504 const uint8_t* offset_ptr =
505 str_offsets_buffer_ + str_index * reader_->OffsetSize();
506 const uint64 offset = reader_->ReadOffset(offset_ptr);
507 if (offset >= string_buffer_length_) {
508 return NULL;
509 }
510
511 const char* str = reinterpret_cast<const char *>(string_buffer_) + offset;
512 ProcessAttributeString(dieoffset, attr, form,
513 str);
vapier 2016/04/14 22:48:47 line wrapping here looks broken -- just unwrap it
514 return start + len;
515 break;
vapier 2016/04/14 22:48:47 pointless break -> delete
yunlian 2016/04/14 23:18:49 Done.
516 }
517 case DW_FORM_GNU_addr_index: {
518 uint64 addr_index = reader_->ReadUnsignedLEB128(start, &len);
519 const uint8_t* addr_ptr =
520 addr_buffer_ + addr_base_ + addr_index * reader_->AddressSize();
521 ProcessAttributeUnsigned(dieoffset, attr, form,
522 reader_->ReadAddress(addr_ptr));
vapier 2016/04/14 22:48:47 line wrapping is broken
yunlian 2016/04/18 21:20:52 Done.
523 return start + len;
524 break;
vapier 2016/04/14 22:48:47 pointless break -> delete
yunlian 2016/04/18 21:20:52 Done.
525 }
526
527
vapier 2016/04/14 22:48:47 only one blank line here
yunlian 2016/04/18 21:20:52 Done.
448 } 528 }
449 fprintf(stderr, "Unhandled form type\n"); 529 fprintf(stderr, "Unhandled form type\n");
450 return NULL; 530 return NULL;
451 } 531 }
452 532
453 const uint8_t *CompilationUnit::ProcessDIE(uint64 dieoffset, 533 const uint8_t *CompilationUnit::ProcessDIE(uint64 dieoffset,
454 const uint8_t *start, 534 const uint8_t *start,
455 const Abbrev& abbrev) { 535 const Abbrev& abbrev) {
456 for (AttributeList::const_iterator i = abbrev.attributes.begin(); 536 for (AttributeList::const_iterator i = abbrev.attributes.begin();
457 i != abbrev.attributes.end(); 537 i != abbrev.attributes.end();
458 i++) { 538 i++) {
459 start = ProcessAttribute(dieoffset, start, i->first, i->second); 539 start = ProcessAttribute(dieoffset, start, i->first, i->second);
460 } 540 }
541
542 // If this is a compilation unit in a split DWARF object, verify that
543 // the dwo_id matches. If it does not match, we will ignore this
544 // compilation unit.
545 if (abbrev.tag == DW_TAG_compile_unit
546 && is_split_dwarf_
547 && dwo_id_ != skeleton_dwo_id_) {
548 return NULL;
549 }
550
461 return start; 551 return start;
462 } 552 }
463 553
464 void CompilationUnit::ProcessDIEs() { 554 void CompilationUnit::ProcessDIEs() {
465 const uint8_t *dieptr = after_header_; 555 const uint8_t *dieptr = after_header_;
466 size_t len; 556 size_t len;
467 557
468 // lengthstart is the place the length field is based on. 558 // lengthstart is the place the length field is based on.
469 // It is the point in the header after the initial length field 559 // It is the point in the header after the initial length field
470 const uint8_t *lengthstart = buffer_; 560 const uint8_t *lengthstart = buffer_;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 } 598 }
509 599
510 if (abbrev.has_children) { 600 if (abbrev.has_children) {
511 die_stack.push(absolute_offset); 601 die_stack.push(absolute_offset);
512 } else { 602 } else {
513 handler_->EndDIE(absolute_offset); 603 handler_->EndDIE(absolute_offset);
514 } 604 }
515 } 605 }
516 } 606 }
517 607
608 // Check for a valid ELF file and return the Address size.
609 // Returns 0 if not a valid ELF file.
610
611 inline int GetElfWidth(const ElfReader& elf) {
vapier 2016/04/14 22:48:47 i'm not seeing where ElfReader is defined. can yo
yunlian 2016/04/18 21:20:52 The elf_reader.h and elf_reader.cc were missing in
612 if (elf.IsElf32File())
613 return 4;
614 if (elf.IsElf64File())
615 return 8;
616 return 0;
617 }
618
619 void CompilationUnit::ProcessSplitDwarf() {
620 struct stat statbuf;
621 if (!have_checked_for_dwp_) {
622 // Look for a .dwp file in the same directory as the executable.
623 have_checked_for_dwp_ = true;
624 string dwp_suffix(".dwp");
625 dwp_path_ = path_ + dwp_suffix;
626 if (stat(dwp_path_.c_str(), &statbuf)) {
vapier 2016/04/14 22:48:47 compare it against != 0, and put a comment in the
yunlian 2016/04/14 23:18:49 Done.
627 string debug_suffix(".debug");
628 dwp_path_ = path_;
629 size_t found = path_.rfind(debug_suffix);
630 if (found + debug_suffix.length() == path_.length())
631 dwp_path_ = dwp_path_.replace(found, debug_suffix.length(), dwp_suffix);
632 }
633 if (stat(dwp_path_.c_str(), &statbuf) == 0) {
634 ElfReader* elf = new ElfReader(dwp_path_);
635 int width = GetElfWidth(*elf);
636 if (width != 0) {
637 dwp_byte_reader_.reset(new ByteReader(reader_->GetEndianness()));
638 dwp_byte_reader_->SetAddressSize(width);
639 dwp_reader_.reset(new DwpReader(*dwp_byte_reader_, elf));
640 dwp_reader_->Initialize();
641 } else {
642 delete elf;
643 }
644 }
645 }
646 bool found_in_dwp = false;
647 if (dwp_reader_ != NULL) {
648 // If we have a .dwp file, read the debug sections for the requested CU.
649 SectionMap sections;
650 dwp_reader_->ReadDebugSectionsForCU(dwo_id_, &sections);
651 if (!sections.empty()) {
652 found_in_dwp = true;
653 CompilationUnit dwp_comp_unit(dwp_path_, sections, 0,
654 dwp_byte_reader_.get(), handler_);
655 dwp_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_, addr_base_,
656 ranges_base_, dwo_id_);
657 dwp_comp_unit.Start();
658 }
659 }
660 if (!found_in_dwp) {
661 // If no .dwp file, try to open the .dwo file.
662 if (stat(dwo_name_, &statbuf) == 0) {
663 ElfReader elf(dwo_name_);
664 int width = GetElfWidth(elf);
665 if (width != 0) {
666 ByteReader reader(ENDIANNESS_LITTLE);
vapier 2016/04/14 22:48:47 is hardcoding little endian here correct ? should
yunlian 2016/04/14 23:18:49 Done.
667 reader.SetAddressSize(width);
668 SectionMap sections;
669 ReadDebugSectionsFromDwo(&elf, &sections);
670 CompilationUnit dwo_comp_unit(dwo_name_, sections, 0, &reader,
671 handler_);
672 dwo_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_,
673 addr_base_, ranges_base_, dwo_id_);
674 dwo_comp_unit.Start();
675 }
676 }
677 }
678 }
679
680 void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader,
681 SectionMap* sections) {
682 static const char* section_names[] = {
vapier 2016/04/14 22:48:47 mark the array itself const too static const cha
yunlian 2016/04/14 23:18:49 Done.
683 ".debug_abbrev",
684 ".debug_info",
685 ".debug_str_offsets",
686 ".debug_str"
687 };
688 for (unsigned int i = 0u; i < sizeof(section_names)/sizeof(*(section_names)); ++i) {
689 string base_name = section_names[i];
690 string dwo_name = base_name + ".dwo";
691 size_t section_size;
692 const char* section_data = elf_reader->GetSectionByName(dwo_name,
693 &section_size);
694 if (section_data != NULL)
695 sections->insert(std::make_pair(
696 base_name, std::make_pair(reinterpret_cast<const uint8_t *>(section_da ta), section_size)));
697 }
698 }
699
700 DwpReader::DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader)
701 : elf_reader_(elf_reader), byte_reader_(byte_reader),
702 cu_index_(NULL), cu_index_size_(0), string_buffer_(NULL),
703 string_buffer_size_(0), version_(0), ncolumns_(0), nunits_(0),
704 nslots_(0), phash_(NULL), pindex_(NULL), shndx_pool_(NULL),
705 offset_table_(NULL), size_table_(NULL), abbrev_data_(NULL),
706 abbrev_size_(0), info_data_(NULL), info_size_(0),
707 str_offsets_data_(NULL), str_offsets_size_(0) {}
708
709 DwpReader::~DwpReader() {
710 if (elf_reader_) delete elf_reader_;
711 }
712
713 void DwpReader::Initialize() {
714 cu_index_ = elf_reader_->GetSectionByName(".debug_cu_index",
715 &cu_index_size_);
716 if (cu_index_ == NULL) {
717 return;
718 }
719 // The .debug_str.dwo section is shared by all CUs in the file.
720 string_buffer_ = elf_reader_->GetSectionByName(".debug_str.dwo",
721 &string_buffer_size_);
722
723 version_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_ind ex_));
724
725 if (version_ == 1) {
726 nslots_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_in dex_)
727 + 3 * sizeof(uint32));
728 phash_ = cu_index_ + 4 * sizeof(uint32);
729 pindex_ = phash_ + nslots_ * sizeof(uint64);
730 shndx_pool_ = pindex_ + nslots_ * sizeof(uint32);
731 if (shndx_pool_ >= cu_index_ + cu_index_size_) {
732 version_ = 0;
733 }
734 } else if (version_ == 2) {
735 ncolumns_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_ index_)
736 + sizeof(uint32));
737 nunits_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_in dex_)
738 + 2 * sizeof(uint32));
739 nslots_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_in dex_)
740 + 3 * sizeof(uint32));
741 phash_ = cu_index_ + 4 * sizeof(uint32);
742 pindex_ = phash_ + nslots_ * sizeof(uint64);
743 offset_table_ = pindex_ + nslots_ * sizeof(uint32);
744 size_table_ = offset_table_ + ncolumns_ * (nunits_ + 1) * sizeof(uint32);
745 abbrev_data_ = elf_reader_->GetSectionByName(".debug_abbrev.dwo",
746 &abbrev_size_);
747 info_data_ = elf_reader_->GetSectionByName(".debug_info.dwo", &info_size_);
748 str_offsets_data_ = elf_reader_->GetSectionByName(".debug_str_offsets.dwo",
749 &str_offsets_size_);
750 if (size_table_ >= cu_index_ + cu_index_size_) {
751 version_ = 0;
752 }
753 }
754 }
755
756 void DwpReader::ReadDebugSectionsForCU(uint64 dwo_id,
757 SectionMap* sections) {
758 if (version_ == 1) {
759 int slot = LookupCU(dwo_id);
760 if (slot == -1) {
761 return;
762 }
763
764 // The index table points to the section index pool, where we
765 // can read a list of section indexes for the debug sections
766 // for the CU whose dwo_id we are looking for.
767 int index = byte_reader_.ReadFourBytes(
768 reinterpret_cast<const uint8_t *>(pindex_)
769 + slot * sizeof(uint32));
770 const char* shndx_list = shndx_pool_ + index * sizeof(uint32);
771 for (;;) {
772 if (shndx_list >= cu_index_ + cu_index_size_) {
773 version_ = 0;
774 return;
775 }
776 unsigned int shndx = byte_reader_.ReadFourBytes(reinterpret_cast<const uin t8_t *>(shndx_list));
777 shndx_list += sizeof(uint32);
778 if (shndx == 0)
779 break;
780 const char * section_name = elf_reader_->GetSectionName(shndx);
vapier 2016/04/14 22:48:47 delete the space before the *
yunlian 2016/04/14 23:18:49 Done.
781 size_t section_size;
782 const char* section_data;
783 // We're only interested in these four debug sections.
784 // The section names in the .dwo file end with ".dwo", but we
785 // add them to the sections table with their normal names.
786 if (!strncmp(section_name, ".debug_abbrev", strlen(".debug_abbrev"))) {
787 section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
788 sections->insert(std::make_pair(
789 ".debug_abbrev", std::make_pair(reinterpret_cast<const uint8_t *> (s ection_data), section_size)));
790 } else if (!strncmp(section_name, ".debug_info", strlen(".debug_info"))) {
791 section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
792 sections->insert(std::make_pair(
793 ".debug_info", std::make_pair(reinterpret_cast<const uint8_t *> (sec tion_data), section_size)));
794 } else if (!strncmp(section_name, ".debug_str_offsets", strlen(".debug_str _offsets"))) {
795 section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
796 sections->insert(std::make_pair(
797 ".debug_str_offsets", std::make_pair(reinterpret_cast<const uint8_t *> (section_data), section_size)));
798 }
799 }
800 sections->insert(std::make_pair(
801 ".debug_str", std::make_pair(reinterpret_cast<const uint8_t *> (string_b uffer_), string_buffer_size_)));
802 } else if (version_ == 2) {
803 uint32 index = LookupCUv2(dwo_id);
804 if (index == 0) {
805 return;
806 }
807
808 // The index points to a row in each of the section offsets table
809 // and the section size table, where we can read the offsets and sizes
810 // of the contributions to each debug section from the CU whose dwo_id
811 // we are looking for. Row 0 of the section offsets table has the
812 // section ids for each column of the table. The size table begins
813 // with row 1.
814 const char* id_row = offset_table_;
815 const char* offset_row = offset_table_ + index * ncolumns_ * sizeof(uint32);
816 const char* size_row =
817 size_table_ + (index - 1) * ncolumns_ * sizeof(uint32);
818 if (size_row + ncolumns_ * sizeof(uint32) > cu_index_ + cu_index_size_) {
819 version_ = 0;
820 return;
821 }
822 for (unsigned int col = 0u; col < ncolumns_; ++col) {
823 uint32 section_id =
824 byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(id_row)
825 + col * sizeof(uint32));
826 uint32 offset =
827 byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(offset_ro w)
828 + col * sizeof(uint32));
829 uint32 size =
830 byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(size_row)
831 + col * sizeof(uint32));
832 if (section_id == DW_SECT_ABBREV) {
833 sections->insert(std::make_pair(
834 ".debug_abbrev", std::make_pair(reinterpret_cast<const uint8_t *> (a bbrev_data_) + offset, size)));
835 } else if (section_id == DW_SECT_INFO) {
836 sections->insert(std::make_pair(
837 ".debug_info", std::make_pair(reinterpret_cast<const uint8_t *> (inf o_data_) + offset, size)));
838 } else if (section_id == DW_SECT_STR_OFFSETS) {
839 sections->insert(
840 std::make_pair(".debug_str_offsets",
841 std::make_pair(reinterpret_cast<const uint8_t *> (str _offsets_data_) + offset, size)));
842 }
843 }
844 sections->insert(std::make_pair(
845 ".debug_str", std::make_pair(reinterpret_cast<const uint8_t *> (string_b uffer_), string_buffer_size_)));
846 }
847 }
848
849 int DwpReader::LookupCU(uint64 dwo_id) {
850 uint32 slot = static_cast<uint32>(dwo_id) & (nslots_ - 1);
851 uint64 probe = byte_reader_.ReadEightBytes(reinterpret_cast<const uint8_t *>(p hash_) + slot * sizeof(uint64));
852 if (probe != 0 && probe != dwo_id) {
853 uint32 secondary_hash =
854 (static_cast<uint32>(dwo_id >> 32) & (nslots_ - 1)) | 1;
855 do {
856 slot = (slot + secondary_hash) & (nslots_ - 1);
857 probe = byte_reader_.ReadEightBytes(reinterpret_cast<const uint8_t *>(phas h_) + slot * sizeof(uint64));
858 } while (probe != 0 && probe != dwo_id);
859 }
860 if (probe == 0)
861 return -1;
862 return slot;
863 }
864
865 uint32 DwpReader::LookupCUv2(uint64 dwo_id) {
866 uint32 slot = static_cast<uint32>(dwo_id) & (nslots_ - 1);
867 uint64 probe = byte_reader_.ReadEightBytes(reinterpret_cast<const uint8_t *>(p hash_) + slot * sizeof(uint64));
868 uint32 index = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(pi ndex_) + slot * sizeof(uint32));
869 if (index != 0 && probe != dwo_id) {
870 uint32 secondary_hash =
871 (static_cast<uint32>(dwo_id >> 32) & (nslots_ - 1)) | 1;
872 do {
873 slot = (slot + secondary_hash) & (nslots_ - 1);
874 probe = byte_reader_.ReadEightBytes(reinterpret_cast<const uint8_t *>(phas h_) + slot * sizeof(uint64));
875 index = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(pinde x_) + slot * sizeof(uint32));
876 } while (index != 0 && probe != dwo_id);
877 }
878 return index;
879 }
880
881
882
518 LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length, 883 LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length,
519 ByteReader* reader, LineInfoHandler* handler): 884 ByteReader* reader, LineInfoHandler* handler):
520 handler_(handler), reader_(reader), buffer_(buffer) { 885 handler_(handler), reader_(reader), buffer_(buffer) {
521 #ifndef NDEBUG 886 #ifndef NDEBUG
522 buffer_length_ = buffer_length; 887 buffer_length_ = buffer_length;
523 #endif 888 #endif
524 header_.std_opcode_lengths = NULL; 889 header_.std_opcode_lengths = NULL;
525 } 890 }
526 891
527 uint64 LineInfo::Start() { 892 uint64 LineInfo::Start() {
(...skipping 1811 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 uint64 insn_offset) { 2704 uint64 insn_offset) {
2340 fprintf(stderr, 2705 fprintf(stderr,
2341 "%s: CFI %s at offset 0x%llx in section '%s':" 2706 "%s: CFI %s at offset 0x%llx in section '%s':"
2342 " the DW_CFA_restore_state instruction at offset 0x%llx" 2707 " the DW_CFA_restore_state instruction at offset 0x%llx"
2343 " would clear the CFA rule in effect\n", 2708 " would clear the CFA rule in effect\n",
2344 filename_.c_str(), CallFrameInfo::KindName(kind), offset, 2709 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
2345 section_.c_str(), insn_offset); 2710 section_.c_str(), insn_offset);
2346 } 2711 }
2347 2712
2348 } // namespace dwarf2reader 2713 } // namespace dwarf2reader
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698