OLD | NEW |
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 if (iter == sections_.end()) | 76 if (iter == sections_.end()) |
77 iter = sections_.find("__debug_abbrev"); | 77 iter = sections_.find("__debug_abbrev"); |
78 assert(iter != sections_.end()); | 78 assert(iter != sections_.end()); |
79 | 79 |
80 abbrevs_ = new std::vector<Abbrev>; | 80 abbrevs_ = new std::vector<Abbrev>; |
81 abbrevs_->resize(1); | 81 abbrevs_->resize(1); |
82 | 82 |
83 // The only way to check whether we are reading over the end of the | 83 // The only way to check whether we are reading over the end of the |
84 // buffer would be to first compute the size of the leb128 data by | 84 // buffer would be to first compute the size of the leb128 data by |
85 // reading it, then go back and read it again. | 85 // reading it, then go back and read it again. |
86 const char* abbrev_start = iter->second.first + | 86 const uint8_t *abbrev_start = iter->second.first + |
87 header_.abbrev_offset; | 87 header_.abbrev_offset; |
88 const char* abbrevptr = abbrev_start; | 88 const uint8_t *abbrevptr = abbrev_start; |
89 #ifndef NDEBUG | 89 #ifndef NDEBUG |
90 const uint64 abbrev_length = iter->second.second - header_.abbrev_offset; | 90 const uint64 abbrev_length = iter->second.second - header_.abbrev_offset; |
91 #endif | 91 #endif |
92 | 92 |
93 while (1) { | 93 while (1) { |
94 CompilationUnit::Abbrev abbrev; | 94 CompilationUnit::Abbrev abbrev; |
95 size_t len; | 95 size_t len; |
96 const uint64 number = reader_->ReadUnsignedLEB128(abbrevptr, &len); | 96 const uint64 number = reader_->ReadUnsignedLEB128(abbrevptr, &len); |
97 | 97 |
98 if (number == 0) | 98 if (number == 0) |
(...skipping 26 matching lines...) Expand all Loading... |
125 static_cast<enum DwarfAttribute>(nametemp); | 125 static_cast<enum DwarfAttribute>(nametemp); |
126 const enum DwarfForm form = static_cast<enum DwarfForm>(formtemp); | 126 const enum DwarfForm form = static_cast<enum DwarfForm>(formtemp); |
127 abbrev.attributes.push_back(std::make_pair(name, form)); | 127 abbrev.attributes.push_back(std::make_pair(name, form)); |
128 } | 128 } |
129 assert(abbrev.number == abbrevs_->size()); | 129 assert(abbrev.number == abbrevs_->size()); |
130 abbrevs_->push_back(abbrev); | 130 abbrevs_->push_back(abbrev); |
131 } | 131 } |
132 } | 132 } |
133 | 133 |
134 // Skips a single DIE's attributes. | 134 // Skips a single DIE's attributes. |
135 const char* CompilationUnit::SkipDIE(const char* start, | 135 const uint8_t *CompilationUnit::SkipDIE(const uint8_t* start, |
136 const Abbrev& abbrev) { | 136 const Abbrev& abbrev) { |
137 for (AttributeList::const_iterator i = abbrev.attributes.begin(); | 137 for (AttributeList::const_iterator i = abbrev.attributes.begin(); |
138 i != abbrev.attributes.end(); | 138 i != abbrev.attributes.end(); |
139 i++) { | 139 i++) { |
140 start = SkipAttribute(start, i->second); | 140 start = SkipAttribute(start, i->second); |
141 } | 141 } |
142 return start; | 142 return start; |
143 } | 143 } |
144 | 144 |
145 // Skips a single attribute form's data. | 145 // Skips a single attribute form's data. |
146 const char* CompilationUnit::SkipAttribute(const char* start, | 146 const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start, |
147 enum DwarfForm form) { | 147 enum DwarfForm form) { |
148 size_t len; | 148 size_t len; |
149 | 149 |
150 switch (form) { | 150 switch (form) { |
151 case DW_FORM_indirect: | 151 case DW_FORM_indirect: |
152 form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start, | 152 form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start, |
153 &len)); | 153 &len)); |
154 start += len; | 154 start += len; |
155 return SkipAttribute(start, form); | 155 return SkipAttribute(start, form); |
156 | 156 |
157 case DW_FORM_flag_present: | 157 case DW_FORM_flag_present: |
158 return start; | 158 return start; |
159 case DW_FORM_data1: | 159 case DW_FORM_data1: |
160 case DW_FORM_flag: | 160 case DW_FORM_flag: |
161 case DW_FORM_ref1: | 161 case DW_FORM_ref1: |
162 return start + 1; | 162 return start + 1; |
163 case DW_FORM_ref2: | 163 case DW_FORM_ref2: |
164 case DW_FORM_data2: | 164 case DW_FORM_data2: |
165 return start + 2; | 165 return start + 2; |
166 case DW_FORM_ref4: | 166 case DW_FORM_ref4: |
167 case DW_FORM_data4: | 167 case DW_FORM_data4: |
168 return start + 4; | 168 return start + 4; |
169 case DW_FORM_ref8: | 169 case DW_FORM_ref8: |
170 case DW_FORM_data8: | 170 case DW_FORM_data8: |
171 case DW_FORM_ref_sig8: | 171 case DW_FORM_ref_sig8: |
172 return start + 8; | 172 return start + 8; |
173 case DW_FORM_string: | 173 case DW_FORM_string: |
174 return start + strlen(start) + 1; | 174 return start + strlen(reinterpret_cast<const char *>(start)) + 1; |
175 case DW_FORM_udata: | 175 case DW_FORM_udata: |
176 case DW_FORM_ref_udata: | 176 case DW_FORM_ref_udata: |
177 reader_->ReadUnsignedLEB128(start, &len); | 177 reader_->ReadUnsignedLEB128(start, &len); |
178 return start + len; | 178 return start + len; |
179 | 179 |
180 case DW_FORM_sdata: | 180 case DW_FORM_sdata: |
181 reader_->ReadSignedLEB128(start, &len); | 181 reader_->ReadSignedLEB128(start, &len); |
182 return start + len; | 182 return start + len; |
183 case DW_FORM_addr: | 183 case DW_FORM_addr: |
184 return start + reader_->AddressSize(); | 184 return start + reader_->AddressSize(); |
(...skipping 26 matching lines...) Expand all Loading... |
211 fprintf(stderr,"Unhandled form type"); | 211 fprintf(stderr,"Unhandled form type"); |
212 return NULL; | 212 return NULL; |
213 } | 213 } |
214 | 214 |
215 // Read a DWARF2/3 header. | 215 // Read a DWARF2/3 header. |
216 // The header is variable length in DWARF3 (and DWARF2 as extended by | 216 // The header is variable length in DWARF3 (and DWARF2 as extended by |
217 // most compilers), and consists of an length field, a version number, | 217 // most compilers), and consists of an length field, a version number, |
218 // the offset in the .debug_abbrev section for our abbrevs, and an | 218 // the offset in the .debug_abbrev section for our abbrevs, and an |
219 // address size. | 219 // address size. |
220 void CompilationUnit::ReadHeader() { | 220 void CompilationUnit::ReadHeader() { |
221 const char* headerptr = buffer_; | 221 const uint8_t *headerptr = buffer_; |
222 size_t initial_length_size; | 222 size_t initial_length_size; |
223 | 223 |
224 assert(headerptr + 4 < buffer_ + buffer_length_); | 224 assert(headerptr + 4 < buffer_ + buffer_length_); |
225 const uint64 initial_length | 225 const uint64 initial_length |
226 = reader_->ReadInitialLength(headerptr, &initial_length_size); | 226 = reader_->ReadInitialLength(headerptr, &initial_length_size); |
227 headerptr += initial_length_size; | 227 headerptr += initial_length_size; |
228 header_.length = initial_length; | 228 header_.length = initial_length; |
229 | 229 |
230 assert(headerptr + 2 < buffer_ + buffer_length_); | 230 assert(headerptr + 2 < buffer_ + buffer_length_); |
231 header_.version = reader_->ReadTwoBytes(headerptr); | 231 header_.version = reader_->ReadTwoBytes(headerptr); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 | 298 |
299 // Now that we have our abbreviations, start processing DIE's. | 299 // Now that we have our abbreviations, start processing DIE's. |
300 ProcessDIEs(); | 300 ProcessDIEs(); |
301 | 301 |
302 return ourlength; | 302 return ourlength; |
303 } | 303 } |
304 | 304 |
305 // If one really wanted, you could merge SkipAttribute and | 305 // If one really wanted, you could merge SkipAttribute and |
306 // ProcessAttribute | 306 // ProcessAttribute |
307 // This is all boring data manipulation and calling of the handler. | 307 // This is all boring data manipulation and calling of the handler. |
308 const char* CompilationUnit::ProcessAttribute( | 308 const uint8_t *CompilationUnit::ProcessAttribute( |
309 uint64 dieoffset, const char* start, enum DwarfAttribute attr, | 309 uint64 dieoffset, const uint8_t *start, enum DwarfAttribute attr, |
310 enum DwarfForm form) { | 310 enum DwarfForm form) { |
311 size_t len; | 311 size_t len; |
312 | 312 |
313 switch (form) { | 313 switch (form) { |
314 // DW_FORM_indirect is never used because it is such a space | 314 // DW_FORM_indirect is never used because it is such a space |
315 // waster. | 315 // waster. |
316 case DW_FORM_indirect: | 316 case DW_FORM_indirect: |
317 form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start, | 317 form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start, |
318 &len)); | 318 &len)); |
319 start += len; | 319 start += len; |
(...skipping 13 matching lines...) Expand all Loading... |
333 return start + 2; | 333 return start + 2; |
334 case DW_FORM_data4: | 334 case DW_FORM_data4: |
335 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, | 335 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, |
336 reader_->ReadFourBytes(start)); | 336 reader_->ReadFourBytes(start)); |
337 return start + 4; | 337 return start + 4; |
338 case DW_FORM_data8: | 338 case DW_FORM_data8: |
339 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, | 339 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, |
340 reader_->ReadEightBytes(start)); | 340 reader_->ReadEightBytes(start)); |
341 return start + 8; | 341 return start + 8; |
342 case DW_FORM_string: { | 342 case DW_FORM_string: { |
343 const char* str = start; | 343 const char *str = reinterpret_cast<const char *>(start); |
344 handler_->ProcessAttributeString(dieoffset, attr, form, | 344 handler_->ProcessAttributeString(dieoffset, attr, form, |
345 str); | 345 str); |
346 return start + strlen(str) + 1; | 346 return start + strlen(str) + 1; |
347 } | 347 } |
348 case DW_FORM_udata: | 348 case DW_FORM_udata: |
349 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, | 349 handler_->ProcessAttributeUnsigned(dieoffset, attr, form, |
350 reader_->ReadUnsignedLEB128(start, | 350 reader_->ReadUnsignedLEB128(start, |
351 &len)); | 351 &len)); |
352 return start + len; | 352 return start + len; |
353 | 353 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + len, | 433 handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + len, |
434 datalen); | 434 datalen); |
435 return start + datalen + len; | 435 return start + datalen + len; |
436 } | 436 } |
437 case DW_FORM_strp: { | 437 case DW_FORM_strp: { |
438 assert(string_buffer_ != NULL); | 438 assert(string_buffer_ != NULL); |
439 | 439 |
440 const uint64 offset = reader_->ReadOffset(start); | 440 const uint64 offset = reader_->ReadOffset(start); |
441 assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_); | 441 assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_); |
442 | 442 |
443 const char* str = string_buffer_ + offset; | 443 const char *str = reinterpret_cast<const char *>(string_buffer_ + offset); |
444 handler_->ProcessAttributeString(dieoffset, attr, form, | 444 handler_->ProcessAttributeString(dieoffset, attr, form, |
445 str); | 445 str); |
446 return start + reader_->OffsetSize(); | 446 return start + reader_->OffsetSize(); |
447 } | 447 } |
448 } | 448 } |
449 fprintf(stderr, "Unhandled form type\n"); | 449 fprintf(stderr, "Unhandled form type\n"); |
450 return NULL; | 450 return NULL; |
451 } | 451 } |
452 | 452 |
453 const char* CompilationUnit::ProcessDIE(uint64 dieoffset, | 453 const uint8_t *CompilationUnit::ProcessDIE(uint64 dieoffset, |
454 const char* start, | 454 const uint8_t *start, |
455 const Abbrev& abbrev) { | 455 const Abbrev& abbrev) { |
456 for (AttributeList::const_iterator i = abbrev.attributes.begin(); | 456 for (AttributeList::const_iterator i = abbrev.attributes.begin(); |
457 i != abbrev.attributes.end(); | 457 i != abbrev.attributes.end(); |
458 i++) { | 458 i++) { |
459 start = ProcessAttribute(dieoffset, start, i->first, i->second); | 459 start = ProcessAttribute(dieoffset, start, i->first, i->second); |
460 } | 460 } |
461 return start; | 461 return start; |
462 } | 462 } |
463 | 463 |
464 void CompilationUnit::ProcessDIEs() { | 464 void CompilationUnit::ProcessDIEs() { |
465 const char* dieptr = after_header_; | 465 const uint8_t *dieptr = after_header_; |
466 size_t len; | 466 size_t len; |
467 | 467 |
468 // lengthstart is the place the length field is based on. | 468 // lengthstart is the place the length field is based on. |
469 // It is the point in the header after the initial length field | 469 // It is the point in the header after the initial length field |
470 const char* lengthstart = buffer_; | 470 const uint8_t *lengthstart = buffer_; |
471 | 471 |
472 // In 64 bit dwarf, the initial length is 12 bytes, because of the | 472 // In 64 bit dwarf, the initial length is 12 bytes, because of the |
473 // 0xffffffff at the start. | 473 // 0xffffffff at the start. |
474 if (reader_->OffsetSize() == 8) | 474 if (reader_->OffsetSize() == 8) |
475 lengthstart += 12; | 475 lengthstart += 12; |
476 else | 476 else |
477 lengthstart += 4; | 477 lengthstart += 4; |
478 | 478 |
479 std::stack<uint64> die_stack; | 479 std::stack<uint64> die_stack; |
480 | 480 |
(...skipping 27 matching lines...) Expand all Loading... |
508 } | 508 } |
509 | 509 |
510 if (abbrev.has_children) { | 510 if (abbrev.has_children) { |
511 die_stack.push(absolute_offset); | 511 die_stack.push(absolute_offset); |
512 } else { | 512 } else { |
513 handler_->EndDIE(absolute_offset); | 513 handler_->EndDIE(absolute_offset); |
514 } | 514 } |
515 } | 515 } |
516 } | 516 } |
517 | 517 |
518 LineInfo::LineInfo(const char* buffer, uint64 buffer_length, | 518 LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length, |
519 ByteReader* reader, LineInfoHandler* handler): | 519 ByteReader* reader, LineInfoHandler* handler): |
520 handler_(handler), reader_(reader), buffer_(buffer) { | 520 handler_(handler), reader_(reader), buffer_(buffer) { |
521 #ifndef NDEBUG | 521 #ifndef NDEBUG |
522 buffer_length_ = buffer_length; | 522 buffer_length_ = buffer_length; |
523 #endif | 523 #endif |
524 header_.std_opcode_lengths = NULL; | 524 header_.std_opcode_lengths = NULL; |
525 } | 525 } |
526 | 526 |
527 uint64 LineInfo::Start() { | 527 uint64 LineInfo::Start() { |
528 ReadHeader(); | 528 ReadHeader(); |
529 ReadLines(); | 529 ReadLines(); |
530 return after_header_ - buffer_; | 530 return after_header_ - buffer_; |
531 } | 531 } |
532 | 532 |
533 // The header for a debug_line section is mildly complicated, because | 533 // The header for a debug_line section is mildly complicated, because |
534 // the line info is very tightly encoded. | 534 // the line info is very tightly encoded. |
535 void LineInfo::ReadHeader() { | 535 void LineInfo::ReadHeader() { |
536 const char* lineptr = buffer_; | 536 const uint8_t *lineptr = buffer_; |
537 size_t initial_length_size; | 537 size_t initial_length_size; |
538 | 538 |
539 const uint64 initial_length | 539 const uint64 initial_length |
540 = reader_->ReadInitialLength(lineptr, &initial_length_size); | 540 = reader_->ReadInitialLength(lineptr, &initial_length_size); |
541 | 541 |
542 lineptr += initial_length_size; | 542 lineptr += initial_length_size; |
543 header_.total_length = initial_length; | 543 header_.total_length = initial_length; |
544 assert(buffer_ + initial_length_size + header_.total_length <= | 544 assert(buffer_ + initial_length_size + header_.total_length <= |
545 buffer_ + buffer_length_); | 545 buffer_ + buffer_length_); |
546 | 546 |
(...skipping 26 matching lines...) Expand all Loading... |
573 (*header_.std_opcode_lengths)[0] = 0; | 573 (*header_.std_opcode_lengths)[0] = 0; |
574 for (int i = 1; i < header_.opcode_base; i++) { | 574 for (int i = 1; i < header_.opcode_base; i++) { |
575 (*header_.std_opcode_lengths)[i] = reader_->ReadOneByte(lineptr); | 575 (*header_.std_opcode_lengths)[i] = reader_->ReadOneByte(lineptr); |
576 lineptr += 1; | 576 lineptr += 1; |
577 } | 577 } |
578 | 578 |
579 // It is legal for the directory entry table to be empty. | 579 // It is legal for the directory entry table to be empty. |
580 if (*lineptr) { | 580 if (*lineptr) { |
581 uint32 dirindex = 1; | 581 uint32 dirindex = 1; |
582 while (*lineptr) { | 582 while (*lineptr) { |
583 const char* dirname = lineptr; | 583 const char *dirname = reinterpret_cast<const char *>(lineptr); |
584 handler_->DefineDir(dirname, dirindex); | 584 handler_->DefineDir(dirname, dirindex); |
585 lineptr += strlen(dirname) + 1; | 585 lineptr += strlen(dirname) + 1; |
586 dirindex++; | 586 dirindex++; |
587 } | 587 } |
588 } | 588 } |
589 lineptr++; | 589 lineptr++; |
590 | 590 |
591 // It is also legal for the file entry table to be empty. | 591 // It is also legal for the file entry table to be empty. |
592 if (*lineptr) { | 592 if (*lineptr) { |
593 uint32 fileindex = 1; | 593 uint32 fileindex = 1; |
594 size_t len; | 594 size_t len; |
595 while (*lineptr) { | 595 while (*lineptr) { |
596 const char* filename = lineptr; | 596 const char *filename = reinterpret_cast<const char *>(lineptr); |
597 lineptr += strlen(filename) + 1; | 597 lineptr += strlen(filename) + 1; |
598 | 598 |
599 uint64 dirindex = reader_->ReadUnsignedLEB128(lineptr, &len); | 599 uint64 dirindex = reader_->ReadUnsignedLEB128(lineptr, &len); |
600 lineptr += len; | 600 lineptr += len; |
601 | 601 |
602 uint64 mod_time = reader_->ReadUnsignedLEB128(lineptr, &len); | 602 uint64 mod_time = reader_->ReadUnsignedLEB128(lineptr, &len); |
603 lineptr += len; | 603 lineptr += len; |
604 | 604 |
605 uint64 filelength = reader_->ReadUnsignedLEB128(lineptr, &len); | 605 uint64 filelength = reader_->ReadUnsignedLEB128(lineptr, &len); |
606 lineptr += len; | 606 lineptr += len; |
607 handler_->DefineFile(filename, fileindex, static_cast<uint32>(dirindex), | 607 handler_->DefineFile(filename, fileindex, static_cast<uint32>(dirindex), |
608 mod_time, filelength); | 608 mod_time, filelength); |
609 fileindex++; | 609 fileindex++; |
610 } | 610 } |
611 } | 611 } |
612 lineptr++; | 612 lineptr++; |
613 | 613 |
614 after_header_ = lineptr; | 614 after_header_ = lineptr; |
615 } | 615 } |
616 | 616 |
617 /* static */ | 617 /* static */ |
618 bool LineInfo::ProcessOneOpcode(ByteReader* reader, | 618 bool LineInfo::ProcessOneOpcode(ByteReader* reader, |
619 LineInfoHandler* handler, | 619 LineInfoHandler* handler, |
620 const struct LineInfoHeader &header, | 620 const struct LineInfoHeader &header, |
621 const char* start, | 621 const uint8_t *start, |
622 struct LineStateMachine* lsm, | 622 struct LineStateMachine* lsm, |
623 size_t* len, | 623 size_t* len, |
624 uintptr pc, | 624 uintptr pc, |
625 bool *lsm_passes_pc) { | 625 bool *lsm_passes_pc) { |
626 size_t oplen = 0; | 626 size_t oplen = 0; |
627 size_t templen; | 627 size_t templen; |
628 uint8 opcode = reader->ReadOneByte(start); | 628 uint8 opcode = reader->ReadOneByte(start); |
629 oplen++; | 629 oplen++; |
630 start++; | 630 start++; |
631 | 631 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 case DW_LNE_set_address: { | 752 case DW_LNE_set_address: { |
753 // With gcc 4.2.1, we cannot tell the line_no here since | 753 // With gcc 4.2.1, we cannot tell the line_no here since |
754 // DW_LNE_set_address is called before DW_LNS_advance_line is | 754 // DW_LNE_set_address is called before DW_LNS_advance_line is |
755 // called. So we do not check if the lsm passes "pc" here. See | 755 // called. So we do not check if the lsm passes "pc" here. See |
756 // also the comment in DW_LNS_advance_line. | 756 // also the comment in DW_LNS_advance_line. |
757 uint64 address = reader->ReadAddress(start); | 757 uint64 address = reader->ReadAddress(start); |
758 lsm->address = address; | 758 lsm->address = address; |
759 } | 759 } |
760 break; | 760 break; |
761 case DW_LNE_define_file: { | 761 case DW_LNE_define_file: { |
762 const char* filename = start; | 762 const char *filename = reinterpret_cast<const char *>(start); |
763 | 763 |
764 templen = strlen(filename) + 1; | 764 templen = strlen(filename) + 1; |
765 start += templen; | 765 start += templen; |
766 | 766 |
767 uint64 dirindex = reader->ReadUnsignedLEB128(start, &templen); | 767 uint64 dirindex = reader->ReadUnsignedLEB128(start, &templen); |
768 oplen += templen; | 768 oplen += templen; |
769 | 769 |
770 const uint64 mod_time = reader->ReadUnsignedLEB128(start, | 770 const uint64 mod_time = reader->ReadUnsignedLEB128(start, |
771 &templen); | 771 &templen); |
772 oplen += templen; | 772 oplen += templen; |
(...skipping 26 matching lines...) Expand all Loading... |
799 } | 799 } |
800 *len = oplen; | 800 *len = oplen; |
801 return false; | 801 return false; |
802 } | 802 } |
803 | 803 |
804 void LineInfo::ReadLines() { | 804 void LineInfo::ReadLines() { |
805 struct LineStateMachine lsm; | 805 struct LineStateMachine lsm; |
806 | 806 |
807 // lengthstart is the place the length field is based on. | 807 // lengthstart is the place the length field is based on. |
808 // It is the point in the header after the initial length field | 808 // It is the point in the header after the initial length field |
809 const char* lengthstart = buffer_; | 809 const uint8_t *lengthstart = buffer_; |
810 | 810 |
811 // In 64 bit dwarf, the initial length is 12 bytes, because of the | 811 // In 64 bit dwarf, the initial length is 12 bytes, because of the |
812 // 0xffffffff at the start. | 812 // 0xffffffff at the start. |
813 if (reader_->OffsetSize() == 8) | 813 if (reader_->OffsetSize() == 8) |
814 lengthstart += 12; | 814 lengthstart += 12; |
815 else | 815 else |
816 lengthstart += 4; | 816 lengthstart += 4; |
817 | 817 |
818 const char* lineptr = after_header_; | 818 const uint8_t *lineptr = after_header_; |
819 lsm.Reset(header_.default_is_stmt); | 819 lsm.Reset(header_.default_is_stmt); |
820 | 820 |
821 // The LineInfoHandler interface expects each line's length along | 821 // The LineInfoHandler interface expects each line's length along |
822 // with its address, but DWARF only provides addresses (sans | 822 // with its address, but DWARF only provides addresses (sans |
823 // length), and an end-of-sequence address; one infers the length | 823 // length), and an end-of-sequence address; one infers the length |
824 // from the next address. So we report a line only when we get the | 824 // from the next address. So we report a line only when we get the |
825 // next line's address, or the end-of-sequence address. | 825 // next line's address, or the end-of-sequence address. |
826 bool have_pending_line = false; | 826 bool have_pending_line = false; |
827 uint64 pending_address = 0; | 827 uint64 pending_address = 0; |
828 uint32 pending_file_num = 0, pending_line_num = 0, pending_column_num = 0; | 828 uint32 pending_file_num = 0, pending_line_num = 0, pending_column_num = 0; |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 Reporter *reporter_; | 1307 Reporter *reporter_; |
1308 | 1308 |
1309 // The code address to which the next instruction in the stream applies. | 1309 // The code address to which the next instruction in the stream applies. |
1310 uint64 address_; | 1310 uint64 address_; |
1311 | 1311 |
1312 // The entry whose instructions we are currently processing. This is | 1312 // The entry whose instructions we are currently processing. This is |
1313 // first a CIE, and then an FDE. | 1313 // first a CIE, and then an FDE. |
1314 const Entry *entry_; | 1314 const Entry *entry_; |
1315 | 1315 |
1316 // The next instruction to process. | 1316 // The next instruction to process. |
1317 const char *cursor_; | 1317 const uint8_t *cursor_; |
1318 | 1318 |
1319 // The current set of rules. | 1319 // The current set of rules. |
1320 RuleMap rules_; | 1320 RuleMap rules_; |
1321 | 1321 |
1322 // The set of rules established by the CIE, used by DW_CFA_restore | 1322 // The set of rules established by the CIE, used by DW_CFA_restore |
1323 // and DW_CFA_restore_extended. We set this after interpreting the | 1323 // and DW_CFA_restore_extended. We set this after interpreting the |
1324 // CIE's instructions. | 1324 // CIE's instructions. |
1325 RuleMap cie_rules_; | 1325 RuleMap cie_rules_; |
1326 | 1326 |
1327 // A stack of saved states, for DW_CFA_remember_state and | 1327 // A stack of saved states, for DW_CFA_remember_state and |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1405 if (8 > bytes_left) return ReportIncomplete(); | 1405 if (8 > bytes_left) return ReportIncomplete(); |
1406 operands->offset = reader_->ReadEightBytes(cursor_); | 1406 operands->offset = reader_->ReadEightBytes(cursor_); |
1407 cursor_ += 8; | 1407 cursor_ += 8; |
1408 break; | 1408 break; |
1409 | 1409 |
1410 case 'e': { | 1410 case 'e': { |
1411 size_t expression_length = reader_->ReadUnsignedLEB128(cursor_, &len); | 1411 size_t expression_length = reader_->ReadUnsignedLEB128(cursor_, &len); |
1412 if (len > bytes_left || expression_length > bytes_left - len) | 1412 if (len > bytes_left || expression_length > bytes_left - len) |
1413 return ReportIncomplete(); | 1413 return ReportIncomplete(); |
1414 cursor_ += len; | 1414 cursor_ += len; |
1415 operands->expression = string(cursor_, expression_length); | 1415 operands->expression = string(reinterpret_cast<const char *>(cursor_), |
| 1416 expression_length); |
1416 cursor_ += expression_length; | 1417 cursor_ += expression_length; |
1417 break; | 1418 break; |
1418 } | 1419 } |
1419 | 1420 |
1420 default: | 1421 default: |
1421 assert(0); | 1422 assert(0); |
1422 } | 1423 } |
1423 } | 1424 } |
1424 | 1425 |
1425 return true; | 1426 return true; |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 if (!rule) { | 1759 if (!rule) { |
1759 // This isn't really the right thing to do, but since CFI generally | 1760 // This isn't really the right thing to do, but since CFI generally |
1760 // only mentions callee-saves registers, and GCC's convention for | 1761 // only mentions callee-saves registers, and GCC's convention for |
1761 // callee-saves registers is that they are unchanged, it's a good | 1762 // callee-saves registers is that they are unchanged, it's a good |
1762 // approximation. | 1763 // approximation. |
1763 rule = new SameValueRule(); | 1764 rule = new SameValueRule(); |
1764 } | 1765 } |
1765 return DoRule(reg, rule); | 1766 return DoRule(reg, rule); |
1766 } | 1767 } |
1767 | 1768 |
1768 bool CallFrameInfo::ReadEntryPrologue(const char *cursor, Entry *entry) { | 1769 bool CallFrameInfo::ReadEntryPrologue(const uint8_t *cursor, Entry *entry) { |
1769 const char *buffer_end = buffer_ + buffer_length_; | 1770 const uint8_t *buffer_end = buffer_ + buffer_length_; |
1770 | 1771 |
1771 // Initialize enough of ENTRY for use in error reporting. | 1772 // Initialize enough of ENTRY for use in error reporting. |
1772 entry->offset = cursor - buffer_; | 1773 entry->offset = cursor - buffer_; |
1773 entry->start = cursor; | 1774 entry->start = cursor; |
1774 entry->kind = kUnknown; | 1775 entry->kind = kUnknown; |
1775 entry->end = NULL; | 1776 entry->end = NULL; |
1776 | 1777 |
1777 // Read the initial length. This sets reader_'s offset size. | 1778 // Read the initial length. This sets reader_'s offset size. |
1778 size_t length_size; | 1779 size_t length_size; |
1779 uint64 length = reader_->ReadInitialLength(cursor, &length_size); | 1780 uint64 length = reader_->ReadInitialLength(cursor, &length_size); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 | 1838 |
1838 // The fields specific to this kind of entry start here. | 1839 // The fields specific to this kind of entry start here. |
1839 entry->fields = cursor; | 1840 entry->fields = cursor; |
1840 | 1841 |
1841 entry->cie = NULL; | 1842 entry->cie = NULL; |
1842 | 1843 |
1843 return true; | 1844 return true; |
1844 } | 1845 } |
1845 | 1846 |
1846 bool CallFrameInfo::ReadCIEFields(CIE *cie) { | 1847 bool CallFrameInfo::ReadCIEFields(CIE *cie) { |
1847 const char *cursor = cie->fields; | 1848 const uint8_t *cursor = cie->fields; |
1848 size_t len; | 1849 size_t len; |
1849 | 1850 |
1850 assert(cie->kind == kCIE); | 1851 assert(cie->kind == kCIE); |
1851 | 1852 |
1852 // Prepare for early exit. | 1853 // Prepare for early exit. |
1853 cie->version = 0; | 1854 cie->version = 0; |
1854 cie->augmentation.clear(); | 1855 cie->augmentation.clear(); |
1855 cie->code_alignment_factor = 0; | 1856 cie->code_alignment_factor = 0; |
1856 cie->data_alignment_factor = 0; | 1857 cie->data_alignment_factor = 0; |
1857 cie->return_address_register = 0; | 1858 cie->return_address_register = 0; |
(...skipping 10 matching lines...) Expand all Loading... |
1868 // If we don't recognize the version, we can't parse any more fields of the | 1869 // If we don't recognize the version, we can't parse any more fields of the |
1869 // CIE. For DWARF CFI, we handle versions 1 through 3 (there was never a | 1870 // CIE. For DWARF CFI, we handle versions 1 through 3 (there was never a |
1870 // version 2 of CFI data). For .eh_frame, we handle versions 1 and 3 as well; | 1871 // version 2 of CFI data). For .eh_frame, we handle versions 1 and 3 as well; |
1871 // the difference between those versions seems to be the same as for | 1872 // the difference between those versions seems to be the same as for |
1872 // .debug_frame. | 1873 // .debug_frame. |
1873 if (cie->version < 1 || cie->version > 3) { | 1874 if (cie->version < 1 || cie->version > 3) { |
1874 reporter_->UnrecognizedVersion(cie->offset, cie->version); | 1875 reporter_->UnrecognizedVersion(cie->offset, cie->version); |
1875 return false; | 1876 return false; |
1876 } | 1877 } |
1877 | 1878 |
1878 const char *augmentation_start = cursor; | 1879 const uint8_t *augmentation_start = cursor; |
1879 const void *augmentation_end = | 1880 const uint8_t *augmentation_end = |
1880 memchr(augmentation_start, '\0', cie->end - augmentation_start); | 1881 reinterpret_cast<const uint8_t *>(memchr(augmentation_start, '\0', |
| 1882 cie->end - augmentation_start)); |
1881 if (! augmentation_end) return ReportIncomplete(cie); | 1883 if (! augmentation_end) return ReportIncomplete(cie); |
1882 cursor = static_cast<const char *>(augmentation_end); | 1884 cursor = augmentation_end; |
1883 cie->augmentation = string(augmentation_start, | 1885 cie->augmentation = string(reinterpret_cast<const char *>(augmentation_start), |
1884 cursor - augmentation_start); | 1886 cursor - augmentation_start); |
1885 // Skip the terminating '\0'. | 1887 // Skip the terminating '\0'. |
1886 cursor++; | 1888 cursor++; |
1887 | 1889 |
1888 // Is this CFI augmented? | 1890 // Is this CFI augmented? |
1889 if (!cie->augmentation.empty()) { | 1891 if (!cie->augmentation.empty()) { |
1890 // Is it an augmentation we recognize? | 1892 // Is it an augmentation we recognize? |
1891 if (cie->augmentation[0] == DW_Z_augmentation_start) { | 1893 if (cie->augmentation[0] == DW_Z_augmentation_start) { |
1892 // Linux C++ ABI 'z' augmentation, used for exception handling data. | 1894 // Linux C++ ABI 'z' augmentation, used for exception handling data. |
1893 cie->has_z_augmentation = true; | 1895 cie->has_z_augmentation = true; |
1894 } else { | 1896 } else { |
(...skipping 25 matching lines...) Expand all Loading... |
1920 cursor += len; | 1922 cursor += len; |
1921 } | 1923 } |
1922 | 1924 |
1923 // If we have a 'z' augmentation string, find the augmentation data and | 1925 // If we have a 'z' augmentation string, find the augmentation data and |
1924 // use the augmentation string to parse it. | 1926 // use the augmentation string to parse it. |
1925 if (cie->has_z_augmentation) { | 1927 if (cie->has_z_augmentation) { |
1926 uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &len); | 1928 uint64_t data_size = reader_->ReadUnsignedLEB128(cursor, &len); |
1927 if (size_t(cie->end - cursor) < len + data_size) | 1929 if (size_t(cie->end - cursor) < len + data_size) |
1928 return ReportIncomplete(cie); | 1930 return ReportIncomplete(cie); |
1929 cursor += len; | 1931 cursor += len; |
1930 const char *data = cursor; | 1932 const uint8_t *data = cursor; |
1931 cursor += data_size; | 1933 cursor += data_size; |
1932 const char *data_end = cursor; | 1934 const uint8_t *data_end = cursor; |
1933 | 1935 |
1934 cie->has_z_lsda = false; | 1936 cie->has_z_lsda = false; |
1935 cie->has_z_personality = false; | 1937 cie->has_z_personality = false; |
1936 cie->has_z_signal_frame = false; | 1938 cie->has_z_signal_frame = false; |
1937 | 1939 |
1938 // Walk the augmentation string, and extract values from the | 1940 // Walk the augmentation string, and extract values from the |
1939 // augmentation data as the string directs. | 1941 // augmentation data as the string directs. |
1940 for (size_t i = 1; i < cie->augmentation.size(); i++) { | 1942 for (size_t i = 1; i < cie->augmentation.size(); i++) { |
1941 switch (cie->augmentation[i]) { | 1943 switch (cie->augmentation[i]) { |
1942 case DW_Z_has_LSDA: | 1944 case DW_Z_has_LSDA: |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2014 } | 2016 } |
2015 } | 2017 } |
2016 | 2018 |
2017 // The CIE's instructions start here. | 2019 // The CIE's instructions start here. |
2018 cie->instructions = cursor; | 2020 cie->instructions = cursor; |
2019 | 2021 |
2020 return true; | 2022 return true; |
2021 } | 2023 } |
2022 | 2024 |
2023 bool CallFrameInfo::ReadFDEFields(FDE *fde) { | 2025 bool CallFrameInfo::ReadFDEFields(FDE *fde) { |
2024 const char *cursor = fde->fields; | 2026 const uint8_t *cursor = fde->fields; |
2025 size_t size; | 2027 size_t size; |
2026 | 2028 |
2027 fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding, | 2029 fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding, |
2028 &size); | 2030 &size); |
2029 if (size > size_t(fde->end - cursor)) | 2031 if (size > size_t(fde->end - cursor)) |
2030 return ReportIncomplete(fde); | 2032 return ReportIncomplete(fde); |
2031 cursor += size; | 2033 cursor += size; |
2032 reader_->SetFunctionBase(fde->address); | 2034 reader_->SetFunctionBase(fde->address); |
2033 | 2035 |
2034 // For the length, we strip off the upper nybble of the encoding used for | 2036 // For the length, we strip off the upper nybble of the encoding used for |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2080 cursor += data_size; | 2082 cursor += data_size; |
2081 } | 2083 } |
2082 | 2084 |
2083 // The FDE's instructions start after those. | 2085 // The FDE's instructions start after those. |
2084 fde->instructions = cursor; | 2086 fde->instructions = cursor; |
2085 | 2087 |
2086 return true; | 2088 return true; |
2087 } | 2089 } |
2088 | 2090 |
2089 bool CallFrameInfo::Start() { | 2091 bool CallFrameInfo::Start() { |
2090 const char *buffer_end = buffer_ + buffer_length_; | 2092 const uint8_t *buffer_end = buffer_ + buffer_length_; |
2091 const char *cursor; | 2093 const uint8_t *cursor; |
2092 bool all_ok = true; | 2094 bool all_ok = true; |
2093 const char *entry_end; | 2095 const uint8_t *entry_end; |
2094 bool ok; | 2096 bool ok; |
2095 | 2097 |
2096 // Traverse all the entries in buffer_, skipping CIEs and offering | 2098 // Traverse all the entries in buffer_, skipping CIEs and offering |
2097 // FDEs to the handler. | 2099 // FDEs to the handler. |
2098 for (cursor = buffer_; cursor < buffer_end; | 2100 for (cursor = buffer_; cursor < buffer_end; |
2099 cursor = entry_end, all_ok = all_ok && ok) { | 2101 cursor = entry_end, all_ok = all_ok && ok) { |
2100 FDE fde; | 2102 FDE fde; |
2101 | 2103 |
2102 // Make it easy to skip this entry with 'continue': assume that | 2104 // Make it easy to skip this entry with 'continue': assume that |
2103 // things are not okay until we've checked all the data, and | 2105 // things are not okay until we've checked all the data, and |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2337 uint64 insn_offset) { | 2339 uint64 insn_offset) { |
2338 fprintf(stderr, | 2340 fprintf(stderr, |
2339 "%s: CFI %s at offset 0x%llx in section '%s':" | 2341 "%s: CFI %s at offset 0x%llx in section '%s':" |
2340 " the DW_CFA_restore_state instruction at offset 0x%llx" | 2342 " the DW_CFA_restore_state instruction at offset 0x%llx" |
2341 " would clear the CFA rule in effect\n", | 2343 " would clear the CFA rule in effect\n", |
2342 filename_.c_str(), CallFrameInfo::KindName(kind), offset, | 2344 filename_.c_str(), CallFrameInfo::KindName(kind), offset, |
2343 section_.c_str(), insn_offset); | 2345 section_.c_str(), insn_offset); |
2344 } | 2346 } |
2345 | 2347 |
2346 } // namespace dwarf2reader | 2348 } // namespace dwarf2reader |
OLD | NEW |