Breakpad Linux dumper: Record AbstractOrigin entries for all DIEs that need them.

Any DIE with an DW_AT_inline attribute can be cited by
DW_AT_abstract_origin attributes --- even if the value of the
DW_AT_inline attribute is DW_INL_not_inlined. Thus, we need to set the
inline_ flag on all such DIEs, regardless of the attribute's value.
This allows us to find names in situations like this:

 <1><30cf>: Abbrev Number: 57 (DW_TAG_subprogram)
    <30d0>   DW_AT_specification: <0x3013>
    <30d4>   DW_AT_decl_file   : 1
    <30d5>   DW_AT_decl_line   : 92
    <30d6>   DW_AT_inline      : 0        (not inlined)
    <30d7>   DW_AT_sibling     : <0x30f0>
...
 <1><30f5>: Abbrev Number: 59 (DW_TAG_subprogram)
    <30f6>   DW_AT_abstract_origin: <0x30cf>
    <30fa>   DW_AT_low_pc      : 0x13bc
    <30fe>   DW_AT_high_pc     : 0x13ec
    <3102>   DW_AT_frame_base  : 0x2c     (location list)
    <3106>   DW_AT_sibling     : <0x3113>

a=jimblandy, r=nealsid,dmuir


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@526 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
jimblandy 2010-02-20 00:51:22 +00:00
parent 6de1b75da4
commit d6fb5a7c51
2 changed files with 28 additions and 20 deletions

View file

@ -327,16 +327,11 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned(
enum DwarfForm form, enum DwarfForm form,
uint64 data) { uint64 data) {
switch (attr) { switch (attr) {
case dwarf2reader::DW_AT_inline: // If this attribute is present at all --- even if its value is
switch(data) { // DW_INL_not_inlined --- then GCC may cite it as someone else's
case dwarf2reader::DW_INL_inlined: // DW_AT_abstract_origin attribute.
case dwarf2reader::DW_INL_declared_not_inlined: case dwarf2reader::DW_AT_inline: inline_ = true; break;
case dwarf2reader::DW_INL_declared_inlined:
inline_ = true; break;
default:
break;
}
break;
case dwarf2reader::DW_AT_low_pc: low_pc_ = data; break; case dwarf2reader::DW_AT_low_pc: low_pc_ = data; break;
case dwarf2reader::DW_AT_high_pc: high_pc_ = data; break; case dwarf2reader::DW_AT_high_pc: high_pc_ = data; break;
default: default:
@ -350,16 +345,11 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeSigned(
enum DwarfForm form, enum DwarfForm form,
int64 data) { int64 data) {
switch (attr) { switch (attr) {
case dwarf2reader::DW_AT_inline: // If this attribute is present at all --- even if its value is
switch(data) { // DW_INL_not_inlined --- then GCC may cite it as someone else's
case dwarf2reader::DW_INL_inlined: // DW_AT_abstract_origin attribute.
case dwarf2reader::DW_INL_declared_not_inlined: case dwarf2reader::DW_AT_inline: inline_ = true; break;
case dwarf2reader::DW_INL_declared_inlined:
inline_ = true; break;
default:
break;
}
break;
default: default:
break; break;
} }

View file

@ -756,6 +756,24 @@ TEST_F(Simple, InlineFunctionSignedAttribute) {
0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL); 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
} }
// Any DIE with an DW_AT_inline attribute can be cited by
// DW_AT_abstract_origin attributes --- even if the value of the
// DW_AT_inline attribute is DW_INL_not_inlined.
TEST_F(Simple, AbstractOriginNotInlined) {
PushLine(0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL, "line-file", 6111581);
StartCU();
AbstractInstanceDIE(&root_handler_, 0x93e9cdad52826b39ULL,
dwarf2reader::DW_INL_not_inlined, 0, "abstract-instance");
DefineInlineInstanceDIE(&root_handler_, "", 0x93e9cdad52826b39ULL,
0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL);
root_handler_.Finish();
TestFunctionCount(1);
TestFunction(0, "abstract-instance",
0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL);
}
TEST_F(Simple, UnknownAbstractOrigin) { TEST_F(Simple, UnknownAbstractOrigin) {
EXPECT_CALL(reporter_, UnknownAbstractOrigin(_, 1ULL)).WillOnce(Return()); EXPECT_CALL(reporter_, UnknownAbstractOrigin(_, 1ULL)).WillOnce(Return());
PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118); PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);