aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-08-02 12:35:39 +0930
committerAlan Modra <amodra@gmail.com>2019-08-02 12:42:02 +0930
commit97c0a07968a7c64e1de96abff8937d089f09b3e7 (patch)
treece504d025bc7c1d1c64d9fa13db1a44c90fda239 /binutils/readelf.c
parent1b611b2dc3075d20372557021f95ec326cdf8aa5 (diff)
downloadgdb-97c0a07968a7c64e1de96abff8937d089f09b3e7.zip
gdb-97c0a07968a7c64e1de96abff8937d089f09b3e7.tar.gz
gdb-97c0a07968a7c64e1de96abff8937d089f09b3e7.tar.bz2
PR24871, readelf segv in dump_ia64_unwind
PR 24871 * readelf.c (ABSADDR): Delete. (dump_ia64_unwind): Expand ABSADDR. Check validity of info.section.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r--binutils/readelf.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 6175b33..b896ad9 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -7415,11 +7415,6 @@ struct absaddr
bfd_vma offset;
};
-#define ABSADDR(a) \
- ((a).section \
- ? filedata->section_headers [(a).section].sh_addr + (a).offset \
- : (a).offset)
-
/* Find the nearest symbol at or below ADDR. Returns the symbol
name, if found, and the offset from the symbol to ADDR. */
@@ -7565,8 +7560,21 @@ dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
if (aux->info == NULL)
continue;
+ offset = tp->info.offset;
+ if (tp->info.section)
+ {
+ if (tp->info.section >= filedata->file_header.e_shnum)
+ {
+ warn (_("Invalid section %u in table entry %ld\n"),
+ tp->info.section, (long) (tp - aux->table));
+ res = FALSE;
+ continue;
+ }
+ offset += filedata->section_headers[tp->info.section].sh_addr;
+ }
+ offset -= aux->info_addr;
/* PR 17531: file: 0997b4d1. */
- if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
+ if (offset >= aux->info_size)
{
warn (_("Invalid offset %lx in table entry %ld\n"),
(long) tp->info.offset, (long) (tp - aux->table));
@@ -7574,7 +7582,7 @@ dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
continue;
}
- head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
+ head = aux->info + offset;
stamp = byte_get ((unsigned char *) head, sizeof (stamp));
printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",