[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