@@ -188,12 +188,14 @@ uptr find_cfi_check_in_dso(dl_phdr_info *info) {
188
188
}
189
189
}
190
190
if (!dynamic) return 0 ;
191
- uptr strtab = 0 , symtab = 0 ;
191
+ uptr strtab = 0 , symtab = 0 , strsz = 0 ;
192
192
for (const ElfW (Dyn) *p = dynamic; p->d_tag != PT_NULL; ++p) {
193
193
if (p->d_tag == DT_SYMTAB)
194
194
symtab = p->d_un .d_ptr ;
195
195
else if (p->d_tag == DT_STRTAB)
196
196
strtab = p->d_un .d_ptr ;
197
+ else if (p->d_tag == DT_STRSZ)
198
+ strsz = p->d_un .d_ptr ;
197
199
}
198
200
199
201
if (symtab > strtab) {
@@ -209,7 +211,8 @@ uptr find_cfi_check_in_dso(dl_phdr_info *info) {
209
211
if (phdr->p_type == PT_LOAD) {
210
212
uptr beg = info->dlpi_addr + phdr->p_vaddr ;
211
213
uptr end = beg + phdr->p_memsz ;
212
- if (strtab >= beg && strtab < end && symtab >= beg && symtab < end)
214
+ if (strtab >= beg && strtab + strsz < end && symtab >= beg &&
215
+ symtab < end)
213
216
break ;
214
217
}
215
218
}
@@ -222,6 +225,10 @@ uptr find_cfi_check_in_dso(dl_phdr_info *info) {
222
225
223
226
for (const ElfW (Sym) *p = (const ElfW (Sym) *)symtab; (ElfW (Addr))p < strtab;
224
227
++p) {
228
+ // There is no reliable way to find the end of the symbol table. In
229
+ // lld-produces files, there are other sections between symtab and strtab.
230
+ // Stop looking when the symbol name is not inside strtab.
231
+ if (p->st_name >= strsz) break ;
225
232
char *name = (char *)(strtab + p->st_name );
226
233
if (strcmp (name, " __cfi_check" ) == 0 ) {
227
234
assert (p->st_info == ELF32_ST_INFO (STB_GLOBAL, STT_FUNC));
0 commit comments