Breakpad DWARF: Add support for DWARF 4 attribute forms.

This patch allows Breakpad's DWARF reader to at least read or skip
attributes using the new forms defined in version 4 of the DWARF
specification, instead of crashing.

Attributes encoded using DW_FORM_flag_present, DW_FORM_sec_offset, and
DW_FORM_exprloc should work fine now. However, compilation units using
DW_FORM_ref_sig8 to refer to types in .debug_types will need further work
to support. (GCC 4.6.2 does not emit .debug_types sections.)

Specifically:

- dwarf2reader::DwarfForm gets new values.
- dwarf2reader::Dwarf2Handler and dwarf2reader::DIEHandler get new handler
  methods, named ProcessAttributeSignature, for DW_FORM_ref_sig8 attributes.
- dwarf2reader::CompilationUnit reads DW_FORM_ref_sig8 attributes, and
  passes them to ProcessAttributeSignature. It also gets support for
  DW_FORM_sec_offset, DW_FORM_exprloc, and DW_FORM_flag_present, using the
  existing appropriate ProcessAttribute* methods.
- dwarf2reader::DIEDispatcher passes through ProcessAttributeSignature
  attributes to its DIEHandler.
- Unit tests are updated.

a=jimb, r=ted.mielczarek
Review URL: http://breakpad.appspot.com/343003/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@912 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
jimblandy 2012-02-01 15:01:54 +00:00
parent 08b912f1ed
commit 5e4f6feaf6
7 changed files with 179 additions and 8 deletions

View file

@ -151,6 +151,8 @@ const char* CompilationUnit::SkipAttribute(const char* start,
start += len;
return SkipAttribute(start, form);
case DW_FORM_flag_present:
return start;
case DW_FORM_data1:
case DW_FORM_flag:
case DW_FORM_ref1:
@ -163,6 +165,7 @@ const char* CompilationUnit::SkipAttribute(const char* start,
return start + 4;
case DW_FORM_ref8:
case DW_FORM_data8:
case DW_FORM_ref_sig8:
return start + 8;
case DW_FORM_string:
return start + strlen(start) + 1;
@ -192,11 +195,13 @@ const char* CompilationUnit::SkipAttribute(const char* start,
return start + 2 + reader_->ReadTwoBytes(start);
case DW_FORM_block4:
return start + 4 + reader_->ReadFourBytes(start);
case DW_FORM_block: {
case DW_FORM_block:
case DW_FORM_exprloc: {
uint64 size = reader_->ReadUnsignedLEB128(start, &len);
return start + size + len;
}
case DW_FORM_strp:
case DW_FORM_sec_offset:
return start + reader_->OffsetSize();
}
fprintf(stderr,"Unhandled form type");
@ -310,6 +315,9 @@ const char* CompilationUnit::ProcessAttribute(
start += len;
return ProcessAttribute(dieoffset, start, attr, form);
case DW_FORM_flag_present:
handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 1);
return start;
case DW_FORM_data1:
case DW_FORM_flag:
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
@ -347,6 +355,10 @@ const char* CompilationUnit::ProcessAttribute(
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadAddress(start));
return start + reader_->AddressSize();
case DW_FORM_sec_offset:
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadOffset(start));
return start + reader_->OffsetSize();
case DW_FORM_ref1:
handler_->ProcessAttributeReference(dieoffset, attr, form,
@ -388,6 +400,10 @@ const char* CompilationUnit::ProcessAttribute(
return start + reader_->OffsetSize();
}
break;
case DW_FORM_ref_sig8:
handler_->ProcessAttributeSignature(dieoffset, attr, form,
reader_->ReadEightBytes(start));
return start + 8;
case DW_FORM_block1: {
uint64 datalen = reader_->ReadOneByte(start);
@ -407,7 +423,8 @@ const char* CompilationUnit::ProcessAttribute(
datalen);
return start + 4 + datalen;
}
case DW_FORM_block: {
case DW_FORM_block:
case DW_FORM_exprloc: {
uint64 datalen = reader_->ReadUnsignedLEB128(start, &len);
handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + len,
datalen);