[compiler-rt] f261e25 - [profile] Fix writing binary id into profiles
Gulfem Savrun Yeniceri via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 27 11:42:33 PST 2021
Author: Gulfem Savrun Yeniceri
Date: 2021-12-27T19:20:19Z
New Revision: f261e258ecc0fc5b8e8a70dbe45752d1bb3c2d69
URL: https://github.com/llvm/llvm-project/commit/f261e258ecc0fc5b8e8a70dbe45752d1bb3c2d69
DIFF: https://github.com/llvm/llvm-project/commit/f261e258ecc0fc5b8e8a70dbe45752d1bb3c2d69.diff
LOG: [profile] Fix writing binary id into profiles
This patch adds support to read all the PT_NOTE segments in the
executable to find the binary ids. Previously, it was only reading
the first PT_NOTE segment, and this was missing the cases where
binary id is in the following segments. As a result, binary-id.c
and binary-id-padding.c test were failing in the following cases:
1) sanitizer-x86_64-linux bot
https://lab.llvm.org/staging/#/builders/97
2) OpenSuse Tumbleweed
https://github.com/llvm/llvm-project/issues/52695
Differential Revision: https://reviews.llvm.org/D115830
Added:
Modified:
compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
Removed:
################################################################################
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
index e61f90b2cef96..ac2ab4a6a8f53 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
@@ -125,11 +125,9 @@ static int WriteOneBinaryId(ProfDataWriter *Writer, uint64_t BinaryIdLen,
static int WriteBinaryIdForNote(ProfDataWriter *Writer,
const ElfW(Nhdr) * Note) {
int BinaryIdSize = 0;
-
const char *NoteName = (const char *)Note + sizeof(ElfW(Nhdr));
if (Note->n_type == NT_GNU_BUILD_ID && Note->n_namesz == 4 &&
memcmp(NoteName, "GNU\0", 4) == 0) {
-
uint64_t BinaryIdLen = Note->n_descsz;
const uint8_t *BinaryIdData =
(const uint8_t *)(NoteName + RoundUp(Note->n_namesz, 4));
@@ -151,12 +149,12 @@ static int WriteBinaryIdForNote(ProfDataWriter *Writer,
*/
static int WriteBinaryIds(ProfDataWriter *Writer, const ElfW(Nhdr) * Note,
const ElfW(Nhdr) * NotesEnd) {
- int TotalBinaryIdsSize = 0;
+ int BinaryIdsSize = 0;
while (Note < NotesEnd) {
- int Result = WriteBinaryIdForNote(Writer, Note);
- if (Result == -1)
+ int OneBinaryIdSize = WriteBinaryIdForNote(Writer, Note);
+ if (OneBinaryIdSize == -1)
return -1;
- TotalBinaryIdsSize += Result;
+ BinaryIdsSize += OneBinaryIdSize;
/* Calculate the offset of the next note in notes section. */
size_t NoteOffset = sizeof(ElfW(Nhdr)) + RoundUp(Note->n_namesz, 4) +
@@ -164,7 +162,7 @@ static int WriteBinaryIds(ProfDataWriter *Writer, const ElfW(Nhdr) * Note,
Note = (const ElfW(Nhdr) *)((const char *)(Note) + NoteOffset);
}
- return TotalBinaryIdsSize;
+ return BinaryIdsSize;
}
/*
@@ -178,21 +176,46 @@ COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) {
const ElfW(Phdr) *ProgramHeader =
(const ElfW(Phdr) *)((uintptr_t)ElfHeader + ElfHeader->e_phoff);
+ int TotalBinaryIdsSize = 0;
uint32_t I;
/* Iterate through entries in the program header. */
for (I = 0; I < ElfHeader->e_phnum; I++) {
- /* Look for the notes section in program header entries. */
+ /* Look for the notes segment in program header entries. */
if (ProgramHeader[I].p_type != PT_NOTE)
continue;
- const ElfW(Nhdr) *Note =
- (const ElfW(Nhdr) *)((uintptr_t)ElfHeader + ProgramHeader[I].p_offset);
- const ElfW(Nhdr) *NotesEnd =
- (const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_filesz);
- return WriteBinaryIds(Writer, Note, NotesEnd);
+ /* There can be multiple notes segment, and examine each of them. */
+ const ElfW(Nhdr) * Note;
+ const ElfW(Nhdr) * NotesEnd;
+ /*
+ * When examining notes in file, use p_offset, which is the offset within
+ * the elf file, to find the start of notes.
+ */
+ if (ProgramHeader[I].p_memsz == 0 ||
+ ProgramHeader[I].p_memsz == ProgramHeader[I].p_filesz) {
+ Note = (const ElfW(Nhdr) *)((uintptr_t)ElfHeader +
+ ProgramHeader[I].p_offset);
+ NotesEnd = (const ElfW(Nhdr) *)((const char *)(Note) +
+ ProgramHeader[I].p_filesz);
+ } else {
+ /*
+ * When examining notes in memory, use p_vaddr, which is the address of
+ * section after loaded to memory, to find the start of notes.
+ */
+ Note =
+ (const ElfW(Nhdr) *)((uintptr_t)ElfHeader + ProgramHeader[I].p_vaddr);
+ NotesEnd =
+ (const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_memsz);
+ }
+
+ int BinaryIdsSize = WriteBinaryIds(Writer, Note, NotesEnd);
+ if (TotalBinaryIdsSize == -1)
+ return -1;
+
+ TotalBinaryIdsSize += BinaryIdsSize;
}
- return 0;
+ return TotalBinaryIdsSize;
}
#else /* !NT_GNU_BUILD_ID */
/*
More information about the llvm-commits
mailing list