| Index: src/common/linux/dump_symbols_unittest.cc
|
| diff --git a/src/common/linux/dump_symbols_unittest.cc b/src/common/linux/dump_symbols_unittest.cc
|
| index 3f86dbe6a34787693bacda4939ffc5ef5a98b920..bb7b20076e6d6d7b8863a3e719fbfc0d702bc12e 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
|
|
|