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

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));
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
ivanpe 2016/04/27 01:11:44 Please, do not leave a blank line here.
yunlian 2016/04/27 16:35:29 Done.
604 inline int GetElfWidth(const ElfReader& elf) {
605 if (elf.IsElf32File())
606 return 4;
607 if (elf.IsElf64File())
608 return 8;
609 return 0;
610 }
611
612 void CompilationUnit::ProcessSplitDwarf() {
ivanpe 2016/04/27 01:11:44 It looks like the code that follows comes from: ht
yunlian 2016/04/27 16:35:29 Done.
613 struct stat statbuf;
614 if (!have_checked_for_dwp_) {
615 // Look for a .dwp file in the same directory as the executable.
616 have_checked_for_dwp_ = true;
617 string dwp_suffix(".dwp");
618 dwp_path_ = path_ + dwp_suffix;
619 if (stat(dwp_path_.c_str(), &statbuf) != 0) {
620 // Fall back to a split .debug file in the same directory.
621 string debug_suffix(".debug");
622 dwp_path_ = path_;
623 size_t found = path_.rfind(debug_suffix);
624 if (found + debug_suffix.length() == path_.length())
625 dwp_path_ = dwp_path_.replace(found, debug_suffix.length(), dwp_suffix);
626 }
627 if (stat(dwp_path_.c_str(), &statbuf) == 0) {
628 ElfReader* elf = new ElfReader(dwp_path_);
629 int width = GetElfWidth(*elf);
630 if (width != 0) {
631 dwp_byte_reader_.reset(new ByteReader(reader_->GetEndianness()));
632 dwp_byte_reader_->SetAddressSize(width);
633 dwp_reader_.reset(new DwpReader(*dwp_byte_reader_, elf));
634 dwp_reader_->Initialize();
635 } else {
636 delete elf;
637 }
638 }
639 }
640 bool found_in_dwp = false;
641 if (dwp_reader_ != NULL) {
642 // If we have a .dwp file, read the debug sections for the requested CU.
643 SectionMap sections;
644 dwp_reader_->ReadDebugSectionsForCU(dwo_id_, &sections);
645 if (!sections.empty()) {
646 found_in_dwp = true;
647 CompilationUnit dwp_comp_unit(dwp_path_, sections, 0,
648 dwp_byte_reader_.get(), handler_);
649 dwp_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_, addr_base_,
650 ranges_base_, dwo_id_);
651 dwp_comp_unit.Start();
652 }
653 }
654 if (!found_in_dwp) {
655 // If no .dwp file, try to open the .dwo file.
656 if (stat(dwo_name_, &statbuf) == 0) {
657 ElfReader elf(dwo_name_);
658 int width = GetElfWidth(elf);
659 if (width != 0) {
660 ByteReader reader(ENDIANNESS_LITTLE);
661 reader.SetAddressSize(width);
662 SectionMap sections;
663 ReadDebugSectionsFromDwo(&elf, &sections);
664 CompilationUnit dwo_comp_unit(dwo_name_, sections, 0, &reader,
665 handler_);
666 dwo_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_,
667 addr_base_, ranges_base_, dwo_id_);
668 dwo_comp_unit.Start();
669 }
670 }
671 }
672 }
673
674 void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader,
675 SectionMap* sections) {
ivanpe 2016/04/27 01:11:44 indent is off.
yunlian 2016/04/27 16:35:29 Done.
676 static const char* const section_names[] = {
677 ".debug_abbrev",
678 ".debug_info",
679 ".debug_str_offsets",
680 ".debug_str"
681 };
682 for (unsigned int i = 0u; i < sizeof(section_names)/sizeof(*(section_names)); ++i) {
ivanpe 2016/04/27 01:11:44 Lines should be <= 80 chars long
yunlian 2016/04/27 16:35:28 Done.
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), section_size)));
ivanpe 2016/04/27 01:11:44 Lines should be <= 80 chars long
yunlian 2016/04/27 16:35:29 Done.
691 }
692 }
693
694 DwpReader::DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader)
695 : elf_reader_(elf_reader), byte_reader_(byte_reader),
696 cu_index_(NULL), cu_index_size_(0), string_buffer_(NULL),
697 string_buffer_size_(0), version_(0), ncolumns_(0), nunits_(0),
698 nslots_(0), phash_(NULL), pindex_(NULL), shndx_pool_(NULL),
699 offset_table_(NULL), size_table_(NULL), abbrev_data_(NULL),
700 abbrev_size_(0), info_data_(NULL), info_size_(0),
701 str_offsets_data_(NULL), str_offsets_size_(0) {}
702
703 DwpReader::~DwpReader() {
704 if (elf_reader_) delete elf_reader_;
705 }
706
707 void DwpReader::Initialize() {
708 cu_index_ = elf_reader_->GetSectionByName(".debug_cu_index",
709 &cu_index_size_);
710 if (cu_index_ == NULL) {
711 return;
712 }
713 // The .debug_str.dwo section is shared by all CUs in the file.
714 string_buffer_ = elf_reader_->GetSectionByName(".debug_str.dwo",
715 &string_buffer_size_);
716
717 version_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_ind ex_));
ivanpe 2016/04/27 01:11:44 Lines should be <= 80 chars long
yunlian 2016/04/27 16:35:28 Done.
718
719 if (version_ == 1) {
720 nslots_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_in dex_)
ivanpe 2016/04/27 01:11:44 Lines should be <= 80 chars long
yunlian 2016/04/27 16:35:28 Done.
721 + 3 * sizeof(uint32));
722 phash_ = cu_index_ + 4 * sizeof(uint32);
723 pindex_ = phash_ + nslots_ * sizeof(uint64);
724 shndx_pool_ = pindex_ + nslots_ * sizeof(uint32);
725 if (shndx_pool_ >= cu_index_ + cu_index_size_) {
726 version_ = 0;
727 }
728 } else if (version_ == 2) {
729 ncolumns_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_ index_)
ivanpe 2016/04/27 01:11:44 Lines should be <= 80 chars long
yunlian 2016/04/27 16:35:28 Done.
730 + sizeof(uint32));
731 nunits_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_in dex_)
ivanpe 2016/04/27 01:11:44 Lines should be <= 80 chars long
yunlian 2016/04/27 16:35:28 Done.
732 + 2 * sizeof(uint32));
733 nslots_ = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(cu_in dex_)
ivanpe 2016/04/27 01:11:44 Lines should be <= 80 chars long
yunlian 2016/04/27 16:35:28 Done.
734 + 3 * sizeof(uint32));
735 phash_ = cu_index_ + 4 * sizeof(uint32);
736 pindex_ = phash_ + nslots_ * sizeof(uint64);
737 offset_table_ = pindex_ + nslots_ * sizeof(uint32);
738 size_table_ = offset_table_ + ncolumns_ * (nunits_ + 1) * sizeof(uint32);
739 abbrev_data_ = elf_reader_->GetSectionByName(".debug_abbrev.dwo",
740 &abbrev_size_);
741 info_data_ = elf_reader_->GetSectionByName(".debug_info.dwo", &info_size_);
742 str_offsets_data_ = elf_reader_->GetSectionByName(".debug_str_offsets.dwo",
743 &str_offsets_size_);
744 if (size_table_ >= cu_index_ + cu_index_size_) {
745 version_ = 0;
746 }
747 }
748 }
749
750 void DwpReader::ReadDebugSectionsForCU(uint64 dwo_id,
751 SectionMap* sections) {
752 if (version_ == 1) {
753 int slot = LookupCU(dwo_id);
754 if (slot == -1) {
755 return;
756 }
757
758 // The index table points to the section index pool, where we
759 // can read a list of section indexes for the debug sections
760 // for the CU whose dwo_id we are looking for.
761 int index = byte_reader_.ReadFourBytes(
762 reinterpret_cast<const uint8_t *>(pindex_)
763 + slot * sizeof(uint32));
764 const char* shndx_list = shndx_pool_ + index * sizeof(uint32);
765 for (;;) {
766 if (shndx_list >= cu_index_ + cu_index_size_) {
767 version_ = 0;
768 return;
769 }
770 unsigned int shndx = byte_reader_.ReadFourBytes(reinterpret_cast<const uin t8_t *>(shndx_list));
ivanpe 2016/04/27 01:11:44 Lines should be <= 80 chars long Please, apply to
yunlian 2016/04/27 16:35:29 Done.
771 shndx_list += sizeof(uint32);
772 if (shndx == 0)
773 break;
774 const char* section_name = elf_reader_->GetSectionName(shndx);
775 size_t section_size;
776 const char* section_data;
777 // We're only interested in these four debug sections.
778 // The section names in the .dwo file end with ".dwo", but we
779 // add them to the sections table with their normal names.
780 if (!strncmp(section_name, ".debug_abbrev", strlen(".debug_abbrev"))) {
781 section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
782 sections->insert(std::make_pair(
783 ".debug_abbrev", std::make_pair(reinterpret_cast<const uint8_t *> (s ection_data), section_size)));
784 } else if (!strncmp(section_name, ".debug_info", strlen(".debug_info"))) {
785 section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
786 sections->insert(std::make_pair(
787 ".debug_info", std::make_pair(reinterpret_cast<const uint8_t *> (sec tion_data), section_size)));
788 } else if (!strncmp(section_name, ".debug_str_offsets", strlen(".debug_str _offsets"))) {
789 section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
790 sections->insert(std::make_pair(
791 ".debug_str_offsets", std::make_pair(reinterpret_cast<const uint8_t *> (section_data), section_size)));
792 }
793 }
794 sections->insert(std::make_pair(
795 ".debug_str", std::make_pair(reinterpret_cast<const uint8_t *> (string_b uffer_), string_buffer_size_)));
796 } else if (version_ == 2) {
797 uint32 index = LookupCUv2(dwo_id);
798 if (index == 0) {
799 return;
800 }
801
802 // The index points to a row in each of the section offsets table
803 // and the section size table, where we can read the offsets and sizes
804 // of the contributions to each debug section from the CU whose dwo_id
805 // we are looking for. Row 0 of the section offsets table has the
806 // section ids for each column of the table. The size table begins
807 // with row 1.
808 const char* id_row = offset_table_;
809 const char* offset_row = offset_table_ + index * ncolumns_ * sizeof(uint32);
810 const char* size_row =
811 size_table_ + (index - 1) * ncolumns_ * sizeof(uint32);
812 if (size_row + ncolumns_ * sizeof(uint32) > cu_index_ + cu_index_size_) {
813 version_ = 0;
814 return;
815 }
816 for (unsigned int col = 0u; col < ncolumns_; ++col) {
817 uint32 section_id =
818 byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(id_row)
819 + col * sizeof(uint32));
820 uint32 offset =
821 byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(offset_ro w)
822 + col * sizeof(uint32));
823 uint32 size =
824 byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(size_row)
825 + col * sizeof(uint32));
826 if (section_id == DW_SECT_ABBREV) {
827 sections->insert(std::make_pair(
828 ".debug_abbrev", std::make_pair(reinterpret_cast<const uint8_t *> (a bbrev_data_) + offset, size)));
829 } else if (section_id == DW_SECT_INFO) {
830 sections->insert(std::make_pair(
831 ".debug_info", std::make_pair(reinterpret_cast<const uint8_t *> (inf o_data_) + offset, size)));
832 } else if (section_id == DW_SECT_STR_OFFSETS) {
833 sections->insert(
834 std::make_pair(".debug_str_offsets",
835 std::make_pair(reinterpret_cast<const uint8_t *> (str _offsets_data_) + offset, size)));
836 }
837 }
838 sections->insert(std::make_pair(
839 ".debug_str", std::make_pair(reinterpret_cast<const uint8_t *> (string_b uffer_), string_buffer_size_)));
840 }
841 }
842
843 int DwpReader::LookupCU(uint64 dwo_id) {
844 uint32 slot = static_cast<uint32>(dwo_id) & (nslots_ - 1);
845 uint64 probe = byte_reader_.ReadEightBytes(reinterpret_cast<const uint8_t *>(p hash_) + slot * sizeof(uint64));
846 if (probe != 0 && probe != dwo_id) {
847 uint32 secondary_hash =
848 (static_cast<uint32>(dwo_id >> 32) & (nslots_ - 1)) | 1;
849 do {
850 slot = (slot + secondary_hash) & (nslots_ - 1);
851 probe = byte_reader_.ReadEightBytes(reinterpret_cast<const uint8_t *>(phas h_) + slot * sizeof(uint64));
852 } while (probe != 0 && probe != dwo_id);
853 }
854 if (probe == 0)
855 return -1;
856 return slot;
857 }
858
859 uint32 DwpReader::LookupCUv2(uint64 dwo_id) {
860 uint32 slot = static_cast<uint32>(dwo_id) & (nslots_ - 1);
861 uint64 probe = byte_reader_.ReadEightBytes(reinterpret_cast<const uint8_t *>(p hash_) + slot * sizeof(uint64));
862 uint32 index = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(pi ndex_) + slot * sizeof(uint32));
863 if (index != 0 && probe != dwo_id) {
864 uint32 secondary_hash =
865 (static_cast<uint32>(dwo_id >> 32) & (nslots_ - 1)) | 1;
866 do {
867 slot = (slot + secondary_hash) & (nslots_ - 1);
868 probe = byte_reader_.ReadEightBytes(reinterpret_cast<const uint8_t *>(phas h_) + slot * sizeof(uint64));
869 index = byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(pinde x_) + slot * sizeof(uint32));
870 } while (index != 0 && probe != dwo_id);
871 }
872 return index;
873 }
874
518 LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length, 875 LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length,
519 ByteReader* reader, LineInfoHandler* handler): 876 ByteReader* reader, LineInfoHandler* handler):
520 handler_(handler), reader_(reader), buffer_(buffer) { 877 handler_(handler), reader_(reader), buffer_(buffer) {
521 #ifndef NDEBUG 878 #ifndef NDEBUG
522 buffer_length_ = buffer_length; 879 buffer_length_ = buffer_length;
523 #endif 880 #endif
524 header_.std_opcode_lengths = NULL; 881 header_.std_opcode_lengths = NULL;
525 } 882 }
526 883
527 uint64 LineInfo::Start() { 884 uint64 LineInfo::Start() {
(...skipping 1811 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 uint64 insn_offset) { 2696 uint64 insn_offset) {
2340 fprintf(stderr, 2697 fprintf(stderr,
2341 "%s: CFI %s at offset 0x%llx in section '%s':" 2698 "%s: CFI %s at offset 0x%llx in section '%s':"
2342 " the DW_CFA_restore_state instruction at offset 0x%llx" 2699 " the DW_CFA_restore_state instruction at offset 0x%llx"
2343 " would clear the CFA rule in effect\n", 2700 " would clear the CFA rule in effect\n",
2344 filename_.c_str(), CallFrameInfo::KindName(kind), offset, 2701 filename_.c_str(), CallFrameInfo::KindName(kind), offset,
2345 section_.c_str(), insn_offset); 2702 section_.c_str(), insn_offset);
2346 } 2703 }
2347 2704
2348 } // namespace dwarf2reader 2705 } // namespace dwarf2reader
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698