Skip to content

Commit f261e25

Browse files
committed
[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 #52695 Differential Revision: https://reviews.llvm.org/D115830
1 parent 773ab3c commit f261e25

File tree

1 file changed

+37
-14
lines changed

1 file changed

+37
-14
lines changed

compiler-rt/lib/profile/InstrProfilingPlatformLinux.c

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,9 @@ static int WriteOneBinaryId(ProfDataWriter *Writer, uint64_t BinaryIdLen,
125125
static int WriteBinaryIdForNote(ProfDataWriter *Writer,
126126
const ElfW(Nhdr) * Note) {
127127
int BinaryIdSize = 0;
128-
129128
const char *NoteName = (const char *)Note + sizeof(ElfW(Nhdr));
130129
if (Note->n_type == NT_GNU_BUILD_ID && Note->n_namesz == 4 &&
131130
memcmp(NoteName, "GNU\0", 4) == 0) {
132-
133131
uint64_t BinaryIdLen = Note->n_descsz;
134132
const uint8_t *BinaryIdData =
135133
(const uint8_t *)(NoteName + RoundUp(Note->n_namesz, 4));
@@ -151,20 +149,20 @@ static int WriteBinaryIdForNote(ProfDataWriter *Writer,
151149
*/
152150
static int WriteBinaryIds(ProfDataWriter *Writer, const ElfW(Nhdr) * Note,
153151
const ElfW(Nhdr) * NotesEnd) {
154-
int TotalBinaryIdsSize = 0;
152+
int BinaryIdsSize = 0;
155153
while (Note < NotesEnd) {
156-
int Result = WriteBinaryIdForNote(Writer, Note);
157-
if (Result == -1)
154+
int OneBinaryIdSize = WriteBinaryIdForNote(Writer, Note);
155+
if (OneBinaryIdSize == -1)
158156
return -1;
159-
TotalBinaryIdsSize += Result;
157+
BinaryIdsSize += OneBinaryIdSize;
160158

161159
/* Calculate the offset of the next note in notes section. */
162160
size_t NoteOffset = sizeof(ElfW(Nhdr)) + RoundUp(Note->n_namesz, 4) +
163161
RoundUp(Note->n_descsz, 4);
164162
Note = (const ElfW(Nhdr) *)((const char *)(Note) + NoteOffset);
165163
}
166164

167-
return TotalBinaryIdsSize;
165+
return BinaryIdsSize;
168166
}
169167

170168
/*
@@ -178,21 +176,46 @@ COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) {
178176
const ElfW(Phdr) *ProgramHeader =
179177
(const ElfW(Phdr) *)((uintptr_t)ElfHeader + ElfHeader->e_phoff);
180178

179+
int TotalBinaryIdsSize = 0;
181180
uint32_t I;
182181
/* Iterate through entries in the program header. */
183182
for (I = 0; I < ElfHeader->e_phnum; I++) {
184-
/* Look for the notes section in program header entries. */
183+
/* Look for the notes segment in program header entries. */
185184
if (ProgramHeader[I].p_type != PT_NOTE)
186185
continue;
187186

188-
const ElfW(Nhdr) *Note =
189-
(const ElfW(Nhdr) *)((uintptr_t)ElfHeader + ProgramHeader[I].p_offset);
190-
const ElfW(Nhdr) *NotesEnd =
191-
(const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_filesz);
192-
return WriteBinaryIds(Writer, Note, NotesEnd);
187+
/* There can be multiple notes segment, and examine each of them. */
188+
const ElfW(Nhdr) * Note;
189+
const ElfW(Nhdr) * NotesEnd;
190+
/*
191+
* When examining notes in file, use p_offset, which is the offset within
192+
* the elf file, to find the start of notes.
193+
*/
194+
if (ProgramHeader[I].p_memsz == 0 ||
195+
ProgramHeader[I].p_memsz == ProgramHeader[I].p_filesz) {
196+
Note = (const ElfW(Nhdr) *)((uintptr_t)ElfHeader +
197+
ProgramHeader[I].p_offset);
198+
NotesEnd = (const ElfW(Nhdr) *)((const char *)(Note) +
199+
ProgramHeader[I].p_filesz);
200+
} else {
201+
/*
202+
* When examining notes in memory, use p_vaddr, which is the address of
203+
* section after loaded to memory, to find the start of notes.
204+
*/
205+
Note =
206+
(const ElfW(Nhdr) *)((uintptr_t)ElfHeader + ProgramHeader[I].p_vaddr);
207+
NotesEnd =
208+
(const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_memsz);
209+
}
210+
211+
int BinaryIdsSize = WriteBinaryIds(Writer, Note, NotesEnd);
212+
if (TotalBinaryIdsSize == -1)
213+
return -1;
214+
215+
TotalBinaryIdsSize += BinaryIdsSize;
193216
}
194217

195-
return 0;
218+
return TotalBinaryIdsSize;
196219
}
197220
#else /* !NT_GNU_BUILD_ID */
198221
/*

0 commit comments

Comments
 (0)