Skip to content

Commit

Permalink
libdrgn: only apply ELF relocations to relocatable files
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
osandov committed May 6, 2019
1 parent 4bb36fc commit 6f16ab0
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions libdrgn/dwarf_index.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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");
}
Expand Down

0 comments on commit 6f16ab0

Please sign in to comment.