dump_syms: Fix handling of DW_FORM_ref_addr to work with DWARF 4
Previously, dump_syms did not handle DW_FORM_ref_addr if it appeared in DWARF 4 debugging info. Also fix a DW_FORM_ref_addr case so that it doesn't fall through to the next switch case when assertions are disabled and the DWARF version isn't recognised. The following steps will reproduce the problem when using LLVM 3.4: cat <<END >example1.c int main() { return 0; } END cat <<END >example2.c void foo(int x) {} END clang -emit-llvm -g -c example1.c -o example1.bc clang -emit-llvm -g -c example2.c -o example2.bc llvm-link-3.4 example1.bc example2.bc -o combined.bc clang combined.bc -o executable ./google-breakpad/build/src/tools/linux/dump_syms/dump_syms executable When using LLVM bitcode linking in this way, LLVM's backend generates partially-merged DWARF debugging info in which some of the references to the "int" type go via "DW_FORM_ref_addr". Since PNaCl uses LLVM bitcode linking, this dump_syms failure occurs with nexes produced by the PNaCl toolchain. BUG= https://code.google.com/p/chromium/issues/detail?id=416368 TEST= see above R=mark@chromium.org, mcgrathr@chromium.org Review URL: https://breakpad.appspot.com/5744002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1408 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
0b6cc95246
commit
10baadae40
1 changed files with 7 additions and 6 deletions
|
@ -183,14 +183,15 @@ const char* CompilationUnit::SkipAttribute(const char* start,
|
||||||
case DW_FORM_addr:
|
case DW_FORM_addr:
|
||||||
return start + reader_->AddressSize();
|
return start + reader_->AddressSize();
|
||||||
case DW_FORM_ref_addr:
|
case DW_FORM_ref_addr:
|
||||||
// DWARF2 and 3 differ on whether ref_addr is address size or
|
// DWARF2 and 3/4 differ on whether ref_addr is address size or
|
||||||
// offset size.
|
// offset size.
|
||||||
assert(header_.version == 2 || header_.version == 3);
|
assert(header_.version >= 2);
|
||||||
if (header_.version == 2) {
|
if (header_.version == 2) {
|
||||||
return start + reader_->AddressSize();
|
return start + reader_->AddressSize();
|
||||||
} else if (header_.version == 3) {
|
} else if (header_.version >= 3) {
|
||||||
return start + reader_->OffsetSize();
|
return start + reader_->OffsetSize();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case DW_FORM_block1:
|
case DW_FORM_block1:
|
||||||
return start + 1 + reader_->ReadOneByte(start);
|
return start + 1 + reader_->ReadOneByte(start);
|
||||||
|
@ -390,14 +391,14 @@ const char* CompilationUnit::ProcessAttribute(
|
||||||
+ offset_from_section_start_);
|
+ offset_from_section_start_);
|
||||||
return start + len;
|
return start + len;
|
||||||
case DW_FORM_ref_addr:
|
case DW_FORM_ref_addr:
|
||||||
// DWARF2 and 3 differ on whether ref_addr is address size or
|
// DWARF2 and 3/4 differ on whether ref_addr is address size or
|
||||||
// offset size.
|
// offset size.
|
||||||
assert(header_.version == 2 || header_.version == 3);
|
assert(header_.version >= 2);
|
||||||
if (header_.version == 2) {
|
if (header_.version == 2) {
|
||||||
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
||||||
reader_->ReadAddress(start));
|
reader_->ReadAddress(start));
|
||||||
return start + reader_->AddressSize();
|
return start + reader_->AddressSize();
|
||||||
} else if (header_.version == 3) {
|
} else if (header_.version >= 3) {
|
||||||
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
||||||
reader_->ReadOffset(start));
|
reader_->ReadOffset(start));
|
||||||
return start + reader_->OffsetSize();
|
return start + reader_->OffsetSize();
|
||||||
|
|
Loading…
Reference in a new issue