| 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 | 
|  |