aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-04-04 16:24:44 +0000
committerted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-04-04 16:24:44 +0000
commit6dc56cca4401eacf1efbb0bdaf71ca85863c7ca0 (patch)
treeb08f5180248b6f2ab6752d81e33085d568c8846c /src
parentRefactor BasicElf synth_elf unitest (diff)
downloadbreakpad-6dc56cca4401eacf1efbb0bdaf71ca85863c7ca0.tar.xz
Support generic Elf notes, with unit tests
A=Mike Hommey <mh@glandium.org> R=ted at https://breakpad.appspot.com/546002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1142 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src')
-rw-r--r--src/common/linux/file_id_unittest.cc9
-rw-r--r--src/common/linux/synth_elf.cc27
-rw-r--r--src/common/linux/synth_elf.h13
-rw-r--r--src/common/linux/synth_elf_unittest.cc41
4 files changed, 63 insertions, 27 deletions
diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc
index 7c6550b1..e2e13747 100644
--- a/src/common/linux/file_id_unittest.cc
+++ b/src/common/linux/file_id_unittest.cc
@@ -47,8 +47,8 @@ using namespace google_breakpad;
using google_breakpad::ElfClass32;
using google_breakpad::ElfClass64;
using google_breakpad::SafeReadLink;
-using google_breakpad::synth_elf::BuildIDNote;
using google_breakpad::synth_elf::ELF;
+using google_breakpad::synth_elf::Notes;
using google_breakpad::test_assembler::kLittleEndian;
using google_breakpad::test_assembler::Section;
using ::testing::Types;
@@ -160,9 +160,10 @@ TYPED_TEST(FileIDTest, BuildID) {
Section text(kLittleEndian);
text.Append(4096, 0);
elf.AddSection(".text", text, SHT_PROGBITS);
- BuildIDNote::AppendSection(elf,
- kExpectedIdentifier,
- sizeof(kExpectedIdentifier));
+ Notes notes(kLittleEndian);
+ notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifier,
+ sizeof(kExpectedIdentifier));
+ elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
elf.Finish();
this->GetElfContents(elf);
diff --git a/src/common/linux/synth_elf.cc b/src/common/linux/synth_elf.cc
index 1a741e55..9cd03ef8 100644
--- a/src/common/linux/synth_elf.cc
+++ b/src/common/linux/synth_elf.cc
@@ -243,30 +243,21 @@ void SymbolTable::AddSymbol(const string& name, uint64_t value,
D64(size);
}
-BuildIDNote::BuildIDNote(const uint8_t* id_bytes,
- size_t id_size,
- Endianness endianness) : Section(endianness) {
- const char kNoteName[] = "GNU";
+void Notes::AddNote(int type, const string &name, const uint8_t* desc_bytes,
+ size_t desc_size) {
// Elf32_Nhdr and Elf64_Nhdr are exactly the same.
Elf32_Nhdr note_header;
memset(&note_header, 0, sizeof(note_header));
- note_header.n_namesz = sizeof(kNoteName);
- note_header.n_descsz = id_size;
- note_header.n_type = NT_GNU_BUILD_ID;
+ note_header.n_namesz = name.length() + 1;
+ note_header.n_descsz = desc_size;
+ note_header.n_type = type;
Append(reinterpret_cast<const uint8_t*>(&note_header),
sizeof(note_header));
- AppendCString(kNoteName);
- Append(id_bytes, id_size);
-}
-
-// static
-void BuildIDNote::AppendSection(ELF& elf,
- const uint8_t* id_bytes,
- size_t id_size) {
- const char kBuildIDSectionName[] = ".note.gnu.build-id";
- BuildIDNote note(id_bytes, id_size, elf.endianness());
- elf.AddSection(kBuildIDSectionName, note, SHT_NOTE);
+ AppendCString(name);
+ Align(4);
+ Append(desc_bytes, desc_size);
+ Align(4);
}
} // namespace synth_elf
diff --git a/src/common/linux/synth_elf.h b/src/common/linux/synth_elf.h
index 9a6c0316..330ceae8 100644
--- a/src/common/linux/synth_elf.h
+++ b/src/common/linux/synth_elf.h
@@ -177,13 +177,16 @@ class SymbolTable : public Section {
StringTable& table_;
};
-// A class to build GNU Build ID note sections
-class BuildIDNote : public Section {
+// A class for note sections
+class Notes : public Section {
public:
- BuildIDNote(const uint8_t* id_bytes, size_t id_size, Endianness endianness);
+ Notes(Endianness endianness)
+ : Section(endianness) {
+ }
- // Append a new Build ID note section to |elf|.
- static void AppendSection(ELF& elf, const uint8_t* id_bytes, size_t id_size);
+ // Add a note.
+ void AddNote(int type, const string &name, const uint8_t* desc_bytes,
+ size_t desc_size);
};
} // namespace synth_elf
diff --git a/src/common/linux/synth_elf_unittest.cc b/src/common/linux/synth_elf_unittest.cc
index 94ff5052..3715b6e6 100644
--- a/src/common/linux/synth_elf_unittest.cc
+++ b/src/common/linux/synth_elf_unittest.cc
@@ -42,6 +42,7 @@
using google_breakpad::ElfClass32;
using google_breakpad::ElfClass64;
using google_breakpad::synth_elf::ELF;
+using google_breakpad::synth_elf::Notes;
using google_breakpad::synth_elf::Section;
using google_breakpad::synth_elf::StringTable;
using google_breakpad::synth_elf::SymbolTable;
@@ -369,4 +370,44 @@ TYPED_TEST(BasicElf, BasicLE) {
EXPECT_EQ(0U, phdr->p_align);
}
+class ElfNotesTest : public Test {};
+
+TEST_F(ElfNotesTest, Empty) {
+ Notes notes(kLittleEndian);
+ string contents;
+ ASSERT_TRUE(notes.GetContents(&contents));
+ EXPECT_EQ(0U, contents.size());
+}
+
+TEST_F(ElfNotesTest, Notes) {
+ Notes notes(kLittleEndian);
+ notes.AddNote(1, "Linux", reinterpret_cast<const uint8_t *>("\x42\x02\0\0"),
+ 4);
+ notes.AddNote(2, "a", reinterpret_cast<const uint8_t *>("foobar"),
+ sizeof("foobar") - 1);
+
+ const uint8_t kExpectedNotesContents[] = {
+ // Note 1
+ 0x06, 0x00, 0x00, 0x00, // name size, including terminating zero
+ 0x04, 0x00, 0x00, 0x00, // desc size
+ 0x01, 0x00, 0x00, 0x00, // type
+ 'L', 'i', 'n', 'u', 'x', 0x00, 0x00, 0x00, // padded "Linux"
+ 0x42, 0x02, 0x00, 0x00, // desc
+ // Note 2
+ 0x02, 0x00, 0x00, 0x00, // name size
+ 0x06, 0x00, 0x00, 0x00, // desc size
+ 0x02, 0x00, 0x00, 0x00, // type
+ 'a', 0x00, 0x00, 0x00, // padded "a"
+ 'f', 'o', 'o', 'b', 'a', 'r', 0x00, 0x00, // padded "foobar"
+ };
+ const size_t kExpectedNotesSize = sizeof(kExpectedNotesContents);
+ EXPECT_EQ(kExpectedNotesSize, notes.Size());
+
+ string notes_contents;
+ ASSERT_TRUE(notes.GetContents(&notes_contents));
+ EXPECT_EQ(0, memcmp(kExpectedNotesContents,
+ notes_contents.data(),
+ notes_contents.size()));
+}
+
#endif // defined(__i386__) || defined(__x86_64__)