aboutsummaryrefslogtreecommitdiff
path: root/contrib/elftoolchain
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2016-12-16 01:42:51 +0000
committerConrad Meyer <cem@FreeBSD.org>2016-12-16 01:42:51 +0000
commit93326017f627976ea17f60a1bc17f98f1249c6b3 (patch)
tree2eef3f5ffd12d578af308cc9887e72847c292e88 /contrib/elftoolchain
parent1d1bfbbb385c6849c5f45f095ddc06b18749eef8 (diff)
downloadsrc-93326017f627976ea17f60a1bc17f98f1249c6b3.tar.gz
src-93326017f627976ea17f60a1bc17f98f1249c6b3.zip
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
Notes
Notes: svn path=/head/; revision=310137
Diffstat (limited to 'contrib/elftoolchain')
-rw-r--r--contrib/elftoolchain/libelf/gelf_phdr.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/contrib/elftoolchain/libelf/gelf_phdr.c b/contrib/elftoolchain/libelf/gelf_phdr.c
index 31e20b0680c5..4786b27c62b5 100644
--- a/contrib/elftoolchain/libelf/gelf_phdr.c
+++ b/contrib/elftoolchain/libelf/gelf_phdr.c
@@ -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);
}