@@ -125,11 +125,9 @@ static int WriteOneBinaryId(ProfDataWriter *Writer, uint64_t BinaryIdLen,
125
125
static int WriteBinaryIdForNote (ProfDataWriter * Writer ,
126
126
const ElfW (Nhdr ) * Note ) {
127
127
int BinaryIdSize = 0 ;
128
-
129
128
const char * NoteName = (const char * )Note + sizeof (ElfW (Nhdr ));
130
129
if (Note -> n_type == NT_GNU_BUILD_ID && Note -> n_namesz == 4 &&
131
130
memcmp (NoteName , "GNU\0" , 4 ) == 0 ) {
132
-
133
131
uint64_t BinaryIdLen = Note -> n_descsz ;
134
132
const uint8_t * BinaryIdData =
135
133
(const uint8_t * )(NoteName + RoundUp (Note -> n_namesz , 4 ));
@@ -151,20 +149,20 @@ static int WriteBinaryIdForNote(ProfDataWriter *Writer,
151
149
*/
152
150
static int WriteBinaryIds (ProfDataWriter * Writer , const ElfW (Nhdr ) * Note ,
153
151
const ElfW (Nhdr ) * NotesEnd ) {
154
- int TotalBinaryIdsSize = 0 ;
152
+ int BinaryIdsSize = 0 ;
155
153
while (Note < NotesEnd ) {
156
- int Result = WriteBinaryIdForNote (Writer , Note );
157
- if (Result == -1 )
154
+ int OneBinaryIdSize = WriteBinaryIdForNote (Writer , Note );
155
+ if (OneBinaryIdSize == -1 )
158
156
return -1 ;
159
- TotalBinaryIdsSize += Result ;
157
+ BinaryIdsSize += OneBinaryIdSize ;
160
158
161
159
/* Calculate the offset of the next note in notes section. */
162
160
size_t NoteOffset = sizeof (ElfW (Nhdr )) + RoundUp (Note -> n_namesz , 4 ) +
163
161
RoundUp (Note -> n_descsz , 4 );
164
162
Note = (const ElfW (Nhdr ) * )((const char * )(Note ) + NoteOffset );
165
163
}
166
164
167
- return TotalBinaryIdsSize ;
165
+ return BinaryIdsSize ;
168
166
}
169
167
170
168
/*
@@ -178,21 +176,46 @@ COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) {
178
176
const ElfW (Phdr ) * ProgramHeader =
179
177
(const ElfW (Phdr ) * )((uintptr_t )ElfHeader + ElfHeader -> e_phoff );
180
178
179
+ int TotalBinaryIdsSize = 0 ;
181
180
uint32_t I ;
182
181
/* Iterate through entries in the program header. */
183
182
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. */
185
184
if (ProgramHeader [I ].p_type != PT_NOTE )
186
185
continue ;
187
186
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 ;
193
216
}
194
217
195
- return 0 ;
218
+ return TotalBinaryIdsSize ;
196
219
}
197
220
#else /* !NT_GNU_BUILD_ID */
198
221
/*
0 commit comments