summaryrefslogtreecommitdiffstats
path: root/src/readelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/readelf.c')
-rw-r--r--src/readelf.c117
1 files changed, 82 insertions, 35 deletions
diff --git a/src/readelf.c b/src/readelf.c
index 739156cf..f9f2f81e 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1364,6 +1364,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
GElf_Sym sym_mem;
+ GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
+
printf ((grpref[0] & GRP_COMDAT)
? ngettext ("\
\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
@@ -1376,8 +1378,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
data->d_size / sizeof (Elf32_Word) - 1),
elf_ndxscn (scn),
elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
- elf_strptr (ebl->elf, symshdr->sh_link,
- gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name)
+ (sym == NULL ? NULL
+ : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
?: gettext ("<INVALID SYMBOL>"),
data->d_size / sizeof (Elf32_Word) - 1);
@@ -1528,10 +1530,12 @@ static void
handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
int class = gelf_getclass (ebl->elf);
- GElf_Shdr glink;
+ GElf_Shdr glink_mem;
+ GElf_Shdr *glink;
Elf_Data *data;
size_t cnt;
size_t shstrndx;
+ size_t sh_entsize;
/* Get the data of the section. */
data = elf_getdata (scn, NULL);
@@ -1543,21 +1547,26 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
+ sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
+
+ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
+ if (glink == NULL)
+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
+ elf_ndxscn (scn));
+
printf (ngettext ("\
\nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
\nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
- shdr->sh_size / shdr->sh_entsize),
- (unsigned long int) (shdr->sh_size / shdr->sh_entsize),
+ shdr->sh_size / sh_entsize),
+ (unsigned long int) (shdr->sh_size / sh_entsize),
class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
shdr->sh_offset,
(int) shdr->sh_link,
- elf_strptr (ebl->elf, shstrndx,
- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
- &glink)->sh_name));
+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
fputs_unlocked (gettext (" Type Value\n"), stdout);
- for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+ for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
{
GElf_Dyn dynmem;
GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
@@ -1706,7 +1715,8 @@ static void
handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
{
int class = gelf_getclass (ebl->elf);
- int nentries = shdr->sh_size / shdr->sh_entsize;
+ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
+ int nentries = shdr->sh_size / sh_entsize;
/* Get the data of the section. */
Elf_Data *data = elf_getdata (scn, NULL);
@@ -1892,7 +1902,8 @@ static void
handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
{
int class = gelf_getclass (ebl->elf);
- int nentries = shdr->sh_size / shdr->sh_entsize;
+ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
+ int nentries = shdr->sh_size / sh_entsize;
/* Get the data of the section. */
Elf_Data *data = elf_getdata (scn, NULL);
@@ -2139,6 +2150,13 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
+ GElf_Shdr glink_mem;
+ GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+ &glink_mem);
+ if (glink == NULL)
+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
+ elf_ndxscn (scn));
+
/* Now we can compute the number of entries in the section. */
unsigned int nsyms = data->d_size / (class == ELFCLASS32
? sizeof (Elf32_Sym)
@@ -2149,15 +2167,12 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
nsyms),
(unsigned int) elf_ndxscn (scn),
elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
- GElf_Shdr glink;
printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
" %lu local symbols String table: [%2u] '%s'\n",
shdr->sh_info),
(unsigned long int) shdr->sh_info,
(unsigned int) shdr->sh_link,
- elf_strptr (ebl->elf, shstrndx,
- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
- &glink)->sh_name));
+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
fputs_unlocked (class == ELFCLASS32
? gettext ("\
@@ -2393,7 +2408,13 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
- GElf_Shdr glink;
+ GElf_Shdr glink_mem;
+ GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+ &glink_mem);
+ if (glink == NULL)
+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
+ elf_ndxscn (scn));
+
printf (ngettext ("\
\nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
@@ -2404,9 +2425,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
shdr->sh_offset,
(unsigned int) shdr->sh_link,
- elf_strptr (ebl->elf, shstrndx,
- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
- &glink)->sh_name));
+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
unsigned int offset = 0;
for (int cnt = shdr->sh_info; --cnt >= 0; )
@@ -2459,8 +2478,14 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
+ GElf_Shdr glink_mem;
+ GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+ &glink_mem);
+ if (glink == NULL)
+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
+ elf_ndxscn (scn));
+
int class = gelf_getclass (ebl->elf);
- GElf_Shdr glink;
printf (ngettext ("\
\nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
@@ -2472,9 +2497,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
shdr->sh_offset,
(unsigned int) shdr->sh_link,
- elf_strptr (ebl->elf, shstrndx,
- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
- &glink)->sh_name));
+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
unsigned int offset = 0;
for (int cnt = shdr->sh_info; --cnt >= 0; )
@@ -2736,25 +2759,30 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
filename = NULL;
}
+ GElf_Shdr glink_mem;
+ GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+ &glink_mem);
+ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
+ if (glink == NULL)
+ error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
+ elf_ndxscn (scn));
+
/* Print the header. */
- GElf_Shdr glink;
printf (ngettext ("\
\nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
"\
\nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
- shdr->sh_size / shdr->sh_entsize),
+ shdr->sh_size / sh_entsize),
(unsigned int) elf_ndxscn (scn),
elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
- (int) (shdr->sh_size / shdr->sh_entsize),
+ (int) (shdr->sh_size / sh_entsize),
class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
shdr->sh_offset,
(unsigned int) shdr->sh_link,
- elf_strptr (ebl->elf, shstrndx,
- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
- &glink)->sh_name));
+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
/* Now we can finally look at the actual contents of this section. */
- for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+ for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
{
if (cnt % 2 == 0)
printf ("\n %4d:", cnt);
@@ -2803,7 +2831,17 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
++counts[lengths[cnt]];
- GElf_Shdr glink;
+ GElf_Shdr glink_mem;
+ GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
+ shdr->sh_link),
+ &glink_mem);
+ if (glink == NULL)
+ {
+ error (0, 0, gettext ("invalid sh_link value in section %Zu"),
+ elf_ndxscn (scn));
+ return;
+ }
+
printf (ngettext ("\
\nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
"\
@@ -2816,9 +2854,7 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
shdr->sh_addr,
shdr->sh_offset,
(unsigned int) shdr->sh_link,
- elf_strptr (ebl->elf, shstrndx,
- gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
- &glink)->sh_name));
+ elf_strptr (ebl->elf, shstrndx, glink->sh_name));
if (extrastr != NULL)
fputs (extrastr, stdout);
@@ -3078,7 +3114,8 @@ print_liblist (Ebl *ebl)
if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
{
- int nentries = shdr->sh_size / shdr->sh_entsize;
+ size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
+ int nentries = shdr->sh_size / sh_entsize;
printf (ngettext ("\
\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
"\
@@ -4398,6 +4435,16 @@ print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
return;
}
+ GElf_Shdr glink_mem;
+ GElf_Shdr *glink;
+ glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
+ if (glink == NULL)
+ {
+ error (0, 0, gettext ("invalid sh_link value in section %Zu"),
+ elf_ndxscn (scn));
+ return;
+ }
+
printf (ngettext ("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
"\