gelf_getphdr: Allow extended indices

Needed for 'readelf -l' of extended phnum files.  (Parity with GNU
binutils.)

Reviewed by:	no one, unfortunately
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D8703
This commit is contained in:
Conrad Meyer 2016-12-16 01:42:51 +00:00
parent 1d1bfbbb38
commit 93326017f6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=310137

View File

@ -53,10 +53,17 @@ gelf_getphdr(Elf *e, int index, GElf_Phdr *d)
Elf64_Ehdr *eh64;
Elf32_Phdr *ep32;
Elf64_Phdr *ep64;
size_t phnum;
if (d == NULL || e == NULL ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
(e->e_kind != ELF_K_ELF) || index < 0) {
(e->e_kind != ELF_K_ELF) || index < 0 ||
elf_getphdrnum(e, &phnum) < 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if ((size_t)index >= phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
@ -66,11 +73,6 @@ gelf_getphdr(Elf *e, int index, GElf_Phdr *d)
((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL))
return (NULL);
if (index >= eh32->e_phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ep32 += index;
d->p_type = ep32->p_type;
@ -87,11 +89,6 @@ gelf_getphdr(Elf *e, int index, GElf_Phdr *d)
(ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL)
return (NULL);
if (index >= eh64->e_phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
ep64 += index;
*d = *ep64;
@ -125,13 +122,15 @@ gelf_newphdr(Elf *e, size_t count)
int
gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s)
{
int ec, phnum;
int ec;
size_t phnum;
void *ehdr;
Elf32_Phdr *ph32;
Elf64_Phdr *ph64;
if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF ||
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
elf_getphdrnum(e, &phnum) < 0) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
@ -144,12 +143,7 @@ gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s)
if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
return (0);
if (ec == ELFCLASS32)
phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
else
phnum = ((Elf64_Ehdr *) ehdr)->e_phnum;
if (ndx < 0 || ndx > phnum) {
if (ndx < 0 || (size_t)ndx > phnum) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}