forked from OSchip/llvm-project
[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
This commit is contained in:
parent
773ab3c665
commit
f261e258ec
|
@ -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 */
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue