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

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: Add debug fission support Created 4 years, 7 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));
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));
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));
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));
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, str);
345 str);
346 return start + strlen(str) + 1; 398 return start + strlen(str) + 1;
347 } 399 }
348 case DW_FORM_udata: 400 case DW_FORM_udata:
349 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 401 ProcessAttributeUnsigned(dieoffset, attr, form,
350 reader_->ReadUnsignedLEB128(start, 402 reader_->ReadUnsignedLEB128(start, &len));
351 &len));
352 return start + len; 403 return start + len;
353 404
354 case DW_FORM_sdata: 405 case DW_FORM_sdata:
355 handler_->ProcessAttributeSigned(dieoffset, attr, form, 406 ProcessAttributeSigned(dieoffset, attr, form,
356 reader_->ReadSignedLEB128(start, &len)); 407 reader_->ReadSignedLEB128(start, &len));
357 return start + len; 408 return start + len;
358 case DW_FORM_addr: 409 case DW_FORM_addr:
359 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 410 ProcessAttributeUnsigned(dieoffset, attr, form,
360 reader_->ReadAddress(start)); 411 reader_->ReadAddress(start));
361 return start + reader_->AddressSize(); 412 return start + reader_->AddressSize();
362 case DW_FORM_sec_offset: 413 case DW_FORM_sec_offset:
363 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 414 ProcessAttributeUnsigned(dieoffset, attr, form,
364 reader_->ReadOffset(start)); 415 reader_->ReadOffset(start));
365 return start + reader_->OffsetSize(); 416 return start + reader_->OffsetSize();
366 417
367 case DW_FORM_ref1: 418 case DW_FORM_ref1:
368 handler_->ProcessAttributeReference(dieoffset, attr, form, 419 handler_->ProcessAttributeReference(dieoffset, attr, form,
369 reader_->ReadOneByte(start) 420 reader_->ReadOneByte(start)
370 + offset_from_section_start_); 421 + offset_from_section_start_);
371 return start + 1; 422 return start + 1;
372 case DW_FORM_ref2: 423 case DW_FORM_ref2:
373 handler_->ProcessAttributeReference(dieoffset, attr, form, 424 handler_->ProcessAttributeReference(dieoffset, attr, form,
374 reader_->ReadTwoBytes(start) 425 reader_->ReadTwoBytes(start)
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 datalen); 485 datalen);
435 return start + datalen + len; 486 return start + datalen + len;
436 } 487 }
437 case DW_FORM_strp: { 488 case DW_FORM_strp: {
438 assert(string_buffer_ != NULL); 489 assert(string_buffer_ != NULL);
439 490
440 const uint64 offset = reader_->ReadOffset(start); 491 const uint64 offset = reader_->ReadOffset(start);
441 assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_); 492 assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_);
442 493
443 const char *str = reinterpret_cast<const char *>(string_buffer_ + offset); 494 const char *str = reinterpret_cast<const char *>(string_buffer_ + offset);
444 handler_->ProcessAttributeString(dieoffset, attr, form, 495 ProcessAttributeString(dieoffset, attr, form, str);
445 str);
446 return start + reader_->OffsetSize(); 496 return start + reader_->OffsetSize();
447 } 497 }
498
499 case DW_FORM_GNU_str_index: {
500 uint64 str_index = reader_->ReadUnsignedLEB128(start, &len);
501 const uint8_t* offset_ptr =
502 str_offsets_buffer_ + str_index * reader_->OffsetSize();
503 const uint64 offset = reader_->ReadOffset(offset_ptr);
504 if (offset >= string_buffer_length_) {
505 return NULL;
506 }
507
508 const char* str = reinterpret_cast<const char *>(string_buffer_) + offset;
509 ProcessAttributeString(dieoffset, attr, form, str);
510 return start + len;
511 break;
512 }
513 case DW_FORM_GNU_addr_index: {
514 uint64 addr_index = reader_->ReadUnsignedLEB128(start, &len);
515 const uint8_t* addr_ptr =
516 addr_buffer_ + addr_base_ + addr_index * reader_->AddressSize();
517 ProcessAttributeUnsigned(dieoffset, attr, form,
518 reader_->ReadAddress(addr_ptr));
519 return start + len;
520 }
448 } 521 }
449 fprintf(stderr, "Unhandled form type\n"); 522 fprintf(stderr, "Unhandled form type\n");
450 return NULL; 523 return NULL;
451 } 524 }
452 525
453 const uint8_t *CompilationUnit::ProcessDIE(uint64 dieoffset, 526 const uint8_t *CompilationUnit::ProcessDIE(uint64 dieoffset,
454 const uint8_t *start, 527 const uint8_t *start,
455 const Abbrev& abbrev) { 528 const Abbrev& abbrev) {
456 for (AttributeList::const_iterator i = abbrev.attributes.begin(); 529 for (AttributeList::const_iterator i = abbrev.attributes.begin();
457 i != abbrev.attributes.end(); 530 i != abbrev.attributes.end();
458 i++) { 531 i++) {
459 start = ProcessAttribute(dieoffset, start, i->first, i->second); 532 start = ProcessAttribute(dieoffset, start, i->first, i->second);
460 } 533 }
534
535 // If this is a compilation unit in a split DWARF object, verify that
536 // the dwo_id matches. If it does not match, we will ignore this
537 // compilation unit.
538 if (abbrev.tag == DW_TAG_compile_unit
539 && is_split_dwarf_
540 && dwo_id_ != skeleton_dwo_id_) {
541 return NULL;
542 }
543
461 return start; 544 return start;
462 } 545 }
463 546
464 void CompilationUnit::ProcessDIEs() { 547 void CompilationUnit::ProcessDIEs() {
465 const uint8_t *dieptr = after_header_; 548 const uint8_t *dieptr = after_header_;
466 size_t len; 549 size_t len;
467 550
468 // lengthstart is the place the length field is based on. 551 // lengthstart is the place the length field is based on.
469 // It is the point in the header after the initial length field 552 // It is the point in the header after the initial length field
470 const uint8_t *lengthstart = buffer_; 553 const uint8_t *lengthstart = buffer_;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 } 591 }
509 592
510 if (abbrev.has_children) { 593 if (abbrev.has_children) {
511 die_stack.push(absolute_offset); 594 die_stack.push(absolute_offset);
512 } else { 595 } else {
513 handler_->EndDIE(absolute_offset); 596 handler_->EndDIE(absolute_offset);
514 } 597 }
515 } 598 }
516 } 599 }
517 600
601 // Check for a valid ELF file and return the Address size.
602 // Returns 0 if not a valid ELF file.
603 inline int GetElfWidth(const ElfReader& elf) {
604 if (elf.IsElf32File())
605 return 4;
606 if (elf.IsElf64File())
607 return 8;
608 return 0;
609 }
610
611 void CompilationUnit::ProcessSplitDwarf() {
612 struct stat statbuf;
613 if (!have_checked_for_dwp_) {
614 // Look for a .dwp file in the same directory as the executable.
615 have_checked_for_dwp_ = true;
616 string dwp_suffix(".dwp");
617 dwp_path_ = path_ + dwp_suffix;
618 if (stat(dwp_path_.c_str(), &statbuf) != 0) {
619 // Fall back to a split .debug file in the same directory.
620 string debug_suffix(".debug");
621 dwp_path_ = path_;
622 size_t found = path_.rfind(debug_suffix);
623 if (found + debug_suffix.length() == path_.length())
624 dwp_path_ = dwp_path_.replace(found, debug_suffix.length(), dwp_suffix);
625 }
626 if (stat(dwp_path_.c_str(), &statbuf) == 0) {
627 ElfReader* elf = new ElfReader(dwp_path_);
628 int width = GetElfWidth(*elf);
629 if (width != 0) {
630 dwp_byte_reader_.reset(new ByteReader(reader_->GetEndianness()));
631 dwp_byte_reader_->SetAddressSize(width);
632 dwp_reader_.reset(new DwpReader(*dwp_byte_reader_, elf));
633 dwp_reader_->Initialize();
634 } else {
635 delete elf;
636 }
637 }
638 }
639 bool found_in_dwp = false;
640 if (dwp_reader_ != NULL) {
641 // If we have a .dwp file, read the debug sections for the requested CU.
642 SectionMap sections;
643 dwp_reader_->ReadDebugSectionsForCU(dwo_id_, &sections);
644 if (!sections.empty()) {
645 found_in_dwp = true;
646 CompilationUnit dwp_comp_unit(dwp_path_, sections, 0,
647 dwp_byte_reader_.get(), handler_);
648 dwp_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_, addr_base_,
649 ranges_base_, dwo_id_);
650 dwp_comp_unit.Start();
651 }
652 }
653 if (!found_in_dwp) {
654 // If no .dwp file, try to open the .dwo file.
655 if (stat(dwo_name_, &statbuf) == 0) {
656 ElfReader elf(dwo_name_);
657 int width = GetElfWidth(elf);
658 if (width != 0) {
659 ByteReader reader(ENDIANNESS_LITTLE);
660 reader.SetAddressSize(width);
661 SectionMap sections;
662 ReadDebugSectionsFromDwo(&elf, &sections);
663 CompilationUnit dwo_comp_unit(dwo_name_, sections, 0, &reader,
664 handler_);
665 dwo_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_,
666 addr_base_, ranges_base_, dwo_id_);
667 dwo_comp_unit.Start();
668 }
669 }
670 }
671 }
672
673 void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader,
674 SectionMap* sections) {
675 static const char* const section_names[] = {
676 ".debug_abbrev",
677 ".debug_info",
678 ".debug_str_offsets",
679 ".debug_str"
680 };
681 for (unsigned int i = 0u;
682 i < sizeof(section_names)/sizeof(*(section_names)); ++i) {
683 string base_name = section_names[i];
684 string dwo_name = base_name + ".dwo";
685 size_t section_size;
686 const char* section_data = elf_reader->GetSectionByName(dwo_name,
687 &section_size);
688 if (section_data != NULL)
689 sections->insert(std::make_pair(
690 base_name, std::make_pair(reinterpret_cast<const uint8_t *>(section_da ta),
ivanpe 2016/04/27 18:02:07 Please, keep lines <= 80 chars.
yunlian 2016/05/02 21:17:38 Done.
691 section_size)));
692 }
693 }
694
695 DwpReader::DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader)
696 : elf_reader_(elf_reader), byte_reader_(byte_reader),
697 cu_index_(NULL), cu_index_size_(0), string_buffer_(NULL),
698 string_buffer_size_(0), version_(0), ncolumns_(0), nunits_(0),
699 nslots_(0), phash_(NULL), pindex_(NULL), shndx_pool_(NULL),
700 offset_table_(NULL), size_table_(NULL), abbrev_data_(NULL),
701 abbrev_size_(0), info_data_(NULL), info_size_(0),
702 str_offsets_data_(NULL), str_offsets_size_(0) {}
703
704 DwpReader::~DwpReader() {
705 if (elf_reader_) delete elf_reader_;
706 }
707
708 void DwpReader::Initialize() {
709 cu_index_ = elf_reader_->GetSectionByName(".debug_cu_index",
710 &cu_index_size_);
711 if (cu_index_ == NULL) {
712 return;
713 }
714 // The .debug_str.dwo section is shared by all CUs in the file.
715 string_buffer_ = elf_reader_->GetSectionByName(".debug_str.dwo",
716 &string_buffer_size_);
717
718 version_ = byte_reader_.ReadFourBytes(
719 reinterpret_cast<const uint8_t *>(cu_index_));
720
721 if (version_ == 1) {
722 nslots_ = byte_reader_.ReadFourBytes(
723 reinterpret_cast<const uint8_t *>(cu_index_)
724 + 3 * sizeof(uint32));
725 phash_ = cu_index_ + 4 * sizeof(uint32);
726 pindex_ = phash_ + nslots_ * sizeof(uint64);
727 shndx_pool_ = pindex_ + nslots_ * sizeof(uint32);
728 if (shndx_pool_ >= cu_index_ + cu_index_size_) {
729 version_ = 0;
730 }
731 } else if (version_ == 2) {
732 ncolumns_ = byte_reader_.ReadFourBytes(
733 reinterpret_cast<const uint8_t *>(cu_index_) + sizeof(uint32));
734 nunits_ = byte_reader_.ReadFourBytes(
735 reinterpret_cast<const uint8_t *>(cu_index_) + 2 * sizeof(uint32));
736 nslots_ = byte_reader_.ReadFourBytes(
737 reinterpret_cast<const uint8_t *>(cu_index_) + 3 * sizeof(uint32));
738 phash_ = cu_index_ + 4 * sizeof(uint32);
739 pindex_ = phash_ + nslots_ * sizeof(uint64);
740 offset_table_ = pindex_ + nslots_ * sizeof(uint32);
741 size_table_ = offset_table_ + ncolumns_ * (nunits_ + 1) * sizeof(uint32);
742 abbrev_data_ = elf_reader_->GetSectionByName(".debug_abbrev.dwo",
743 &abbrev_size_);
744 info_data_ = elf_reader_->GetSectionByName(".debug_info.dwo", &info_size_);
745 str_offsets_data_ = elf_reader_->GetSectionByName(".debug_str_offsets.dwo",
746 &str_offsets_size_);
747 if (size_table_ >= cu_index_ + cu_index_size_) {
748 version_ = 0;
749 }
750 }
751 }
752
753 void DwpReader::ReadDebugSectionsForCU(uint64 dwo_id,
754 SectionMap* sections) {
755 if (version_ == 1) {
756 int slot = LookupCU(dwo_id);
757 if (slot == -1) {
758 return;
759 }
760
761 // The index table points to the section index pool, where we
762 // can read a list of section indexes for the debug sections
763 // for the CU whose dwo_id we are looking for.
764 int index = byte_reader_.ReadFourBytes(
765 reinterpret_cast<const uint8_t *>(pindex_)
766 + slot * sizeof(uint32));
767 const char* shndx_list = shndx_pool_ + index * sizeof(uint32);
768 for (;;) {
769 if (shndx_list >= cu_index_ + cu_index_size_) {
770 version_ = 0;
771 return;
772 }
773 unsigned int shndx = byte_reader_.ReadFourBytes(
774 reinterpret_cast<const uint8_t *>(shndx_list));
775 shndx_list += sizeof(uint32);
776 if (shndx == 0)
777 break;
778 const char* section_name = elf_reader_->GetSectionName(shndx);
779 size_t section_size;
780 const char* section_data;
781 // We're only interested in these four debug sections.
782 // The section names in the .dwo file end with ".dwo", but we
783 // add them to the sections table with their normal names.
784 if (!strncmp(section_name, ".debug_abbrev", strlen(".debug_abbrev"))) {
785 section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
786 sections->insert(std::make_pair(
787 ".debug_abbrev",
788 std::make_pair(reinterpret_cast<const uint8_t *> (section_data),
789 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",
794 std::make_pair(reinterpret_cast<const uint8_t *> (section_data),
795 section_size)));
796 } else if (!strncmp(section_name, ".debug_str_offsets",
797 strlen(".debug_str_offsets"))) {
798 section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
799 sections->insert(std::make_pair(
800 ".debug_str_offsets",
801 std::make_pair(reinterpret_cast<const uint8_t *> (section_data),
802 section_size)));
803 }
804 }
805 sections->insert(std::make_pair(
806 ".debug_str",
807 std::make_pair(reinterpret_cast<const uint8_t *> (string_buffer_),
808 string_buffer_size_)));
809 } else if (version_ == 2) {
810 uint32 index = LookupCUv2(dwo_id);
811 if (index == 0) {
812 return;
813 }
814
815 // The index points to a row in each of the section offsets table
816 // and the section size table, where we can read the offsets and sizes
817 // of the contributions to each debug section from the CU whose dwo_id
818 // we are looking for. Row 0 of the section offsets table has the
819 // section ids for each column of the table. The size table begins
820 // with row 1.
821 const char* id_row = offset_table_;
822 const char* offset_row = offset_table_
823 + index * ncolumns_ * sizeof(uint32);
824 const char* size_row =
825 size_table_ + (index - 1) * ncolumns_ * sizeof(uint32);
826 if (size_row + ncolumns_ * sizeof(uint32) > cu_index_ + cu_index_size_) {
827 version_ = 0;
828 return;
829 }
830 for (unsigned int col = 0u; col < ncolumns_; ++col) {
831 uint32 section_id =
832 byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(id_row)
833 + col * sizeof(uint32));
834 uint32 offset = byte_reader_.ReadFourBytes(
835 reinterpret_cast<const uint8_t *>(offset_row)
836 + col * sizeof(uint32));
837 uint32 size = byte_reader_.ReadFourBytes(
838 reinterpret_cast<const uint8_t *>(size_row) + col * sizeof(uint32));
839 if (section_id == DW_SECT_ABBREV) {
840 sections->insert(std::make_pair(
841 ".debug_abbrev",
842 std::make_pair(reinterpret_cast<const uint8_t *> (abbrev_data_)
843 + offset, size)));
844 } else if (section_id == DW_SECT_INFO) {
845 sections->insert(std::make_pair(
846 ".debug_info",
847 std::make_pair(reinterpret_cast<const uint8_t *> (info_data_)
848 + offset, size)));
849 } else if (section_id == DW_SECT_STR_OFFSETS) {
850 sections->insert(std::make_pair(
851 ".debug_str_offsets",
852 std::make_pair(reinterpret_cast<const uint8_t *> (str_offsets_data_)
853 + offset, size)));
854 }
855 }
856 sections->insert(std::make_pair(
857 ".debug_str",
858 std::make_pair(reinterpret_cast<const uint8_t *> (string_buffer_),
859 string_buffer_size_)));
860 }
861 }
862
863 int DwpReader::LookupCU(uint64 dwo_id) {
864 uint32 slot = static_cast<uint32>(dwo_id) & (nslots_ - 1);
865 uint64 probe = byte_reader_.ReadEightBytes(
866 reinterpret_cast<const uint8_t *>(phash_) + slot * sizeof(uint64));
867 if (probe != 0 && probe != dwo_id) {
868 uint32 secondary_hash =
869 (static_cast<uint32>(dwo_id >> 32) & (nslots_ - 1)) | 1;
870 do {
871 slot = (slot + secondary_hash) & (nslots_ - 1);
872 probe = byte_reader_.ReadEightBytes(
873 reinterpret_cast<const uint8_t *>(phash_) + slot * sizeof(uint64));
874 } while (probe != 0 && probe != dwo_id);
875 }
876 if (probe == 0)
877 return -1;
878 return slot;
879 }
880
881 uint32 DwpReader::LookupCUv2(uint64 dwo_id) {
882 uint32 slot = static_cast<uint32>(dwo_id) & (nslots_ - 1);
883 uint64 probe = byte_reader_.ReadEightBytes(
884 reinterpret_cast<const uint8_t *>(phash_) + slot * sizeof(uint64));
885 uint32 index = byte_reader_.ReadFourBytes(
886 reinterpret_cast<const uint8_t *>(pindex_) + slot * sizeof(uint32));
887 if (index != 0 && probe != dwo_id) {
888 uint32 secondary_hash =
889 (static_cast<uint32>(dwo_id >> 32) & (nslots_ - 1)) | 1;
890 do {
891 slot = (slot + secondary_hash) & (nslots_ - 1);
892 probe = byte_reader_.ReadEightBytes(
893 reinterpret_cast<const uint8_t *>(phash_) + slot * sizeof(uint64));
894 index = byte_reader_.ReadFourBytes(
895 reinterpret_cast<const uint8_t *>(pindex_) + slot * sizeof(uint32));
896 } while (index != 0 && probe != dwo_id);
897 }
898 return index;
899 }
900
518 LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length, 901 LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length,
519 ByteReader* reader, LineInfoHandler* handler): 902 ByteReader* reader, LineInfoHandler* handler):
520 handler_(handler), reader_(reader), buffer_(buffer) { 903 handler_(handler), reader_(reader), buffer_(buffer) {
521 #ifndef NDEBUG 904 #ifndef NDEBUG
522 buffer_length_ = buffer_length; 905 buffer_length_ = buffer_length;
523 #endif 906 #endif
524 header_.std_opcode_lengths = NULL; 907 header_.std_opcode_lengths = NULL;
525 } 908 }
526 909
527 uint64 LineInfo::Start() { 910 uint64 LineInfo::Start() {
(...skipping 1811 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 uint64 insn_offset) { 2722 uint64 insn_offset) {
2340 fprintf(stderr, 2723 fprintf(stderr,
2341 "%s: CFI %s at offset 0x%llx in section '%s':" 2724 "%s: CFI %s at offset 0x%llx in section '%s':"
2342 " the DW_CFA_restore_state instruction at offset 0x%llx" 2725 " the DW_CFA_restore_state instruction at offset 0x%llx"
2343 " would clear the CFA rule in effect\n", 2726 " would clear the CFA rule in effect\n",
2344 filename_.c_str(), CallFrameInfo::KindName(kind), offset, 2727 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
2345 section_.c_str(), insn_offset); 2728 section_.c_str(), insn_offset);
2346 } 2729 }
2347 2730
2348 } // namespace dwarf2reader 2731 } // namespace dwarf2reader
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698