mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-23 17:53:07 +00:00
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.
This commit is contained in:
parent
4bb36fc150
commit
6f16ab09d6
@ -349,24 +349,23 @@ void drgn_dwarf_index_destroy(struct drgn_dwarf_index *dindex)
|
|||||||
static struct drgn_error *read_sections(struct debug_file *file)
|
static struct drgn_error *read_sections(struct debug_file *file)
|
||||||
{
|
{
|
||||||
struct drgn_error *err;
|
struct drgn_error *err;
|
||||||
const char *e_ident;
|
GElf_Ehdr ehdr_mem, *ehdr;
|
||||||
size_t shstrndx;
|
size_t shstrndx;
|
||||||
Elf_Scn *scn = NULL;
|
Elf_Scn *scn = NULL;
|
||||||
size_t section_index[NUM_SECTIONS] = {};
|
size_t section_index[NUM_SECTIONS] = {};
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
e_ident = elf_getident(file->elf, NULL);
|
ehdr = gelf_getehdr(file->elf, &ehdr_mem);
|
||||||
if (!e_ident)
|
if (!ehdr)
|
||||||
return &drgn_not_elf;
|
return &drgn_not_elf;
|
||||||
|
|
||||||
file->bswap = (e_ident[EI_DATA] !=
|
file->bswap = (ehdr->e_ident[EI_DATA] !=
|
||||||
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ?
|
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ?
|
||||||
ELFDATA2LSB : ELFDATA2MSB));
|
ELFDATA2LSB : ELFDATA2MSB));
|
||||||
|
|
||||||
if (elf_getshdrstrndx(file->elf, &shstrndx))
|
if (elf_getshdrstrndx(file->elf, &shstrndx))
|
||||||
return drgn_error_libelf();
|
return drgn_error_libelf();
|
||||||
|
|
||||||
/* First pass: get the symbol table and all debug sections. */
|
|
||||||
while ((scn = elf_nextscn(file->elf, scn))) {
|
while ((scn = elf_nextscn(file->elf, scn))) {
|
||||||
GElf_Shdr *shdr, shdr_mem;
|
GElf_Shdr *shdr, shdr_mem;
|
||||||
const char *scnname;
|
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))) {
|
while ((scn = elf_nextscn(file->elf, scn))) {
|
||||||
GElf_Shdr *shdr, shdr_mem;
|
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])
|
if (shdr->sh_info != section_index[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (e_ident[EI_CLASS] != ELFCLASS64) {
|
if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
|
||||||
return drgn_error_create(DRGN_ERROR_ELF_FORMAT,
|
return drgn_error_create(DRGN_ERROR_ELF_FORMAT,
|
||||||
"32-bit ELF relocations are not implemented");
|
"32-bit ELF relocations are not implemented");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user