From 8ade75f9558e31d25aec862a552fe78f9ba98c82 Mon Sep 17 00:00:00 2001 From: "ted.mielczarek" Date: Tue, 30 Aug 2011 15:21:07 +0000 Subject: issue 243 - Linux dumper should use build id produced by ld --build-id if available R=thestig at http://breakpad.appspot.com/185001 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@830 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/common/linux/file_id_unittest.cc | 150 ++++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 55 deletions(-) (limited to 'src/common/linux/file_id_unittest.cc') diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc index f5298b12..24208983 100644 --- a/src/common/linux/file_id_unittest.cc +++ b/src/common/linux/file_id_unittest.cc @@ -33,18 +33,20 @@ #include #include "common/linux/file_id.h" +#include "common/linux/synth_elf.h" +#include "common/test_assembler.h" #include "breakpad_googletest_includes.h" using namespace google_breakpad; - -namespace { -typedef testing::Test FileIDTest; -} - -TEST(FileIDTest, FileIDStrip) { - // Calculate the File ID of our binary using - // FileID::ElfFileIdentifier, then make a copy of our binary, - // strip it, and ensure that we still get the same result. +using google_breakpad::synth_elf::BuildIDNote; +using google_breakpad::synth_elf::ELF; +using google_breakpad::test_assembler::kLittleEndian; +using google_breakpad::test_assembler::Section; + +TEST(FileIDStripTest, StripSelf) { + // Calculate the File ID of this binary using + // FileID::ElfFileIdentifier, then make a copy of this binary, + // strip it, and ensure that the result is the same. char exe_name[PATH_MAX]; ssize_t len = readlink("/proc/self/exe", exe_name, PATH_MAX - 1); ASSERT_NE(len, -1); @@ -75,58 +77,40 @@ TEST(FileIDTest, FileIDStrip) { unlink(templ); } -struct ElfClass32 { - typedef Elf32_Ehdr Ehdr; - typedef Elf32_Shdr Shdr; - static const int kClass = ELFCLASS32; -}; +class FileIDTest : public testing::Test { +public: + void GetElfContents(ELF& elf) { + string contents; + ASSERT_TRUE(elf.GetContents(&contents)); + ASSERT_LT(0, contents.size()); -struct ElfClass64 { - typedef Elf64_Ehdr Ehdr; - typedef Elf64_Shdr Shdr; - static const int kClass = ELFCLASS64; -}; - -template -struct ElfishElf { - static const size_t kTextSectionSize = 128; - typedef typename ElfClass::Ehdr Ehdr; - typedef typename ElfClass::Shdr Shdr; - - Ehdr elf_header; - Shdr text_header; - Shdr string_header; - char text_section[kTextSectionSize]; - char string_section[8]; - - static void Populate(ElfishElf* elf) { - memset(elf, 0, sizeof(ElfishElf)); - memcpy(elf, ELFMAG, SELFMAG); - elf->elf_header.e_ident[EI_CLASS] = ElfClass::kClass; - elf->elf_header.e_shoff = offsetof(ElfishElf, text_header); - elf->elf_header.e_shnum = 2; - elf->elf_header.e_shstrndx = 1; - elf->text_header.sh_name = 0; - elf->text_header.sh_type = SHT_PROGBITS; - elf->text_header.sh_offset = offsetof(ElfishElf, text_section); - elf->text_header.sh_size = kTextSectionSize; - for (size_t i = 0; i < kTextSectionSize; ++i) { - elf->text_section[i] = i * 3; - } - elf->string_header.sh_offset = offsetof(ElfishElf, string_section); - strcpy(elf->string_section, ".text"); + elfdata_v.clear(); + elfdata_v.insert(elfdata_v.begin(), contents.begin(), contents.end()); + elfdata = &elfdata_v[0]; } + + vector elfdata_v; + uint8_t* elfdata; }; -TEST(FileIDTest, ElfClass) { +TEST_F(FileIDTest, ElfClass) { uint8_t identifier[sizeof(MDGUID)]; const char expected_identifier_string[] = "80808080-8080-0000-0000-008080808080"; char identifier_string[sizeof(expected_identifier_string)]; + const size_t kTextSectionSize = 128; + + ELF elf32(EM_386, ELFCLASS32, kLittleEndian); + Section text32(kLittleEndian); + for (size_t i = 0; i < kTextSectionSize; ++i) { + text32.D8(i * 3); + } + elf32.AddSection(".text", text32, SHT_PROGBITS); + elf32.Finish(); + GetElfContents(elf32); + + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier)); - ElfishElf elf32; - ElfishElf::Populate(&elf32); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(&elf32, identifier)); FileID::ConvertIdentifierToString(identifier, identifier_string, sizeof(identifier_string)); EXPECT_STREQ(expected_identifier_string, identifier_string); @@ -134,9 +118,65 @@ TEST(FileIDTest, ElfClass) { memset(identifier, 0, sizeof(identifier)); memset(identifier_string, 0, sizeof(identifier_string)); - ElfishElf elf64; - ElfishElf::Populate(&elf64); - EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(&elf64, identifier)); + ELF elf64(EM_X86_64, ELFCLASS64, kLittleEndian); + Section text64(kLittleEndian); + for (size_t i = 0; i < kTextSectionSize; ++i) { + text64.D8(i * 3); + } + elf64.AddSection(".text", text64, SHT_PROGBITS); + elf64.Finish(); + GetElfContents(elf64); + + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier)); + + FileID::ConvertIdentifierToString(identifier, identifier_string, + sizeof(identifier_string)); + EXPECT_STREQ(expected_identifier_string, identifier_string); +} + +TEST_F(FileIDTest, BuildID) { + const uint8_t kExpectedIdentifier[sizeof(MDGUID)] = + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; + char expected_identifier_string[] = + "00000000-0000-0000-0000-000000000000"; + FileID::ConvertIdentifierToString(kExpectedIdentifier, + expected_identifier_string, + sizeof(expected_identifier_string)); + + uint8_t identifier[sizeof(MDGUID)]; + char identifier_string[sizeof(expected_identifier_string)]; + + ELF elf32(EM_386, ELFCLASS32, kLittleEndian); + Section text(kLittleEndian); + text.Append(4096, 0); + elf32.AddSection(".text", text, SHT_PROGBITS); + BuildIDNote::AppendSection(elf32, + kExpectedIdentifier, + sizeof(kExpectedIdentifier)); + elf32.Finish(); + GetElfContents(elf32); + + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier)); + + FileID::ConvertIdentifierToString(identifier, identifier_string, + sizeof(identifier_string)); + EXPECT_STREQ(expected_identifier_string, identifier_string); + + memset(identifier, 0, sizeof(identifier)); + memset(identifier_string, 0, sizeof(identifier_string)); + + ELF elf64(EM_X86_64, ELFCLASS64, kLittleEndian); + // Re-use empty text section from previous test + elf64.AddSection(".text", text, SHT_PROGBITS); + BuildIDNote::AppendSection(elf64, + kExpectedIdentifier, + sizeof(kExpectedIdentifier)); + elf64.Finish(); + GetElfContents(elf64); + + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(elfdata, identifier)); + FileID::ConvertIdentifierToString(identifier, identifier_string, sizeof(identifier_string)); EXPECT_STREQ(expected_identifier_string, identifier_string); -- cgit v1.2.1