Skip to content

Commit 6f16ab0

Browse files
committed
libdrgn: only apply ELF relocations to relocatable files
Relocations are only supposed to be applied to ET_REL files, not ET_EXEC files like vmlinux. This hasn't been an issue with the kernel builds that I've tested on because the relocations match the contents of the section. However, on Fedora, the relocation sections don't match, probably because they post-process the binary in some way. This leads to completely bogus debug information being parsed by drgn_dwarf_index. Fix it by only relocating ET_REL files.
1 parent 4bb36fc commit 6f16ab0

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

libdrgn/dwarf_index.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -349,24 +349,23 @@ void drgn_dwarf_index_destroy(struct drgn_dwarf_index *dindex)
349349
static struct drgn_error *read_sections(struct debug_file *file)
350350
{
351351
struct drgn_error *err;
352-
const char *e_ident;
352+
GElf_Ehdr ehdr_mem, *ehdr;
353353
size_t shstrndx;
354354
Elf_Scn *scn = NULL;
355355
size_t section_index[NUM_SECTIONS] = {};
356356
size_t i;
357357

358-
e_ident = elf_getident(file->elf, NULL);
359-
if (!e_ident)
358+
ehdr = gelf_getehdr(file->elf, &ehdr_mem);
359+
if (!ehdr)
360360
return &drgn_not_elf;
361361

362-
file->bswap = (e_ident[EI_DATA] !=
362+
file->bswap = (ehdr->e_ident[EI_DATA] !=
363363
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ?
364364
ELFDATA2LSB : ELFDATA2MSB));
365365

366366
if (elf_getshdrstrndx(file->elf, &shstrndx))
367367
return drgn_error_libelf();
368368

369-
/* First pass: get the symbol table and all debug sections. */
370369
while ((scn = elf_nextscn(file->elf, scn))) {
371370
GElf_Shdr *shdr, shdr_mem;
372371
const char *scnname;
@@ -404,7 +403,10 @@ static struct drgn_error *read_sections(struct debug_file *file)
404403
}
405404
}
406405

407-
/* Second pass: get the relocation sections. */
406+
if (ehdr->e_type != ET_REL)
407+
return NULL;
408+
409+
/* Make a second pass to get the relocation sections, if needed. */
408410
while ((scn = elf_nextscn(file->elf, scn))) {
409411
GElf_Shdr *shdr, shdr_mem;
410412

@@ -422,7 +424,7 @@ static struct drgn_error *read_sections(struct debug_file *file)
422424
if (shdr->sh_info != section_index[i])
423425
continue;
424426

425-
if (e_ident[EI_CLASS] != ELFCLASS64) {
427+
if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
426428
return drgn_error_create(DRGN_ERROR_ELF_FORMAT,
427429
"32-bit ELF relocations are not implemented");
428430
}

0 commit comments

Comments
 (0)