From 6f16ab09d6029fe91e4527e3003b76b5d9a61366 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 6 May 2019 11:09:46 -0700 Subject: [PATCH] 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. --- libdrgn/dwarf_index.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libdrgn/dwarf_index.c b/libdrgn/dwarf_index.c index d78e7e21..933e3eb0 100644 --- a/libdrgn/dwarf_index.c +++ b/libdrgn/dwarf_index.c @@ -349,24 +349,23 @@ void drgn_dwarf_index_destroy(struct drgn_dwarf_index *dindex) static struct drgn_error *read_sections(struct debug_file *file) { struct drgn_error *err; - const char *e_ident; + GElf_Ehdr ehdr_mem, *ehdr; size_t shstrndx; Elf_Scn *scn = NULL; size_t section_index[NUM_SECTIONS] = {}; size_t i; - e_ident = elf_getident(file->elf, NULL); - if (!e_ident) + ehdr = gelf_getehdr(file->elf, &ehdr_mem); + if (!ehdr) return &drgn_not_elf; - file->bswap = (e_ident[EI_DATA] != + file->bswap = (ehdr->e_ident[EI_DATA] != (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ? ELFDATA2LSB : ELFDATA2MSB)); if (elf_getshdrstrndx(file->elf, &shstrndx)) return drgn_error_libelf(); - /* First pass: get the symbol table and all debug sections. */ while ((scn = elf_nextscn(file->elf, scn))) { GElf_Shdr *shdr, shdr_mem; const char *scnname; @@ -404,7 +403,10 @@ static struct drgn_error *read_sections(struct debug_file *file) } } - /* Second pass: get the relocation sections. */ + if (ehdr->e_type != ET_REL) + return NULL; + + /* Make a second pass to get the relocation sections, if needed. */ while ((scn = elf_nextscn(file->elf, scn))) { GElf_Shdr *shdr, shdr_mem; @@ -422,7 +424,7 @@ static struct drgn_error *read_sections(struct debug_file *file) if (shdr->sh_info != section_index[i]) continue; - if (e_ident[EI_CLASS] != ELFCLASS64) { + if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) { return drgn_error_create(DRGN_ERROR_ELF_FORMAT, "32-bit ELF relocations are not implemented"); }