diff options
Diffstat (limited to 'src/common/linux/dump_symbols_unittest.cc')
-rw-r--r-- | src/common/linux/dump_symbols_unittest.cc | 76 |
1 files changed, 54 insertions, 22 deletions
diff --git a/src/common/linux/dump_symbols_unittest.cc b/src/common/linux/dump_symbols_unittest.cc index 3f86dbe6..bb7b2007 100644 --- a/src/common/linux/dump_symbols_unittest.cc +++ b/src/common/linux/dump_symbols_unittest.cc @@ -40,6 +40,8 @@ #include <vector> #include "breakpad_googletest_includes.h" +#include "common/linux/elf_gnu_compat.h" +#include "common/linux/elfutils.h" #include "common/linux/dump_symbols.h" #include "common/linux/synth_elf.h" #include "common/module.h" @@ -54,6 +56,7 @@ bool ReadSymbolDataInternal(const uint8_t* obj_file, Module** module); using google_breakpad::synth_elf::ELF; +using google_breakpad::synth_elf::Notes; using google_breakpad::synth_elf::StringTable; using google_breakpad::synth_elf::SymbolTable; using google_breakpad::test_assembler::kLittleEndian; @@ -61,7 +64,9 @@ using google_breakpad::test_assembler::Section; using std::stringstream; using std::vector; using ::testing::Test; +using ::testing::Types; +template<typename ElfClass> class DumpSymbols : public Test { public: void GetElfContents(ELF& elf) { @@ -78,7 +83,11 @@ class DumpSymbols : public Test { uint8_t* elfdata; }; -TEST_F(DumpSymbols, Invalid) { +typedef Types<ElfClass32, ElfClass64> ElfClasses; + +TYPED_TEST_CASE(DumpSymbols, ElfClasses); + +TYPED_TEST(DumpSymbols, Invalid) { Elf32_Ehdr header; memset(&header, 0, sizeof(header)); Module* module; @@ -90,8 +99,8 @@ TEST_F(DumpSymbols, Invalid) { &module)); } -TEST_F(DumpSymbols, SimplePublic32) { - ELF elf(EM_386, ELFCLASS32, kLittleEndian); +TYPED_TEST(DumpSymbols, SimplePublic) { + ELF elf(TypeParam::kMachine, TypeParam::kClass, kLittleEndian); // Zero out text section for simplicity. Section text(kLittleEndian); text.Append(4096, 0); @@ -99,8 +108,11 @@ TEST_F(DumpSymbols, SimplePublic32) { // Add a public symbol. StringTable table(kLittleEndian); - SymbolTable syms(kLittleEndian, 4, table); - syms.AddSymbol("superfunc", (uint32_t)0x1000, (uint32_t)0x10, + SymbolTable syms(kLittleEndian, TypeParam::kAddrSize, table); + syms.AddSymbol("superfunc", + (typename TypeParam::Addr)0x1000, + (typename TypeParam::Addr)0x10, + // ELF32_ST_INFO works for 32-or 64-bit. ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), SHN_UNDEF + 1); int index = elf.AddSection(".dynstr", table, SHT_STRTAB); @@ -109,14 +121,14 @@ TEST_F(DumpSymbols, SimplePublic32) { SHF_ALLOC, // flags 0, // addr index, // link - sizeof(Elf32_Sym)); // entsize + sizeof(typename TypeParam::Sym)); // entsize elf.Finish(); - GetElfContents(elf); + this->GetElfContents(elf); Module* module; DumpOptions options(ALL_SYMBOL_DATA, true); - EXPECT_TRUE(ReadSymbolDataInternal(elfdata, + EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, "foo", vector<string>(), options, @@ -124,24 +136,40 @@ TEST_F(DumpSymbols, SimplePublic32) { stringstream s; module->Write(s, ALL_SYMBOL_DATA); - EXPECT_EQ("MODULE Linux x86 000000000000000000000000000000000 foo\n" - "PUBLIC 1000 0 superfunc\n", - s.str()); + const string expected = + string("MODULE Linux ") + TypeParam::kMachineName + + " 000000000000000000000000000000000 foo\n" + "INFO CODE_ID 00000000000000000000000000000000\n" + "PUBLIC 1000 0 superfunc\n"; + EXPECT_EQ(expected, s.str()); delete module; } -TEST_F(DumpSymbols, SimplePublic64) { - ELF elf(EM_X86_64, ELFCLASS64, kLittleEndian); +TYPED_TEST(DumpSymbols, SimpleBuildID) { + ELF elf(TypeParam::kMachine, TypeParam::kClass, kLittleEndian); // Zero out text section for simplicity. Section text(kLittleEndian); text.Append(4096, 0); elf.AddSection(".text", text, SHT_PROGBITS); + // Add a Build ID + const uint8_t kExpectedIdentifierBytes[] = + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13}; + Notes notes(kLittleEndian); + notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, + sizeof(kExpectedIdentifierBytes)); + elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE); + // Add a public symbol. StringTable table(kLittleEndian); - SymbolTable syms(kLittleEndian, 8, table); - syms.AddSymbol("superfunc", (uint64_t)0x1000, (uint64_t)0x10, - ELF64_ST_INFO(STB_GLOBAL, STT_FUNC), + SymbolTable syms(kLittleEndian, TypeParam::kAddrSize, table); + syms.AddSymbol("superfunc", + (typename TypeParam::Addr)0x1000, + (typename TypeParam::Addr)0x10, + // ELF32_ST_INFO works for 32-or 64-bit. + ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), SHN_UNDEF + 1); int index = elf.AddSection(".dynstr", table, SHT_STRTAB); elf.AddSection(".dynsym", syms, @@ -149,14 +177,14 @@ TEST_F(DumpSymbols, SimplePublic64) { SHF_ALLOC, // flags 0, // addr index, // link - sizeof(Elf64_Sym)); // entsize + sizeof(typename TypeParam::Sym)); // entsize elf.Finish(); - GetElfContents(elf); + this->GetElfContents(elf); Module* module; DumpOptions options(ALL_SYMBOL_DATA, true); - EXPECT_TRUE(ReadSymbolDataInternal(elfdata, + EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, "foo", vector<string>(), options, @@ -164,9 +192,13 @@ TEST_F(DumpSymbols, SimplePublic64) { stringstream s; module->Write(s, ALL_SYMBOL_DATA); - EXPECT_EQ("MODULE Linux x86_64 000000000000000000000000000000000 foo\n" - "PUBLIC 1000 0 superfunc\n", - s.str()); + const string expected = + string("MODULE Linux ") + TypeParam::kMachineName + + " 030201000504070608090A0B0C0D0E0F0 foo\n" + "INFO CODE_ID 000102030405060708090A0B0C0D0E0F10111213\n" + "PUBLIC 1000 0 superfunc\n"; + EXPECT_EQ(expected, s.str()); + delete module; } } // namespace google_breakpad |