mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-28 10:04:17 +01:00
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
This commit is contained in:
parent
3a8617eb8c
commit
6dc56cca44
@ -47,8 +47,8 @@ using namespace google_breakpad;
|
|||||||
using google_breakpad::ElfClass32;
|
using google_breakpad::ElfClass32;
|
||||||
using google_breakpad::ElfClass64;
|
using google_breakpad::ElfClass64;
|
||||||
using google_breakpad::SafeReadLink;
|
using google_breakpad::SafeReadLink;
|
||||||
using google_breakpad::synth_elf::BuildIDNote;
|
|
||||||
using google_breakpad::synth_elf::ELF;
|
using google_breakpad::synth_elf::ELF;
|
||||||
|
using google_breakpad::synth_elf::Notes;
|
||||||
using google_breakpad::test_assembler::kLittleEndian;
|
using google_breakpad::test_assembler::kLittleEndian;
|
||||||
using google_breakpad::test_assembler::Section;
|
using google_breakpad::test_assembler::Section;
|
||||||
using ::testing::Types;
|
using ::testing::Types;
|
||||||
@ -160,9 +160,10 @@ TYPED_TEST(FileIDTest, BuildID) {
|
|||||||
Section text(kLittleEndian);
|
Section text(kLittleEndian);
|
||||||
text.Append(4096, 0);
|
text.Append(4096, 0);
|
||||||
elf.AddSection(".text", text, SHT_PROGBITS);
|
elf.AddSection(".text", text, SHT_PROGBITS);
|
||||||
BuildIDNote::AppendSection(elf,
|
Notes notes(kLittleEndian);
|
||||||
kExpectedIdentifier,
|
notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifier,
|
||||||
sizeof(kExpectedIdentifier));
|
sizeof(kExpectedIdentifier));
|
||||||
|
elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
|
||||||
elf.Finish();
|
elf.Finish();
|
||||||
this->GetElfContents(elf);
|
this->GetElfContents(elf);
|
||||||
|
|
||||||
|
@ -243,30 +243,21 @@ void SymbolTable::AddSymbol(const string& name, uint64_t value,
|
|||||||
D64(size);
|
D64(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildIDNote::BuildIDNote(const uint8_t* id_bytes,
|
void Notes::AddNote(int type, const string &name, const uint8_t* desc_bytes,
|
||||||
size_t id_size,
|
size_t desc_size) {
|
||||||
Endianness endianness) : Section(endianness) {
|
|
||||||
const char kNoteName[] = "GNU";
|
|
||||||
// Elf32_Nhdr and Elf64_Nhdr are exactly the same.
|
// Elf32_Nhdr and Elf64_Nhdr are exactly the same.
|
||||||
Elf32_Nhdr note_header;
|
Elf32_Nhdr note_header;
|
||||||
memset(¬e_header, 0, sizeof(note_header));
|
memset(¬e_header, 0, sizeof(note_header));
|
||||||
note_header.n_namesz = sizeof(kNoteName);
|
note_header.n_namesz = name.length() + 1;
|
||||||
note_header.n_descsz = id_size;
|
note_header.n_descsz = desc_size;
|
||||||
note_header.n_type = NT_GNU_BUILD_ID;
|
note_header.n_type = type;
|
||||||
|
|
||||||
Append(reinterpret_cast<const uint8_t*>(¬e_header),
|
Append(reinterpret_cast<const uint8_t*>(¬e_header),
|
||||||
sizeof(note_header));
|
sizeof(note_header));
|
||||||
AppendCString(kNoteName);
|
AppendCString(name);
|
||||||
Append(id_bytes, id_size);
|
Align(4);
|
||||||
}
|
Append(desc_bytes, desc_size);
|
||||||
|
Align(4);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace synth_elf
|
} // namespace synth_elf
|
||||||
|
@ -177,13 +177,16 @@ class SymbolTable : public Section {
|
|||||||
StringTable& table_;
|
StringTable& table_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A class to build GNU Build ID note sections
|
// A class for note sections
|
||||||
class BuildIDNote : public Section {
|
class Notes : public Section {
|
||||||
public:
|
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|.
|
// Add a note.
|
||||||
static void AppendSection(ELF& elf, const uint8_t* id_bytes, size_t id_size);
|
void AddNote(int type, const string &name, const uint8_t* desc_bytes,
|
||||||
|
size_t desc_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace synth_elf
|
} // namespace synth_elf
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
using google_breakpad::ElfClass32;
|
using google_breakpad::ElfClass32;
|
||||||
using google_breakpad::ElfClass64;
|
using google_breakpad::ElfClass64;
|
||||||
using google_breakpad::synth_elf::ELF;
|
using google_breakpad::synth_elf::ELF;
|
||||||
|
using google_breakpad::synth_elf::Notes;
|
||||||
using google_breakpad::synth_elf::Section;
|
using google_breakpad::synth_elf::Section;
|
||||||
using google_breakpad::synth_elf::StringTable;
|
using google_breakpad::synth_elf::StringTable;
|
||||||
using google_breakpad::synth_elf::SymbolTable;
|
using google_breakpad::synth_elf::SymbolTable;
|
||||||
@ -369,4 +370,44 @@ TYPED_TEST(BasicElf, BasicLE) {
|
|||||||
EXPECT_EQ(0U, phdr->p_align);
|
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(¬es_contents));
|
||||||
|
EXPECT_EQ(0, memcmp(kExpectedNotesContents,
|
||||||
|
notes_contents.data(),
|
||||||
|
notes_contents.size()));
|
||||||
|
}
|
||||||
|
|
||||||
#endif // defined(__i386__) || defined(__x86_64__)
|
#endif // defined(__i386__) || defined(__x86_64__)
|
||||||
|
Loading…
Reference in New Issue
Block a user