Handle ELF files with 65280 or more sections
If e_shnum or e_shstrndx are at least SHN_LORESERVE (0xff00) then an escape value is used to indicate that the actual value is found in one of section 0's fields. Sponsored by: DARPA, AFRL
This commit is contained in:
parent
adb7cfe32b
commit
97a9b0b123
@ -368,7 +368,7 @@ static u_int64_t elf_get_half(Elf32_Ehdr *e, void *base, elf_member_t member);
|
||||
static u_int64_t elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member);
|
||||
static u_int64_t elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member);
|
||||
|
||||
static void elf_print_ehdr(Elf32_Ehdr *e);
|
||||
static void elf_print_ehdr(Elf32_Ehdr *e, void *sh);
|
||||
static void elf_print_phdr(Elf32_Ehdr *e, void *p);
|
||||
static void elf_print_shdr(Elf32_Ehdr *e, void *sh);
|
||||
static void elf_print_symtab(Elf32_Ehdr *e, void *sh, char *str);
|
||||
@ -382,6 +382,33 @@ static void elf_print_note(Elf32_Ehdr *e, void *sh);
|
||||
|
||||
static void usage(void);
|
||||
|
||||
/*
|
||||
* Helpers for ELF files with shnum or shstrndx values that don't fit in the
|
||||
* ELF header. If the values are too large then an escape value is used to
|
||||
* indicate that the actual value is found in one of section 0's fields.
|
||||
*/
|
||||
static uint64_t
|
||||
elf_get_shnum(Elf32_Ehdr *e, void *sh)
|
||||
{
|
||||
uint64_t shnum;
|
||||
|
||||
shnum = elf_get_quarter(e, e, E_SHNUM);
|
||||
if (shnum == 0)
|
||||
shnum = elf_get_word(e, (char *)sh, SH_SIZE);
|
||||
return shnum;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
elf_get_shstrndx(Elf32_Ehdr *e, void *sh)
|
||||
{
|
||||
uint64_t shstrndx;
|
||||
|
||||
shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
|
||||
if (shstrndx == SHN_XINDEX)
|
||||
shstrndx = elf_get_word(e, (char *)sh, SH_LINK);
|
||||
return shstrndx;
|
||||
}
|
||||
|
||||
int
|
||||
main(int ac, char **av)
|
||||
{
|
||||
@ -467,10 +494,10 @@ main(int ac, char **av)
|
||||
phentsize = elf_get_quarter(e, e, E_PHENTSIZE);
|
||||
phnum = elf_get_quarter(e, e, E_PHNUM);
|
||||
shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
|
||||
shnum = elf_get_quarter(e, e, E_SHNUM);
|
||||
shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
|
||||
p = (char *)e + phoff;
|
||||
sh = (char *)e + shoff;
|
||||
shnum = elf_get_shnum(e, sh);
|
||||
shstrndx = elf_get_shstrndx(e, sh);
|
||||
offset = elf_get_off(e, (char *)sh + shstrndx * shentsize, SH_OFFSET);
|
||||
shstrtab = (char *)e + offset;
|
||||
for (i = 0; (u_int64_t)i < shnum; i++) {
|
||||
@ -482,7 +509,7 @@ main(int ac, char **av)
|
||||
dynstr = (char *)e + offset;
|
||||
}
|
||||
if (flags & ED_EHDR)
|
||||
elf_print_ehdr(e);
|
||||
elf_print_ehdr(e, sh);
|
||||
if (flags & ED_PHDR)
|
||||
elf_print_phdr(e, p);
|
||||
if (flags & ED_SHDR)
|
||||
@ -556,7 +583,7 @@ main(int ac, char **av)
|
||||
}
|
||||
|
||||
static void
|
||||
elf_print_ehdr(Elf32_Ehdr *e)
|
||||
elf_print_ehdr(Elf32_Ehdr *e, void *sh)
|
||||
{
|
||||
u_int64_t class;
|
||||
u_int64_t data;
|
||||
@ -589,8 +616,8 @@ elf_print_ehdr(Elf32_Ehdr *e)
|
||||
phentsize = elf_get_quarter(e, e, E_PHENTSIZE);
|
||||
phnum = elf_get_quarter(e, e, E_PHNUM);
|
||||
shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
|
||||
shnum = elf_get_quarter(e, e, E_SHNUM);
|
||||
shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
|
||||
shnum = elf_get_shnum(e, sh);
|
||||
shstrndx = elf_get_shstrndx(e, sh);
|
||||
fprintf(out, "\nelf header:\n");
|
||||
fprintf(out, "\n");
|
||||
fprintf(out, "\te_ident: %s %s %s\n", ei_classes[class], ei_data[data],
|
||||
@ -671,7 +698,7 @@ elf_print_shdr(Elf32_Ehdr *e, void *sh)
|
||||
int i;
|
||||
|
||||
shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
|
||||
shnum = elf_get_quarter(e, e, E_SHNUM);
|
||||
shnum = elf_get_shnum(e, sh);
|
||||
fprintf(out, "\nsection header:\n");
|
||||
for (i = 0; (u_int64_t)i < shnum; i++) {
|
||||
v = (char *)sh + i * shentsize;
|
||||
|
Loading…
x
Reference in New Issue
Block a user