aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSim Sun <simsun@fb.com>2024-04-17 16:52:25 -0700
committerJoshua Peraza <jperaza@chromium.org>2024-04-18 16:19:18 +0000
commita8a43bad6fdb2d63b623862bea8f6bc959d8edc9 (patch)
tree671324d486fa0de9d36e29ba30ea4f16100659aa
parente5dc1f86b2defc8f76b56fb473b804e42e75c41d (diff)
downloadgoogle-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.cc14
-rw-r--r--src/common/linux/file_id_unittest.cc39
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**)&note_section, &note_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**)&note_section, &note_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) {