Index: src/common/dwarf/dwarf2reader_die_unittest.cc |
=================================================================== |
--- a/src/common/dwarf/dwarf2reader_die_unittest.cc |
+++ b/src/common/dwarf/dwarf2reader_die_unittest.cc |
@@ -94,16 +94,20 @@ class MockDwarf2Handler: public Dwarf2Ha |
enum DwarfAttribute attr, |
enum DwarfForm form, |
const char* data, |
uint64 len)); |
MOCK_METHOD4(ProcessAttributeString, void(uint64 offset, |
enum DwarfAttribute attr, |
enum DwarfForm form, |
const std::string& data)); |
+ MOCK_METHOD4(ProcessAttributeSignature, void(uint64 offset, |
+ DwarfAttribute attr, |
+ enum DwarfForm form, |
+ uint64 signature)); |
MOCK_METHOD1(EndDIE, void(uint64 offset)); |
}; |
struct DIEFixture { |
DIEFixture() { |
// Fix the initial offset of the .debug_info and .debug_abbrev sections. |
info.start() = 0; |
@@ -246,39 +250,39 @@ struct DwarfFormsFixture: public DIEFixt |
info.Header(params.version, abbrev_table, params.address_size) |
.ULEB128(1); // abbrev code |
} |
// Set up handler to expect a compilation unit matching |params|, |
// containing one childless DIE of the given tag, in the sequence s. Stop |
// just before the expectations. |
void ExpectBeginCompilationUnit(const DwarfHeaderParams ¶ms, |
- DwarfTag tag) { |
+ DwarfTag tag, uint64 offset=0) { |
EXPECT_CALL(handler, |
- StartCompilationUnit(0, params.address_size, |
+ StartCompilationUnit(offset, params.address_size, |
params.format_size, _, |
params.version)) |
.InSequence(s) |
.WillOnce(Return(true)); |
EXPECT_CALL(handler, StartDIE(_, tag, _)) |
.InSequence(s) |
.WillOnce(Return(true)); |
} |
void ExpectEndCompilationUnit() { |
EXPECT_CALL(handler, EndDIE(_)) |
.InSequence(s) |
.WillOnce(Return()); |
} |
- void ParseCompilationUnit(const DwarfHeaderParams ¶ms) { |
+ void ParseCompilationUnit(const DwarfHeaderParams ¶ms, uint64 offset=0) { |
ByteReader byte_reader(params.endianness == kLittleEndian ? |
ENDIANNESS_LITTLE : ENDIANNESS_BIG); |
- CompilationUnit parser(MakeSectionMap(), 0, &byte_reader, &handler); |
- EXPECT_EQ(parser.Start(), info_contents.size()); |
+ CompilationUnit parser(MakeSectionMap(), offset, &byte_reader, &handler); |
+ EXPECT_EQ(offset + parser.Start(), info_contents.size()); |
} |
// The sequence to which the fixture's methods append expectations. |
Sequence s; |
}; |
struct DwarfForms: public DwarfFormsFixture, |
public TestWithParam<DwarfHeaderParams> { }; |
@@ -342,16 +346,121 @@ TEST_P(DwarfForms, block2) { |
Pointee('*'), 258)) |
.InSequence(s) |
.WillOnce(Return()); |
ExpectEndCompilationUnit(); |
ParseCompilationUnit(GetParam()); |
} |
+TEST_P(DwarfForms, flag_present) { |
+ StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x3e449ac2, |
+ (DwarfAttribute) 0x359d1972, |
+ dwarf2reader::DW_FORM_flag_present); |
+ // DW_FORM_flag_present occupies no space in the DIE. |
+ info.Finish(); |
+ |
+ ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x3e449ac2); |
+ EXPECT_CALL(handler, |
+ ProcessAttributeUnsigned(_, (DwarfAttribute) 0x359d1972, |
+ dwarf2reader::DW_FORM_flag_present, |
+ 1)) |
+ .InSequence(s) |
+ .WillOnce(Return()); |
+ ExpectEndCompilationUnit(); |
+ |
+ ParseCompilationUnit(GetParam()); |
+} |
+ |
+TEST_P(DwarfForms, sec_offset) { |
+ StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x1d971689, |
+ (DwarfAttribute) 0xa060bfd1, |
+ dwarf2reader::DW_FORM_sec_offset); |
+ u_int64_t value; |
+ if (GetParam().format_size == 4) { |
+ value = 0xacc9c388; |
+ info.D32(value); |
+ } else { |
+ value = 0xcffe5696ffe3ed0aULL; |
+ info.D64(value); |
+ } |
+ info.Finish(); |
+ |
+ ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x1d971689); |
+ EXPECT_CALL(handler, ProcessAttributeUnsigned(_, (DwarfAttribute) 0xa060bfd1, |
+ dwarf2reader::DW_FORM_sec_offset, |
+ value)) |
+ .InSequence(s) |
+ .WillOnce(Return()); |
+ ExpectEndCompilationUnit(); |
+ |
+ ParseCompilationUnit(GetParam()); |
+} |
+ |
+TEST_P(DwarfForms, exprloc) { |
+ StartSingleAttributeDIE(GetParam(), (DwarfTag) 0xb6d167bb, |
+ (DwarfAttribute) 0xba3ae5cb, |
+ dwarf2reader::DW_FORM_exprloc); |
+ info.ULEB128(29) |
+ .Append(29, 173); |
+ info.Finish(); |
+ |
+ ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0xb6d167bb); |
+ EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xba3ae5cb, |
+ dwarf2reader::DW_FORM_exprloc, |
+ Pointee(173), 29)) |
+ .InSequence(s) |
+ .WillOnce(Return()); |
+ ExpectEndCompilationUnit(); |
+ |
+ ParseCompilationUnit(GetParam()); |
+} |
+ |
+TEST_P(DwarfForms, ref_sig8) { |
+ StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b, |
+ (DwarfAttribute) 0xd708d908, |
+ dwarf2reader::DW_FORM_ref_sig8); |
+ info.D64(0xf72fa0cb6ddcf9d6ULL); |
+ info.Finish(); |
+ |
+ ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b); |
+ EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908, |
+ dwarf2reader::DW_FORM_ref_sig8, |
+ 0xf72fa0cb6ddcf9d6ULL)) |
+ .InSequence(s) |
+ .WillOnce(Return()); |
+ ExpectEndCompilationUnit(); |
+ |
+ ParseCompilationUnit(GetParam()); |
+} |
+ |
+// A value passed to ProcessAttributeSignature is just an absolute number, |
+// not an offset within the compilation unit as most of the other |
+// DW_FORM_ref forms are. Check that the reader doesn't try to apply any |
+// offset to the signature, by reading it from a compilation unit that does |
+// not start at the beginning of the section. |
+TEST_P(DwarfForms, ref_sig8_not_first) { |
+ info.Append(98, '*'); |
+ StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b, |
+ (DwarfAttribute) 0xd708d908, |
+ dwarf2reader::DW_FORM_ref_sig8); |
+ info.D64(0xf72fa0cb6ddcf9d6ULL); |
+ info.Finish(); |
+ |
+ ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b, 98); |
+ EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908, |
+ dwarf2reader::DW_FORM_ref_sig8, |
+ 0xf72fa0cb6ddcf9d6ULL)) |
+ .InSequence(s) |
+ .WillOnce(Return()); |
+ ExpectEndCompilationUnit(); |
+ |
+ ParseCompilationUnit(GetParam(), 98); |
+} |
+ |
// Tests for the other attribute forms could go here. |
INSTANTIATE_TEST_CASE_P( |
HeaderVariants, DwarfForms, |
::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4), |
DwarfHeaderParams(kLittleEndian, 4, 2, 8), |
DwarfHeaderParams(kLittleEndian, 4, 3, 4), |
DwarfHeaderParams(kLittleEndian, 4, 3, 8), |