diff options
author | Sim Sun <simsun@fb.com> | 2024-04-17 16:52:25 -0700 |
---|---|---|
committer | Joshua Peraza <jperaza@chromium.org> | 2024-04-18 16:19:18 +0000 |
commit | a8a43bad6fdb2d63b623862bea8f6bc959d8edc9 (patch) | |
tree | 671324d486fa0de9d36e29ba30ea4f16100659aa | |
parent | e5dc1f86b2defc8f76b56fb473b804e42e75c41d (diff) | |
download | google-breakpad-a8a43bad6fdb2d63b623862bea8f6bc959d8edc9.tar.gz |
Prefer to use .note.gnu.build-id section as ElfBuildId
Summary:
Android prefers `.note.gnu-build-id`[0] as BuildId than anyother PT_NOTE
phdrs. This CL tries to read ElfBuildId from `.note.gnu.build-id` first
to fix the BuildId mismatch issue between Android tombstone report and
breakpad symbol file.
e.g
```
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .note.androi[...] NOTE 0000000000000270 00000270
0000000000000018 0000000000000000 A 0 0 4
[ 2] .note.hwasan[...] NOTE 0000000000000288 00000288
000000000000001c 0000000000000000 A 0 0 4
[ 3] .note.gnu.bu[...] NOTE 00000000000002a4 000002a4
0000000000000020 0000000000000000 A 0 0 4
$ readelf -x .note.hwasan.globals
Hex dump of section '.note.hwasan.globals':
0x00000288 08000000 08000000 03000000 4c4c564d ............LLVM
0x00000298 00000000 98890100 409d0100 ........@...
$ readelf -x .note.gnu.build-id
Hex dump of section '.note.gnu.build-id':
0x000002a4 04000000 10000000 03000000 474e5500 ............GNU.
0x000002b4 a4eb3625 c1db6452 1e881973 bfdff9bd ..6%..dR...s....
```
The BuildId in tombstone:
```
libartbase.so (BuildId: c7e463b51b0898d442269a421353bdbd)
```
But the breakpad dump_syms got:
```
MODULE Linux arm64 000189989D40000100000000000000000 libartbase.so
INFO CODE_ID 98890100409D0100
`````
[0]
https://cs.android.com/android/platform/superproject/main/+/main:system/unwinding/libunwindstack/ElfInterface.cpp;l=423-427;drc=3d19fbcc09b1b44928639b06cd0b88f735cd988d
Change-Id: I01e3514e0e2a1ea163c03093055284448ed4e89c
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5463566
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
-rw-r--r-- | src/common/linux/file_id.cc | 14 | ||||
-rw-r--r-- | src/common/linux/file_id_unittest.cc | 39 |
2 files changed, 46 insertions, 7 deletions
diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index d8fcbd8d..29653160 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -99,6 +99,13 @@ static bool ElfClassBuildIDNoteIdentifier(const void* section, size_t length, // and copy it into |identifier|. static bool FindElfBuildIDNote(const void* elf_mapped_base, wasteful_vector<uint8_t>& identifier) { + void* note_section; + size_t note_size; + if (FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, + (const void**)¬e_section, ¬e_size)) { + return ElfClassBuildIDNoteIdentifier(note_section, note_size, identifier); + } + PageAllocator allocator; // lld normally creates 2 PT_NOTEs, gold normally creates 1. auto_wasteful_vector<ElfSegment, 2> segs(&allocator); @@ -110,13 +117,6 @@ static bool FindElfBuildIDNote(const void* elf_mapped_base, } } - void* note_section; - size_t note_size; - if (FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, - (const void**)¬e_section, ¬e_size)) { - return ElfClassBuildIDNoteIdentifier(note_section, note_size, identifier); - } - return false; } diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc index 0ef45353..7be239f6 100644 --- a/src/common/linux/file_id_unittest.cc +++ b/src/common/linux/file_id_unittest.cc @@ -326,6 +326,45 @@ TYPED_TEST(FileIDTest, BuildIDMultiplePH) { EXPECT_EQ(expected_identifier_string, identifier_string); } +TYPED_TEST(FileIDTest, BuildIDMultiplePHPreferGNU) { + const uint8_t kExpectedIdentifierBytes[] = + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13}; + const string expected_identifier_string = + this->get_file_id(kExpectedIdentifierBytes); + + ELF elf(EM_386, TypeParam::kClass, kLittleEndian); + Section text(kLittleEndian); + text.Append(4096, 0); + elf.AddSection(".text", text, SHT_PROGBITS); + Notes notes1(kLittleEndian); + notes1.AddNote(0, "Linux", + reinterpret_cast<const uint8_t*>("\0x42\0x02\0\0"), 4); + Notes notes2(kLittleEndian); + notes2.AddNote(NT_GNU_BUILD_ID, "GNU", + reinterpret_cast<const uint8_t*>("\0x42\0x02\0\0"), 4); + Notes notes3(kLittleEndian); + notes3.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, + sizeof(kExpectedIdentifierBytes)); + int note1_idx = elf.AddSection(".note1", notes1, SHT_NOTE); + int note2_idx = elf.AddSection(".note2", notes2, SHT_NOTE); + int note3_idx = elf.AddSection(".note.gnu.build-id", notes3, SHT_NOTE); + elf.AddSegment(note1_idx, note1_idx, PT_NOTE); + elf.AddSegment(note2_idx, note2_idx, PT_NOTE); + elf.AddSegment(note3_idx, note3_idx, PT_NOTE); + elf.Finish(); + this->GetElfContents(elf); + + id_vector identifier(this->make_vector()); + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, + identifier)); + EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); + + string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); + EXPECT_EQ(expected_identifier_string, identifier_string); +} + // Test to make sure two files with different text sections produce // different hashes when not using a build id. TYPED_TEST(FileIDTest, UniqueHashes) { |