You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
\f
/* The difference between readelf and objdump:
#include "elf/i960.h"
#include "elf/ia64.h"
#include "elf/ip2k.h"
+#include "elf/m32c.h"
#include "elf/m32r.h"
#include "elf/m68k.h"
#include "elf/m68hc11.h"
#include "elf/mmix.h"
#include "elf/mn10200.h"
#include "elf/mn10300.h"
+#include "elf/ms1.h"
#include "elf/msp430.h"
#include "elf/or32.h"
#include "elf/pj.h"
#include "libiberty.h"
char *program_name = "readelf";
-long archive_file_offset;
-unsigned long archive_file_size;
-unsigned long dynamic_addr;
-bfd_size_type dynamic_size;
-unsigned int dynamic_nent;
-char *dynamic_strings;
-unsigned long dynamic_strings_length;
-char *string_table;
-unsigned long string_table_length;
-unsigned long num_dynamic_syms;
-Elf_Internal_Sym *dynamic_symbols;
-Elf_Internal_Syminfo *dynamic_syminfo;
-unsigned long dynamic_syminfo_offset;
-unsigned int dynamic_syminfo_nent;
-char program_interpreter[64];
-bfd_vma dynamic_info[DT_JMPREL + 1];
-bfd_vma version_info[16];
-Elf_Internal_Ehdr elf_header;
-Elf_Internal_Shdr *section_headers;
-Elf_Internal_Phdr *program_headers;
-Elf_Internal_Dyn *dynamic_section;
-Elf_Internal_Shdr *symtab_shndx_hdr;
-int show_name;
-int do_dynamic;
-int do_syms;
-int do_reloc;
-int do_sections;
-int do_section_groups;
-int do_segments;
-int do_unwind;
-int do_using_dynamic;
-int do_header;
-int do_dump;
-int do_version;
-int do_wide;
-int do_histogram;
-int do_debugging;
-int do_debug_info;
-int do_debug_abbrevs;
-int do_debug_lines;
-int do_debug_pubnames;
-int do_debug_aranges;
-int do_debug_ranges;
-int do_debug_frames;
-int do_debug_frames_interp;
-int do_debug_macinfo;
-int do_debug_str;
-int do_debug_loc;
-int do_arch;
-int do_notes;
-int is_32bit_elf;
-int have_frame_base;
-int need_base_address;
-bfd_vma eh_addr_size;
+static long archive_file_offset;
+static unsigned long archive_file_size;
+static unsigned long dynamic_addr;
+static bfd_size_type dynamic_size;
+static unsigned int dynamic_nent;
+static char *dynamic_strings;
+static unsigned long dynamic_strings_length;
+static char *string_table;
+static unsigned long string_table_length;
+static unsigned long num_dynamic_syms;
+static Elf_Internal_Sym *dynamic_symbols;
+static Elf_Internal_Syminfo *dynamic_syminfo;
+static unsigned long dynamic_syminfo_offset;
+static unsigned int dynamic_syminfo_nent;
+static char program_interpreter[64];
+static bfd_vma dynamic_info[DT_JMPREL + 1];
+static bfd_vma version_info[16];
+static Elf_Internal_Ehdr elf_header;
+static Elf_Internal_Shdr *section_headers;
+static Elf_Internal_Phdr *program_headers;
+static Elf_Internal_Dyn *dynamic_section;
+static Elf_Internal_Shdr *symtab_shndx_hdr;
+static int show_name;
+static int do_dynamic;
+static int do_syms;
+static int do_reloc;
+static int do_sections;
+static int do_section_groups;
+static int do_section_details;
+static int do_segments;
+static int do_unwind;
+static int do_using_dynamic;
+static int do_header;
+static int do_dump;
+static int do_version;
+static int do_wide;
+static int do_histogram;
+static int do_debugging;
+static int do_debug_info;
+static int do_debug_abbrevs;
+static int do_debug_lines;
+static int do_debug_pubnames;
+static int do_debug_aranges;
+static int do_debug_ranges;
+static int do_debug_frames;
+static int do_debug_frames_interp;
+static int do_debug_macinfo;
+static int do_debug_str;
+static int do_debug_loc;
+static int do_arch;
+static int do_notes;
+static int is_32bit_elf;
+static int have_frame_base;
+static int need_base_address;
+static bfd_vma eh_addr_size;
struct group_list
{
unsigned int group_index;
};
-struct group *section_groups;
-size_t group_count;
-
-struct group **section_headers_groups;
+static size_t group_count;
+static struct group *section_groups;
+static struct group **section_headers_groups;
/* A dynamic array of flags indicating for which sections a hex dump
has been requested (via the -x switch) and/or a disassembly dump
#define DISASS_DUMP (1 << 1)
#define DEBUG_DUMP (1 << 2)
-/* How to rpint a vma value. */
+/* How to print a vma value. */
typedef enum print_mode
{
HEX,
#define streq(a,b) (strcmp ((a), (b)) == 0)
#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
\f
-static void
+static void ATTRIBUTE_PRINTF_1
error (const char *message, ...)
{
va_list args;
va_end (args);
}
-static void
+static void ATTRIBUTE_PRINTF_1
warn (const char *message, ...)
{
va_list args;
}
static void *
-get_data (void *var, FILE *file, long offset, size_t size, const char *reason)
+cmalloc (size_t nmemb, size_t size)
+{
+ /* Check for overflow. */
+ if (nmemb >= ~(size_t) 0 / size)
+ return NULL;
+ else
+ return malloc (nmemb * size);
+}
+
+static void *
+xcmalloc (size_t nmemb, size_t size)
+{
+ /* Check for overflow. */
+ if (nmemb >= ~(size_t) 0 / size)
+ return NULL;
+ else
+ return xmalloc (nmemb * size);
+}
+
+static void *
+xcrealloc (void *ptr, size_t nmemb, size_t size)
+{
+ /* Check for overflow. */
+ if (nmemb >= ~(size_t) 0 / size)
+ return NULL;
+ else
+ return xrealloc (ptr, nmemb * size);
+}
+
+static void *
+get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb,
+ const char *reason)
{
void *mvar;
- if (size == 0)
+ if (size == 0 || nmemb == 0)
return NULL;
if (fseek (file, archive_file_offset + offset, SEEK_SET))
{
- error (_("Unable to seek to 0x%x for %s\n"),
+ error (_("Unable to seek to 0x%lx for %s\n"),
archive_file_offset + offset, reason);
return NULL;
}
mvar = var;
if (mvar == NULL)
{
- mvar = malloc (size);
+ /* Check for overflow. */
+ if (nmemb < (~(size_t) 0 - 1) / size)
+ /* + 1 so that we can '\0' terminate invalid string table sections. */
+ mvar = malloc (size * nmemb + 1);
if (mvar == NULL)
{
- error (_("Out of memory allocating 0x%x bytes for %s\n"),
- size, reason);
+ error (_("Out of memory allocating 0x%lx bytes for %s\n"),
+ (unsigned long)(size * nmemb), reason);
return NULL;
}
+
+ ((char *) mvar)[size * nmemb] = '\0';
}
- if (fread (mvar, size, 1, file) != 1)
+ if (fread (mvar, size, nmemb, file) != nmemb)
{
- error (_("Unable to read in 0x%x bytes of %s\n"), size, reason);
+ error (_("Unable to read in 0x%lx bytes of %s\n"),
+ (unsigned long)(size * nmemb), reason);
if (mvar != var)
free (mvar);
return NULL;
case EM_XTENSA:
case EM_XTENSA_OLD:
case EM_M32R:
+ case EM_M32C:
+ case EM_MS1:
return TRUE;
case EM_MMA:
{
Elf32_External_Rela *erelas;
- erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+ erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
if (!erelas)
return 0;
nrelas = rel_size / sizeof (Elf32_External_Rela);
- relas = malloc (nrelas * sizeof (Elf_Internal_Rela));
+ relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
if (relas == NULL)
{
+ free (erelas);
error (_("out of memory parsing relocs"));
return 0;
}
{
Elf64_External_Rela *erelas;
- erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+ erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
if (!erelas)
return 0;
nrelas = rel_size / sizeof (Elf64_External_Rela);
- relas = malloc (nrelas * sizeof (Elf_Internal_Rela));
+ relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
if (relas == NULL)
{
+ free (erelas);
error (_("out of memory parsing relocs"));
return 0;
}
{
Elf32_External_Rel *erels;
- erels = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+ erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
if (!erels)
return 0;
nrels = rel_size / sizeof (Elf32_External_Rel);
- rels = malloc (nrels * sizeof (Elf_Internal_Rela));
+ rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
if (rels == NULL)
{
+ free (erels);
error (_("out of memory parsing relocs"));
return 0;
}
{
Elf64_External_Rel *erels;
- erels = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+ erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
if (!erels)
return 0;
nrels = rel_size / sizeof (Elf64_External_Rel);
- rels = malloc (nrels * sizeof (Elf_Internal_Rela));
+ rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
if (rels == NULL)
{
+ free (erels);
error (_("out of memory parsing relocs"));
return 0;
}
case EM_XTENSA:
rtype = elf_xtensa_reloc_type (type);
break;
+
+ case EM_M32C:
+ rtype = elf_m32c_reloc_type (type);
+ break;
+
+ case EM_MS1:
+ rtype = elf_ms1_reloc_type (type);
+ break;
}
if (rtype == NULL)
else
printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
- if (symtab_index)
+ if (elf_header.e_machine == EM_ALPHA
+ && streq (rtype, "R_ALPHA_LITUSE")
+ && is_rela)
+ {
+ switch (rels[i].r_addend)
+ {
+ case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
+ case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
+ case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
+ case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
+ case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
+ case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
+ case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
+ default: rtype = NULL;
+ }
+ if (rtype)
+ printf (" (%s)", rtype);
+ else
+ {
+ putchar (' ');
+ printf (_("<unknown addend: %lx>"),
+ (unsigned long) rels[i].r_addend);
+ }
+ }
+ else if (symtab_index)
{
if (symtab == NULL || symtab_index >= nsyms)
printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
sec_name = "ABS";
else if (psym->st_shndx == SHN_COMMON)
sec_name = "COMMON";
+ else if (elf_header.e_machine == EM_X86_64
+ && psym->st_shndx == SHN_X86_64_LCOMMON)
+ sec_name = "LARGE_COMMON";
else if (elf_header.e_machine == EM_IA_64
&& elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
&& psym->st_shndx == SHN_IA_64_ANSI_COMMON)
}
else if (strtab == NULL)
printf (_("<string table index: %3ld>"), psym->st_name);
- else if (psym->st_name > strtablen)
+ else if (psym->st_name >= strtablen)
printf (_("<corrupt string table index: %3ld>"), psym->st_name);
else
print_symbol (22, strtab + psym->st_name);
print_vma (rels[i].r_addend, LONG_HEX);
}
- if (elf_header.e_machine == EM_SPARCV9
- && streq (rtype, "R_SPARC_OLO10"))
+ if (elf_header.e_machine == EM_SPARCV9 && streq (rtype, "R_SPARC_OLO10"))
printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info));
putchar ('\n');
}
}
+static const char *
+get_ppc_dynamic_type (unsigned long type)
+{
+ switch (type)
+ {
+ case DT_PPC_GOT: return "PPC_GOT";
+ default:
+ return NULL;
+ }
+}
+
static const char *
get_ppc64_dynamic_type (unsigned long type)
{
case DT_HP_GST_SIZE: return "HP_GST_SIZE";
case DT_HP_GST_VERSION: return "HP_GST_VERSION";
case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
+ case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
+ case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
+ case DT_HP_FILTERED: return "HP_FILTERED";
+ case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
+ case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
+ case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
+ case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
+ case DT_PLT: return "PLT";
+ case DT_PLT_SIZE: return "PLT_SIZE";
+ case DT_DLT: return "DLT";
+ case DT_DLT_SIZE: return "DLT_SIZE";
default:
return NULL;
}
}
}
+static const char *
+get_alpha_dynamic_type (unsigned long type)
+{
+ switch (type)
+ {
+ case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
+ default:
+ return NULL;
+ }
+}
+
static const char *
get_dynamic_type (unsigned long type)
{
- static char buff[32];
+ static char buff[64];
switch (type)
{
case EM_SPARCV9:
result = get_sparc64_dynamic_type (type);
break;
+ case EM_PPC:
+ result = get_ppc_dynamic_type (type);
+ break;
case EM_PPC64:
result = get_ppc64_dynamic_type (type);
break;
case EM_IA_64:
result = get_ia64_dynamic_type (type);
break;
+ case EM_ALPHA:
+ result = get_alpha_dynamic_type (type);
+ break;
default:
result = NULL;
break;
if (result != NULL)
return result;
- sprintf (buff, _("Processor Specific: %lx"), type);
+ snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
}
- else if ((type >= DT_LOOS) && (type <= DT_HIOS))
+ else if (((type >= DT_LOOS) && (type <= DT_HIOS))
+ || (elf_header.e_machine == EM_PARISC
+ && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
{
const char *result;
if (result != NULL)
return result;
- sprintf (buff, _("Operating System specific: %lx"), type);
+ snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
+ type);
}
else
- sprintf (buff, _("<unknown>: %lx"), type);
+ snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
return buff;
}
default:
if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
- sprintf (buff, _("Processor Specific: (%x)"), e_type);
+ snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
- sprintf (buff, _("OS Specific: (%x)"), e_type);
+ snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
else
- sprintf (buff, _("<unknown>: %x"), e_type);
+ snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
return buff;
}
}
case EM_IQ2000: return "Vitesse IQ2000";
case EM_XTENSA_OLD:
case EM_XTENSA: return "Tensilica Xtensa Processor";
+ case EM_M32C: return "Renesas M32c";
+ case EM_MS1: return "Morpho Techologies MS1 processor";
default:
- sprintf (buff, _("<unknown>: %x"), e_machine);
+ snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_machine);
return buff;
}
}
case ELFOSABI_STANDALONE: return _("Standalone App");
case ELFOSABI_ARM: return "ARM";
default:
- sprintf (buff, _("<unknown: %x>"), osabi);
+ snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
return buff;
}
}
+static const char *
+get_arm_segment_type (unsigned long type)
+{
+ switch (type)
+ {
+ case PT_ARM_EXIDX:
+ return "EXIDX";
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
static const char *
get_mips_segment_type (unsigned long type)
{
case PT_HP_CORE_MMF: return "HP_CORE_MMF";
case PT_HP_PARALLEL: return "HP_PARALLEL";
case PT_HP_FASTBIND: return "HP_FASTBIND";
+ case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
+ case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
+ case PT_HP_STACK: return "HP_STACK";
+ case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
case PT_PARISC_UNWIND: return "PARISC_UNWIND";
+ case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
default:
break;
}
switch (elf_header.e_machine)
{
+ case EM_ARM:
+ result = get_arm_segment_type (p_type);
+ break;
case EM_MIPS:
case EM_MIPS_RS3_LE:
result = get_mips_segment_type (p_type);
sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
}
else
- sprintf (buff, _("<unknown>: %lx"), p_type);
+ snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
return buff;
}
case SHT_PARISC_EXT: return "PARISC_EXT";
case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
case SHT_PARISC_DOC: return "PARISC_DOC";
+ case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
+ case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
+ case SHT_PARISC_STUBS: return "PARISC_STUBS";
+ case SHT_PARISC_DLKM: return "PARISC_DLKM";
default:
break;
}
else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
else
- sprintf (buff, _("<unknown>: %x"), sh_type);
+ snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
return buff;
}
#define OPTION_DEBUG_DUMP 512
-struct option options[] =
+static struct option options[] =
{
{"all", no_argument, 0, 'a'},
{"file-header", no_argument, 0, 'h'},
{"sections", no_argument, 0, 'S'},
{"section-headers", no_argument, 0, 'S'},
{"section-groups", no_argument, 0, 'g'},
+ {"section-details", no_argument, 0, 't'},
+ {"full-section-name",no_argument, 0, 'N'},
{"symbols", no_argument, 0, 's'},
{"syms", no_argument, 0, 's'},
{"relocs", no_argument, 0, 'r'},
-S --section-headers Display the sections' header\n\
--sections An alias for --section-headers\n\
-g --section-groups Display the section groups\n\
+ -t --section-details Display the section details\n\
-e --headers Equivalent to: -h -l -S\n\
-s --syms Display the symbol table\n\
--symbols An alias for --syms\n\
usage ();
while ((c = getopt_long
- (argc, argv, "ersuahnldSDAIgw::x:i:vVWH", options, NULL)) != EOF)
+ (argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF)
{
char *cp;
int section;
case 'g':
do_section_groups++;
break;
+ case 't':
+ case 'N':
+ do_sections++;
+ do_section_details++;
+ break;
case 'e':
do_header++;
do_sections++;
case ELFCLASS32: return "ELF32";
case ELFCLASS64: return "ELF64";
default:
- sprintf (buff, _("<unknown: %x>"), elf_class);
+ snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
return buff;
}
}
case ELFDATA2LSB: return _("2's complement, little endian");
case ELFDATA2MSB: return _("2's complement, big endian");
default:
- sprintf (buff, _("<unknown: %x>"), encoding);
+ snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
return buff;
}
}
unsigned int i;
phdrs = get_data (NULL, file, elf_header.e_phoff,
- elf_header.e_phentsize * elf_header.e_phnum,
+ elf_header.e_phentsize, elf_header.e_phnum,
_("program headers"));
if (!phdrs)
return 0;
unsigned int i;
phdrs = get_data (NULL, file, elf_header.e_phoff,
- elf_header.e_phentsize * elf_header.e_phnum,
+ elf_header.e_phentsize, elf_header.e_phnum,
_("program headers"));
if (!phdrs)
return 0;
if (program_headers != NULL)
return 1;
- phdrs = malloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+ phdrs = cmalloc (elf_header.e_phnum, sizeof (Elf_Internal_Phdr));
if (phdrs == NULL)
{
putc ('\n', stdout);
}
- if (do_segments && section_headers != NULL)
+ if (do_segments && section_headers != NULL && string_table != NULL)
{
printf (_("\n Section to Segment mapping:\n"));
printf (_(" Segment Sections...\n"));
- assert (string_table != NULL);
-
for (i = 0; i < elf_header.e_phnum; i++)
{
unsigned int j;
unsigned int i;
shdrs = get_data (NULL, file, elf_header.e_shoff,
- elf_header.e_shentsize * num, _("section headers"));
+ elf_header.e_shentsize, num, _("section headers"));
if (!shdrs)
return 0;
- section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
+ section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
if (section_headers == NULL)
{
unsigned int i;
shdrs = get_data (NULL, file, elf_header.e_shoff,
- elf_header.e_shentsize * num, _("section headers"));
+ elf_header.e_shentsize, num, _("section headers"));
if (!shdrs)
return 0;
- section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
+ section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
if (section_headers == NULL)
{
Elf_Internal_Sym *psym;
unsigned int j;
- esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
+ esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
_("symbols"));
if (!esyms)
return NULL;
== (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
{
shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
- symtab_shndx_hdr->sh_size, _("symtab shndx"));
+ 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
if (!shndx)
{
free (esyms);
}
number = section->sh_size / section->sh_entsize;
- isyms = malloc (number * sizeof (Elf_Internal_Sym));
+ isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
if (isyms == NULL)
{
Elf_Internal_Sym *psym;
unsigned int j;
- esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
+ esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
_("symbols"));
if (!esyms)
return NULL;
== (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
{
shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
- symtab_shndx_hdr->sh_size, _("symtab shndx"));
+ 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
if (!shndx)
{
free (esyms);
}
number = section->sh_size / section->sh_entsize;
- isyms = malloc (number * sizeof (Elf_Internal_Sym));
+ isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
if (isyms == NULL)
{
static const char *
get_elf_section_flags (bfd_vma sh_flags)
{
- static char buff[32];
+ static char buff[1024];
+ char *p = buff;
+ int index, size = sizeof (buff) - (8 + 4 + 1);
+ const struct
+ {
+ const char *str;
+ int len;
+ }
+ flags [] =
+ {
+ { "WRITE", 5 },
+ { "ALLOC", 5 },
+ { "EXEC", 4 },
+ { "MERGE", 5 },
+ { "STRINGS", 7 },
+ { "INFO LINK", 9 },
+ { "LINK ORDER", 10 },
+ { "OS NONCONF", 10 },
+ { "GROUP", 5 },
+ { "TLS", 3 }
+ };
- *buff = 0;
+ if (do_section_details)
+ {
+ sprintf (buff, "[%8.8lx]: ", (unsigned long) sh_flags);
+ p += 8 + 4;
+ }
while (sh_flags)
{
flag = sh_flags & - sh_flags;
sh_flags &= ~ flag;
- switch (flag)
+ if (do_section_details)
{
- case SHF_WRITE: strcat (buff, "W"); break;
- case SHF_ALLOC: strcat (buff, "A"); break;
- case SHF_EXECINSTR: strcat (buff, "X"); break;
- case SHF_MERGE: strcat (buff, "M"); break;
- case SHF_STRINGS: strcat (buff, "S"); break;
- case SHF_INFO_LINK: strcat (buff, "I"); break;
- case SHF_LINK_ORDER: strcat (buff, "L"); break;
- case SHF_OS_NONCONFORMING: strcat (buff, "O"); break;
- case SHF_GROUP: strcat (buff, "G"); break;
- case SHF_TLS: strcat (buff, "T"); break;
+ switch (flag)
+ {
+ case SHF_WRITE: index = 0; break;
+ case SHF_ALLOC: index = 1; break;
+ case SHF_EXECINSTR: index = 2; break;
+ case SHF_MERGE: index = 3; break;
+ case SHF_STRINGS: index = 4; break;
+ case SHF_INFO_LINK: index = 5; break;
+ case SHF_LINK_ORDER: index = 6; break;
+ case SHF_OS_NONCONFORMING: index = 7; break;
+ case SHF_GROUP: index = 8; break;
+ case SHF_TLS: index = 9; break;
- default:
- if (flag & SHF_MASKOS)
+ default:
+ index = -1;
+ break;
+ }
+
+ if (p != buff + 8 + 4)
{
- strcat (buff, "o");
- sh_flags &= ~ SHF_MASKOS;
+ if (size < 10 + 2)
+ abort ();
+ size -= 2;
+ *p++ = ',';
+ *p++ = ' ';
+ }
+
+ if (index != -1)
+ {
+ size -= flags [index].len;
+ p = stpcpy (p, flags [index].str);
+ }
+ else if (flag & SHF_MASKOS)
+ {
+ size -= 5 + 8;
+ sprintf (p, "OS (%8.8lx)", (unsigned long) flag);
+ p += 5 + 8;
}
else if (flag & SHF_MASKPROC)
{
- strcat (buff, "p");
- sh_flags &= ~ SHF_MASKPROC;
+ size -= 7 + 8;
+ sprintf (p, "PROC (%8.8lx)", (unsigned long) flag);
+ p += 7 + 8;
}
else
- strcat (buff, "x");
- break;
+ {
+ size -= 10 + 8;
+ sprintf (p, "UNKNOWN (%8.8lx)", (unsigned long) flag);
+ p += 10 + 8;
+ }
+ }
+ else
+ {
+ switch (flag)
+ {
+ case SHF_WRITE: *p = 'W'; break;
+ case SHF_ALLOC: *p = 'A'; break;
+ case SHF_EXECINSTR: *p = 'X'; break;
+ case SHF_MERGE: *p = 'M'; break;
+ case SHF_STRINGS: *p = 'S'; break;
+ case SHF_INFO_LINK: *p = 'I'; break;
+ case SHF_LINK_ORDER: *p = 'L'; break;
+ case SHF_OS_NONCONFORMING: *p = 'O'; break;
+ case SHF_GROUP: *p = 'G'; break;
+ case SHF_TLS: *p = 'T'; break;
+
+ default:
+ if (elf_header.e_machine == EM_X86_64
+ && flag == SHF_X86_64_LARGE)
+ *p = 'l';
+ else if (flag & SHF_MASKOS)
+ {
+ *p = 'o';
+ sh_flags &= ~ SHF_MASKOS;
+ }
+ else if (flag & SHF_MASKPROC)
+ {
+ *p = 'p';
+ sh_flags &= ~ SHF_MASKPROC;
+ }
+ else
+ *p = 'x';
+ break;
+ }
+ p++;
}
}
+ *p = '\0';
return buff;
}
return 0;
/* Read in the string table, so that we have names to display. */
- section = SECTION_HEADER (elf_header.e_shstrndx);
-
- if (section->sh_size != 0)
+ if (SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum)
{
- string_table = get_data (NULL, file, section->sh_offset,
- section->sh_size, _("string table"));
+ section = SECTION_HEADER (elf_header.e_shstrndx);
- if (string_table == NULL)
- return 0;
+ if (section->sh_size != 0)
+ {
+ string_table = get_data (NULL, file, section->sh_offset,
+ 1, section->sh_size, _("string table"));
- string_table_length = section->sh_size;
+ string_table_length = string_table != NULL ? section->sh_size : 0;
+ }
}
/* Scan the sections for the dynamic symbol table
break;
}
+#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
+ do \
+ { \
+ size_t expected_entsize \
+ = is_32bit_elf ? size32 : size64; \
+ if (section->sh_entsize != expected_entsize) \
+ error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
+ i, (unsigned long int) section->sh_entsize, \
+ (unsigned long int) expected_entsize); \
+ section->sh_entsize = expected_entsize; \
+ } \
+ while (0)
+#define CHECK_ENTSIZE(section, i, type) \
+ CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
+ sizeof (Elf64_External_##type))
+
for (i = 0, section = section_headers;
i < elf_header.e_shnum;
i++, section++)
continue;
}
+ CHECK_ENTSIZE (section, i, Sym);
num_dynamic_syms = section->sh_size / section->sh_entsize;
dynamic_symbols = GET_ELF_SYMBOLS (file, section);
}
}
dynamic_strings = get_data (NULL, file, section->sh_offset,
- section->sh_size, _("dynamic strings"));
+ 1, section->sh_size, _("dynamic strings"));
dynamic_strings_length = section->sh_size;
}
else if (section->sh_type == SHT_SYMTAB_SHNDX)
}
symtab_shndx_hdr = section;
}
+ else if (section->sh_type == SHT_SYMTAB)
+ CHECK_ENTSIZE (section, i, Sym);
+ else if (section->sh_type == SHT_GROUP)
+ CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
+ else if (section->sh_type == SHT_REL)
+ CHECK_ENTSIZE (section, i, Rel);
+ else if (section->sh_type == SHT_RELA)
+ CHECK_ENTSIZE (section, i, Rela);
else if ((do_debugging || do_debug_info || do_debug_abbrevs
|| do_debug_lines || do_debug_pubnames || do_debug_aranges
|| do_debug_frames || do_debug_macinfo || do_debug_str
printf (_("\nSection Header:\n"));
if (is_32bit_elf)
- printf
- (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
+ {
+ if (do_section_details)
+ {
+ printf (_(" [Nr] Name\n"));
+ printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
+ }
+ else
+ printf
+ (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
+ }
else if (do_wide)
- printf
- (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
+ {
+ if (do_section_details)
+ {
+ printf (_(" [Nr] Name\n"));
+ printf (_(" Type Address Off Size ES Lk Inf Al\n"));
+ }
+ else
+ printf
+ (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
+ }
else
{
- printf (_(" [Nr] Name Type Address Offset\n"));
- printf (_(" Size EntSize Flags Link Info Align\n"));
+ if (do_section_details)
+ {
+ printf (_(" [Nr] Name\n"));
+ printf (_(" Type Address Offset Link\n"));
+ printf (_(" Size EntSize Info Align\n"));
+ }
+ else
+ {
+ printf (_(" [Nr] Name Type Address Offset\n"));
+ printf (_(" Size EntSize Flags Link Info Align\n"));
+ }
}
+ if (do_section_details)
+ printf (_(" Flags\n"));
+
for (i = 0, section = section_headers;
i < elf_header.e_shnum;
i++, section++)
{
- printf (" [%2u] %-17.17s %-15.15s ",
- SECTION_HEADER_NUM (i),
- SECTION_NAME (section),
- get_section_type_name (section->sh_type));
+ if (do_section_details)
+ {
+ printf (" [%2u] %s\n",
+ SECTION_HEADER_NUM (i),
+ SECTION_NAME (section));
+ if (is_32bit_elf || do_wide)
+ printf (" %-15.15s ",
+ get_section_type_name (section->sh_type));
+ }
+ else
+ printf (" [%2u] %-17.17s %-15.15s ",
+ SECTION_HEADER_NUM (i),
+ SECTION_NAME (section),
+ get_section_type_name (section->sh_type));
if (is_32bit_elf)
{
(unsigned long) section->sh_size,
(unsigned long) section->sh_entsize);
- printf (" %3s ", get_elf_section_flags (section->sh_flags));
+ if (do_section_details)
+ fputs (" ", stdout);
+ else
+ printf (" %3s ", get_elf_section_flags (section->sh_flags));
printf ("%2ld %3lu %2ld\n",
(unsigned long) section->sh_link,
print_vma (section->sh_entsize, LONG_HEX);
}
- printf (" %3s ", get_elf_section_flags (section->sh_flags));
+ if (do_section_details)
+ fputs (" ", stdout);
+ else
+ printf (" %3s ", get_elf_section_flags (section->sh_flags));
printf ("%2ld %3lu ",
(unsigned long) section->sh_link,
putchar ('\n');
}
}
+ else if (do_section_details)
+ {
+ printf (" %-15.15s ",
+ get_section_type_name (section->sh_type));
+ print_vma (section->sh_addr, LONG_HEX);
+ if ((long) section->sh_offset == section->sh_offset)
+ printf (" %16.16lx", (unsigned long) section->sh_offset);
+ else
+ {
+ printf (" ");
+ print_vma (section->sh_offset, LONG_HEX);
+ }
+ printf (" %ld\n ", (unsigned long) section->sh_link);
+ print_vma (section->sh_size, LONG_HEX);
+ putchar (' ');
+ print_vma (section->sh_entsize, LONG_HEX);
+
+ printf (" %-16lu %ld\n",
+ (unsigned long) section->sh_info,
+ (unsigned long) section->sh_addralign);
+ }
else
{
putchar (' ');
(unsigned long) section->sh_info,
(unsigned long) section->sh_addralign);
}
+
+ if (do_section_details)
+ printf (" %s\n", get_elf_section_flags (section->sh_flags));
}
- printf (_("Key to Flags:\n\
+ if (!do_section_details)
+ printf (_("Key to Flags:\n\
W (write), A (alloc), X (execute), M (merge), S (strings)\n\
I (info), L (link order), G (group), x (unknown)\n\
O (extra OS processing required) o (OS specific), p (processor specific)\n"));
return "COMDAT";
default:
- sprintf (buff, _("[<unknown>: 0x%x]"), flags);
+ snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
break;
}
return buff;
Elf_Internal_Shdr *symtab_sec, *strtab_sec;
Elf_Internal_Sym *symtab;
char *strtab;
+ size_t strtab_size;
/* Don't process section groups unless needed. */
if (!do_unwind && !do_section_groups)
strtab_sec = NULL;
symtab = NULL;
strtab = NULL;
+ strtab_size = 0;
for (i = 0, section = section_headers, group = section_groups;
i < elf_header.e_shnum;
i++, section++)
Elf_Internal_Sym *sym;
/* Get the symbol table. */
- sec = SECTION_HEADER (section->sh_link);
- if (sec->sh_type != SHT_SYMTAB)
+ if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum
+ || ((sec = SECTION_HEADER (section->sh_link))->sh_type
+ != SHT_SYMTAB))
{
error (_("Bad sh_link in group section `%s'\n"), name);
continue;
}
group_name = SECTION_NAME (section_headers + sec_index);
+ strtab_sec = NULL;
+ if (strtab)
+ free (strtab);
strtab = NULL;
+ strtab_size = 0;
}
else
{
/* Get the string table. */
- sec = SECTION_HEADER (symtab_sec->sh_link);
- if (strtab_sec != sec)
+ if (SECTION_HEADER_INDEX (symtab_sec->sh_link)
+ >= elf_header.e_shnum)
+ {
+ strtab_sec = NULL;
+ if (strtab)
+ free (strtab);
+ strtab = NULL;
+ strtab_size = 0;
+ }
+ else if (strtab_sec
+ != (sec = SECTION_HEADER (symtab_sec->sh_link)))
{
strtab_sec = sec;
if (strtab)
free (strtab);
strtab = get_data (NULL, file, strtab_sec->sh_offset,
- strtab_sec->sh_size,
+ 1, strtab_sec->sh_size,
_("string table"));
+ strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
}
- group_name = strtab + sym->st_name;
+ group_name = sym->st_name < strtab_size
+ ? strtab + sym->st_name : "<corrupt>";
}
start = get_data (NULL, file, section->sh_offset,
- section->sh_size, _("section data"));
+ 1, section->sh_size, _("section data"));
indices = start;
size = (section->sh_size / section->sh_entsize) - 1;
if (do_section_groups)
{
- printf ("\n%s group section `%s' [%s] contains %u sections:\n",
- get_group_flags (entry), name, group_name, size);
+ printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
+ get_group_flags (entry), i, name, group_name, size);
printf (_(" [Index] Name\n"));
}
entry = byte_get (indices, 4);
indices += 4;
+ if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum)
+ {
+ error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
+ entry, i, elf_header.e_shnum - 1);
+ continue;
+ }
+ else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE)
+ {
+ error (_("invalid section [%5u] in group section [%5u]\n"),
+ entry, i);
+ continue;
+ }
+
if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
!= NULL)
{
if (entry)
{
- error (_("section [%5u] already in group section [%5u]\n"),
- entry,
+ error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
+ entry, i,
section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
continue;
}
if (do_section_groups)
{
sec = SECTION_HEADER (entry);
- printf (" [%5u] %s\n",
- entry, SECTION_NAME (sec));
+ printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
}
g = xmalloc (sizeof (struct group_list));
return 1;
}
-struct
+static struct
{
const char *name;
int reloc;
is_rela = section->sh_type == SHT_RELA;
- if (section->sh_link)
+ if (section->sh_link
+ && SECTION_HEADER_INDEX (section->sh_link)
+ < elf_header.e_shnum)
{
Elf_Internal_Shdr *symsec;
Elf_Internal_Sym *symtab;
unsigned long nsyms;
- unsigned long strtablen;
+ unsigned long strtablen = 0;
char *strtab = NULL;
symsec = SECTION_HEADER (section->sh_link);
+ if (symsec->sh_type != SHT_SYMTAB
+ && symsec->sh_type != SHT_DYNSYM)
+ continue;
+
nsyms = symsec->sh_size / symsec->sh_entsize;
symtab = GET_ELF_SYMBOLS (file, symsec);
if (symtab == NULL)
continue;
- strsec = SECTION_HEADER (symsec->sh_link);
+ if (SECTION_HEADER_INDEX (symsec->sh_link)
+ < elf_header.e_shnum)
+ {
+ strsec = SECTION_HEADER (symsec->sh_link);
- strtab = get_data (NULL, file, strsec->sh_offset,
- strsec->sh_size, _("string table"));
- strtablen = strtab == NULL ? 0 : strsec->sh_size;
+ strtab = get_data (NULL, file, strsec->sh_offset,
+ 1, strsec->sh_size,
+ _("string table"));
+ strtablen = strtab == NULL ? 0 : strsec->sh_size;
+ }
dump_relocations (file, rel_offset, rel_size,
symtab, nsyms, strtab, strtablen, is_rela);
(unsigned long) (tp->info.offset - aux->seg_base));
head = aux->info + (tp->info.offset - aux->info_addr);
- stamp = BYTE_GET ((unsigned char *) head);
+ stamp = byte_get ((unsigned char *) head, sizeof (stamp));
printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
(unsigned) UNW_VER (stamp),
/* Second, build the unwind table from the contents of the unwind section: */
size = sec->sh_size;
- table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
+ table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
if (!table)
return 0;
- aux->table = xmalloc (size / (3 * eh_addr_size) * sizeof (aux->table[0]));
+ aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
tep = aux->table;
for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
{
++relsec)
{
if (relsec->sh_type != SHT_RELA
+ || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|| SECTION_HEADER (relsec->sh_info) != sec)
continue;
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
{
- if (sec->sh_type == SHT_SYMTAB)
+ if (sec->sh_type == SHT_SYMTAB
+ && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
{
aux.nsyms = sec->sh_size / sec->sh_entsize;
aux.symtab = GET_ELF_SYMBOLS (file, sec);
strsec = SECTION_HEADER (sec->sh_link);
- aux.strtab_size = strsec->sh_size;
aux.strtab = get_data (NULL, file, strsec->sh_offset,
- aux.strtab_size, _("string table"));
+ 1, strsec->sh_size, _("string table"));
+ aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
}
else if (sec->sh_type == SHT_IA_64_UNWIND)
unwcount++;
{
aux.info_size = sec->sh_size;
aux.info_addr = sec->sh_addr;
- aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size,
+ aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
_("unwind info"));
printf (_("\nUnwind section "));
struct hppa_unw_aux_info *aux,
Elf_Internal_Shdr *sec)
{
- unsigned long size, unw_ent_size, nrelas, i;
+ unsigned long size, unw_ent_size, nentries, nrelas, i;
Elf_Internal_Phdr *seg;
struct hppa_unw_table_entry *tep;
Elf_Internal_Shdr *relsec;
/* Second, build the unwind table from the contents of the unwind
section. */
size = sec->sh_size;
- table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
+ table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
if (!table)
return 0;
- unw_ent_size = 2 * eh_addr_size + 8;
+ unw_ent_size = 16;
+ nentries = size / unw_ent_size;
+ size = unw_ent_size * nentries;
- tep = aux->table = xmalloc (size / unw_ent_size * sizeof (aux->table[0]));
+ tep = aux->table = xcmalloc (nentries, sizeof (aux->table[0]));
- for (tp = table; tp < table + size; tp += (2 * eh_addr_size + 8), ++tep)
+ for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
{
unsigned int tmp1, tmp2;
tep->start.section = SHN_UNDEF;
tep->end.section = SHN_UNDEF;
- if (is_32bit_elf)
- {
- tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
- tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
- tmp1 = byte_get ((unsigned char *) tp + 8, 4);
- tmp2 = byte_get ((unsigned char *) tp + 12, 4);
- }
- else
- {
- tep->start.offset = BYTE_GET ((unsigned char *) tp + 0);
- tep->end.offset = BYTE_GET ((unsigned char *) tp + 8);
- tmp1 = byte_get ((unsigned char *) tp + 16, 4);
- tmp2 = byte_get ((unsigned char *) tp + 20, 4);
- }
+ tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
+ tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
+ tmp1 = byte_get ((unsigned char *) tp + 8, 4);
+ tmp2 = byte_get ((unsigned char *) tp + 12, 4);
+
+ tep->start.offset += aux->seg_base;
+ tep->end.offset += aux->seg_base;
tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
tep->Millicode = (tmp1 >> 30) & 0x1;
tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
tep->reserved4 = (tmp2 >> 27) & 0x1;
tep->Total_frame_size = tmp2 & 0x7ffffff;
-
- tep->start.offset += aux->seg_base;
- tep->end.offset += aux->seg_base;
}
free (table);
++relsec)
{
if (relsec->sh_type != SHT_RELA
+ || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|| SECTION_HEADER (relsec->sh_info) != sec)
continue;
free (rela);
}
- aux->table_len = size / unw_ent_size;
+ aux->table_len = nentries;
return 1;
}
memset (& aux, 0, sizeof (aux));
- assert (string_table != NULL);
+ if (string_table == NULL)
+ return 1;
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
{
- if (sec->sh_type == SHT_SYMTAB)
+ if (sec->sh_type == SHT_SYMTAB
+ && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
{
aux.nsyms = sec->sh_size / sec->sh_entsize;
aux.symtab = GET_ELF_SYMBOLS (file, sec);
strsec = SECTION_HEADER (sec->sh_link);
- aux.strtab_size = strsec->sh_size;
aux.strtab = get_data (NULL, file, strsec->sh_offset,
- aux.strtab_size, _("string table"));
+ 1, strsec->sh_size, _("string table"));
+ aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
}
else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
unwsec = sec;
time_t time = entry->d_un.d_val;
tmp = gmtime (&time);
- sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
- tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
- tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+ snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
+ tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
printf ("Time Stamp: %s\n", timebuf);
}
break;
{ DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
{ DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
{ DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
- { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
+ { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
+ { DT_HP_GST, "HP_GST" },
+ { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
+ { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
+ { DT_HP_NODELETE, "HP_NODELETE" },
+ { DT_HP_GROUP, "HP_GROUP" },
+ { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
};
int first = 1;
size_t cnt;
Elf32_External_Dyn *edyn, *ext;
Elf_Internal_Dyn *entry;
- edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
+ edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
_("dynamic section"));
if (!edyn)
return 0;
break;
}
- dynamic_section = malloc (dynamic_nent * sizeof (*entry));
+ dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
if (dynamic_section == NULL)
{
error (_("Out of memory\n"));
Elf64_External_Dyn *edyn, *ext;
Elf_Internal_Dyn *entry;
- edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
+ edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
_("dynamic section"));
if (!edyn)
return 0;
break;
}
- dynamic_section = malloc (dynamic_nent * sizeof (*entry));
+ dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
if (dynamic_section == NULL)
{
error (_("Out of memory\n"));
return 1;
}
-static const char *
-get_dynamic_flags (bfd_vma flags)
+static void
+print_dynamic_flags (bfd_vma flags)
{
- static char buff[128];
- char *p = buff;
+ int first = 1;
- *p = '\0';
while (flags)
{
bfd_vma flag;
flag = flags & - flags;
flags &= ~ flag;
- if (p != buff)
- *p++ = ' ';
+ if (first)
+ first = 0;
+ else
+ putc (' ', stdout);
switch (flag)
{
- case DF_ORIGIN: strcpy (p, "ORIGIN"); break;
- case DF_SYMBOLIC: strcpy (p, "SYMBOLIC"); break;
- case DF_TEXTREL: strcpy (p, "TEXTREL"); break;
- case DF_BIND_NOW: strcpy (p, "BIND_NOW"); break;
- case DF_STATIC_TLS: strcpy (p, "STATIC_TLS"); break;
- default: strcpy (p, "unknown"); break;
+ case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
+ case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
+ case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
+ case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
+ case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
+ default: fputs ("unknown", stdout); break;
}
-
- p = strchr (p, '\0');
}
- return buff;
+ puts ("");
}
/* Parse and display the contents of the dynamic section. */
continue;
}
- dynamic_strings = get_data (NULL, file, offset, str_tab_len,
+ dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
_("dynamic string table"));
dynamic_strings_length = str_tab_len;
break;
Elf_Internal_Syminfo *syminfo;
/* There is a syminfo section. Read the data. */
- extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz,
- _("symbol information"));
+ extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
+ syminsz, _("symbol information"));
if (!extsyminfo)
return 0;
{
case DT_FLAGS:
if (do_dynamic)
- puts (get_dynamic_flags (entry->d_un.d_val));
+ print_dynamic_flags (entry->d_un.d_val);
break;
case DT_AUXILIARY:
printf_vma (section->sh_addr);
printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
(unsigned long) section->sh_offset, section->sh_link,
- SECTION_NAME (SECTION_HEADER (section->sh_link)));
+ SECTION_HEADER_INDEX (section->sh_link)
+ < elf_header.e_shnum
+ ? SECTION_NAME (SECTION_HEADER (section->sh_link))
+ : "<corrupt>");
- edefs = get_data (NULL, file, section->sh_offset, section->sh_size,
+ edefs = get_data (NULL, file, section->sh_offset, 1,
+ section->sh_size,
_("version definition section"));
if (!edefs)
break;
printf_vma (section->sh_addr);
printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
(unsigned long) section->sh_offset, section->sh_link,
- SECTION_NAME (SECTION_HEADER (section->sh_link)));
+ SECTION_HEADER_INDEX (section->sh_link)
+ < elf_header.e_shnum
+ ? SECTION_NAME (SECTION_HEADER (section->sh_link))
+ : "<corrupt>");
- eneed = get_data (NULL, file, section->sh_offset, section->sh_size,
+ eneed = get_data (NULL, file, section->sh_offset, 1,
+ section->sh_size,
_("version need section"));
if (!eneed)
break;
Elf_Internal_Shdr *string_sec;
long off;
+ if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
+ break;
+
link_section = SECTION_HEADER (section->sh_link);
- total = section->sh_size / section->sh_entsize;
+ total = section->sh_size / sizeof (Elf_External_Versym);
+
+ if (SECTION_HEADER_INDEX (link_section->sh_link)
+ >= elf_header.e_shnum)
+ break;
found = 1;
string_sec = SECTION_HEADER (link_section->sh_link);
- strtab = get_data (NULL, file, string_sec->sh_offset,
+ strtab = get_data (NULL, file, string_sec->sh_offset, 1,
string_sec->sh_size, _("version string table"));
if (!strtab)
break;
off = offset_from_vma (file,
version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
total * sizeof (short));
- edata = get_data (NULL, file, off, total * sizeof (short),
+ edata = get_data (NULL, file, off, total, sizeof (short),
_("version symbol data"));
if (!edata)
{
break;
}
- data = malloc (total * sizeof (short));
+ data = cmalloc (total, sizeof (short));
for (cnt = total; cnt --;)
data[cnt] = byte_get (edata + cnt * sizeof (short),
check_def = 1;
check_need = 1;
- if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
- != SHT_NOBITS)
+ if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx)
+ >= elf_header.e_shnum
+ || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
+ != SHT_NOBITS)
{
if (symbols[cnt + j].st_shndx == SHN_UNDEF)
check_def = 0;
Elf_External_Vernaux evna;
unsigned long a_off;
- get_data (&evn, file, offset, sizeof (evn),
+ get_data (&evn, file, offset, sizeof (evn), 1,
_("version need"));
ivn.vn_aux = BYTE_GET (evn.vn_aux);
do
{
get_data (&evna, file, a_off, sizeof (evna),
- _("version need aux (2)"));
+ 1, _("version need aux (2)"));
ivna.vna_next = BYTE_GET (evna.vna_next);
ivna.vna_other = BYTE_GET (evna.vna_other);
do
{
- get_data (&evd, file, offset, sizeof (evd),
+ get_data (&evd, file, offset, sizeof (evd), 1,
_("version def"));
ivd.vd_next = BYTE_GET (evd.vd_next);
get_data (&evda, file,
offset - ivd.vd_next + ivd.vd_aux,
- sizeof (evda), _("version def aux"));
+ sizeof (evda), 1,
+ _("version def aux"));
ivda.vda_name = BYTE_GET (evda.vda_name);
case STB_WEAK: return "WEAK";
default:
if (binding >= STB_LOPROC && binding <= STB_HIPROC)
- sprintf (buff, _("<processor specific>: %d"), binding);
+ snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
+ binding);
else if (binding >= STB_LOOS && binding <= STB_HIOS)
- sprintf (buff, _("<OS specific>: %d"), binding);
+ snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
else
- sprintf (buff, _("<unknown>: %d"), binding);
+ snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
return buff;
}
}
if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
return "PARISC_MILLI";
- sprintf (buff, _("<processor specific>: %d"), type);
+ snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
}
else if (type >= STT_LOOS && type <= STT_HIOS)
{
return "HP_STUB";
}
- sprintf (buff, _("<OS specific>: %d"), type);
+ snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
}
else
- sprintf (buff, _("<unknown>: %d"), type);
+ snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
return buff;
}
}
&& elf_header.e_machine == EM_IA_64
&& elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
return "ANSI_COM";
+ else if (elf_header.e_machine == EM_X86_64
+ && type == SHN_X86_64_LCOMMON)
+ return "LARGE_COM";
else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
sprintf (buff, "PRC[0x%04x]", type);
else if (type >= SHN_LOOS && type <= SHN_HIOS)
unsigned char *e_data;
bfd_vma *i_data;
- e_data = malloc (number * ent_size);
+ e_data = cmalloc (number, ent_size);
if (e_data == NULL)
{
return NULL;
}
- i_data = malloc (number * sizeof (*i_data));
+ i_data = cmalloc (number, sizeof (*i_data));
if (i_data == NULL)
{
i++, section++)
{
unsigned int si;
- char *strtab;
+ char *strtab = NULL;
+ unsigned long int strtab_size = 0;
Elf_Internal_Sym *symtab;
Elf_Internal_Sym *psym;
continue;
if (section->sh_link == elf_header.e_shstrndx)
- strtab = string_table;
- else
+ {
+ strtab = string_table;
+ strtab_size = string_table_length;
+ }
+ else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum)
{
Elf_Internal_Shdr *string_sec;
string_sec = SECTION_HEADER (section->sh_link);
strtab = get_data (NULL, file, string_sec->sh_offset,
- string_sec->sh_size, _("string table"));
+ 1, string_sec->sh_size, _("string table"));
+ strtab_size = strtab != NULL ? string_sec->sh_size : 0;
}
for (si = 0, psym = symtab;
printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
printf (" %4s ", get_symbol_index_type (psym->st_shndx));
- print_symbol (25, strtab + psym->st_name);
+ print_symbol (25, psym->st_name < strtab_size
+ ? strtab + psym->st_name : "<corrupt>");
if (section->sh_type == SHT_DYNSYM &&
version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
sizeof data + si * sizeof (vers_data));
get_data (&data, file, offset + si * sizeof (vers_data),
- sizeof (data), _("version data"));
+ sizeof (data), 1, _("version data"));
vers_data = byte_get (data, 2);
- is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
- == SHT_NOBITS);
+ is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx)
+ < elf_header.e_shnum
+ && SECTION_HEADER (psym->st_shndx)->sh_type
+ == SHT_NOBITS);
check_def = (psym->st_shndx != SHN_UNDEF);
{
unsigned long vna_off;
- get_data (&evn, file, offset, sizeof (evn),
+ get_data (&evn, file, offset, sizeof (evn), 1,
_("version need"));
ivn.vn_aux = BYTE_GET (evn.vn_aux);
Elf_External_Vernaux evna;
get_data (&evna, file, vna_off,
- sizeof (evna),
+ sizeof (evna), 1,
_("version need aux (3)"));
ivna.vna_other = BYTE_GET (evna.vna_other);
if (ivna.vna_other == vers_data)
{
printf ("@%s (%d)",
- strtab + ivna.vna_name, ivna.vna_other);
+ ivna.vna_name < strtab_size
+ ? strtab + ivna.vna_name : "<corrupt>",
+ ivna.vna_other);
check_def = 0;
}
else if (! is_nobits)
Elf_External_Verdef evd;
get_data (&evd, file, offset, sizeof (evd),
- _("version def"));
+ 1, _("version def"));
ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
ivd.vd_aux = BYTE_GET (evd.vd_aux);
offset += ivd.vd_aux;
get_data (&evda, file, offset, sizeof (evda),
- _("version def aux"));
+ 1, _("version def aux"));
ivda.vda_name = BYTE_GET (evda.vda_name);
if (psym->st_name != ivda.vda_name)
printf ((vers_data & 0x8000)
? "@%s" : "@@%s",
- strtab + ivda.vda_name);
+ ivda.vda_name < strtab_size
+ ? strtab + ivda.vda_name : "<corrupt>");
}
}
}
addr = section->sh_addr;
- start = get_data (NULL, file, section->sh_offset, bytes, _("section data"));
+ start = get_data (NULL, file, section->sh_offset, 1, bytes,
+ _("section data"));
if (!start)
return 0;
state_machine_regs.last_file_entry = 0;
}
-/* Handled an extend line op. Returns true if this is the end
- of sequence. */
+/* Handled an extend line op.
+ Returns the number of bytes read. */
static int
process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
debug_str_size = sec->sh_size;
- debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+ debug_str_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
_("debug_str section data"));
}
return _("<no .debug_str section>");
if (offset > debug_str_size)
- return _("<offset is too big>");
+ {
+ warn (_("DW_FORM_strp offset too big: %lx\n"), offset);
+ return _("<offset is too big>");
+ }
return debug_str_contents + offset;
}
debug_loc_size = sec->sh_size;
- debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+ debug_loc_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
_("debug_loc section data"));
}
if (debug_range_contents != NULL)
return;
- /* Locate the .debug_str section. */
+ /* Locate the .debug_ranges section. */
sec = find_section (".debug_ranges");
if (sec == NULL)
return;
debug_range_size = sec->sh_size;
- debug_range_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+ debug_range_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
_("debug_range section data"));
}
Elf_Internal_Sym *sym;
if (relsec->sh_type != SHT_RELA
+ || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|| SECTION_HEADER (relsec->sh_info) != section
- || relsec->sh_size == 0)
+ || relsec->sh_size == 0
+ || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
continue;
if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
example of this see the _clz.o binary in libgcc.a. */
&& ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
{
- warn (_("%s: skipping unexpected symbol type %s in relocation in section .rela%s\n"),
+ warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
SECTION_NAME (section));
continue;
}
else
{
+ /* In MIPS little-endian objects, r_info isn't really a
+ 64-bit little-endian value: it has a 32-bit little-endian
+ symbol index followed by four individual byte fields.
+ Reorder INFO accordingly. */
+ if (elf_header.e_machine == EM_MIPS
+ && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
+ rp->r_info = (((rp->r_info & 0xffffffff) << 32)
+ | ((rp->r_info >> 56) & 0xff)
+ | ((rp->r_info >> 40) & 0xff00)
+ | ((rp->r_info >> 24) & 0xff0000)
+ | ((rp->r_info >> 8) & 0xff000000));
+
sym = symtab + ELF64_R_SYM (rp->r_info);
if (ELF64_R_SYM (rp->r_info) != 0
{
static char buffer[100];
- sprintf (buffer, _("Unknown TAG value: %lx"), tag);
+ snprintf (buffer, sizeof (buffer), _("Unknown TAG value: %lx"), tag);
return buffer;
}
}
{
static char buffer[100];
- sprintf (buffer, _("Unknown FORM value: %lx"), form);
+ snprintf (buffer, sizeof (buffer), _("Unknown FORM value: %lx"), form);
return buffer;
}
}
break;
default:
- warn (_("Unrecognized form: %d\n"), form);
+ warn (_("Unrecognized form: %lu\n"), form);
break;
}
{
max += 1024;
debug_info_p->loc_offsets
- = xrealloc (debug_info_p->loc_offsets,
- max * sizeof (*debug_info_p->loc_offsets));
+ = xcrealloc (debug_info_p->loc_offsets,
+ max, sizeof (*debug_info_p->loc_offsets));
debug_info_p->have_frame_base
- = xrealloc (debug_info_p->have_frame_base,
- max * sizeof (*debug_info_p->have_frame_base));
+ = xcrealloc (debug_info_p->have_frame_base,
+ max, sizeof (*debug_info_p->have_frame_base));
debug_info_p->max_loc_offsets = max;
}
debug_info_p->loc_offsets [num] = uvalue;
{
max += 1024;
debug_info_p->range_lists
- = xrealloc (debug_info_p->range_lists,
- max * sizeof (*debug_info_p->range_lists));
+ = xcrealloc (debug_info_p->range_lists,
+ max, sizeof (*debug_info_p->range_lists));
debug_info_p->max_range_lists = max;
}
debug_info_p->range_lists [num] = uvalue;
case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
/* DWARF 2.1 value. */
case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
+ case DW_ATE_decimal_float: printf ("(decimal float)"); break;
default:
if (uvalue >= DW_ATE_lo_user
&& uvalue <= DW_ATE_hi_user)
{
static char buffer[100];
- sprintf (buffer, _("Unknown AT value: %lx"), attribute);
+ snprintf (buffer, sizeof (buffer), _("Unknown AT value: %lx"),
+ attribute);
return buffer;
}
}
}
/* Then allocate an array to hold the information. */
- debug_information = malloc (num_units *
- sizeof (* debug_information));
+ debug_information = cmalloc (num_units,
+ sizeof (* debug_information));
if (debug_information == NULL)
{
error (_("Not enough memory for a debug info array of %u entries"),
if (!do_loc)
{
- printf (_(" Compilation Unit @ %lx:\n"), cu_offset);
+ printf (_(" Compilation Unit @ offset 0x%lx:\n"), cu_offset);
printf (_(" Length: %ld\n"), compunit.cu_length);
printf (_(" Version: %d\n"), compunit.cu_version);
printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
return 0;
}
- begin = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+ begin = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
_("debug_abbrev section data"));
if (!begin)
return 0;
}
/* Set num_debug_info_entries here so that it can be used to check if
- we need to proecess .debug_loc and .debug_ranges sections. */
+ we need to process .debug_loc and .debug_ranges sections. */
if ((do_loc || do_debug_loc || do_debug_ranges)
&& num_debug_info_entries == 0)
num_debug_info_entries = num_units;
if (section == NULL)
return 0;
- start = get_data (NULL, file, section->sh_offset, section->sh_size,
+ start = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
_("extracting information from .debug_info section"));
if (start == NULL)
return 0;
/* Get the pointer size from the comp unit associated
with this block of line number information. */
pointer_size = get_pointer_size_and_offset_of_comp_unit
- (comp_unit, ".debug_lines", NULL);
+ (comp_unit, ".debug_line", NULL);
comp_unit ++;
printf (_(" Length: %ld\n"), info.li_length);
printf (_(" Line Base: %d\n"), info.li_line_base);
printf (_(" Line Range: %d\n"), info.li_line_range);
printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
- printf (_(" (Pointer size: %u)\n"), pointer_size);
+ printf (_(" (Pointer size: %u)%s\n"),
+ pointer_size,
+ warned_about_missing_comp_units ? " [assumed]" : "" );
end_of_sequence = data + info.li_length + initial_length_size;
else switch (op_code)
{
case DW_LNS_extended_op:
+ if (pointer_size == 0)
+ {
+ warn (_("Extend line ops need a valid pointer size, guessing at 4\n"));
+ pointer_size = 4;
+ }
+
data += process_extended_line_op (data, info.li_default_is_stmt,
pointer_size);
break;
{
if (start < next)
warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
- start - section_begin, next - section_begin);
+ (long)(start - section_begin), (long)(next - section_begin));
else if (start > next)
warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
- start - section_begin, next - section_begin);
+ (long)(start - section_begin), (long)(next - section_begin));
}
start = next;
+ if (offset >= bytes)
+ {
+ warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"),
+ offset);
+ continue;
+ }
+
while (1)
{
+ if (start + 2 * pointer_size > section_end)
+ {
+ warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+ offset);
+ break;
+ }
+
begin = byte_get (start, pointer_size);
start += pointer_size;
end = byte_get (start, pointer_size);
if (begin == -1UL && end != -1UL)
{
base_address = end;
- printf (" %8.8lx %8.8lx %8.8lx (base address)\n",
+ printf (_(" %8.8lx %8.8lx %8.8lx (base address)\n"),
offset, begin, end);
continue;
}
+ if (start + 2 > section_end)
+ {
+ warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+ offset);
+ break;
+ }
+
length = byte_get (start, 2);
start += 2;
+ if (start + length > section_end)
+ {
+ warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+ offset);
+ break;
+ }
+
printf (" %8.8lx %8.8lx %8.8lx (",
offset, begin + base_address, end + base_address);
need_frame_base = decode_location_expression (start,
{
if (start < next)
warn (_("There is a hole [0x%lx - 0x%lx] in .debug_ranges section.\n"),
- start - section_begin, next - section_begin);
+ (long)(start - section_begin), (long)(next - section_begin));
else if (start > next)
warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_ranges section.\n"),
- start - section_begin, next - section_begin);
+ (long)(start - section_begin), (long)(next - section_begin));
}
start = next;
start += pointer_size;
if (begin == 0 && end == 0)
- break;
+ {
+ printf (_(" %8.8lx <End of list>\n"), offset);
+ break;
+ }
/* Check base address specifiers. */
if (begin == -1UL && end != -1UL)
putchar ('\n');
}
- fputs (_(" <End of list>\n"), stdout);
}
}
putchar ('\n');
return;
fc->ncols = reg + 1;
- fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
- fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
+ fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int));
+ fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
while (prev < fc->ncols)
{
if (!cie)
{
- warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
+ warn ("Invalid CIE pointer %08lx in FDE at %p\n",
cie_id, saved_start);
start = block_end;
fc->ncols = 0;
else
{
fc->ncols = cie->ncols;
- fc->col_type = xmalloc (fc->ncols * sizeof (short int));
- fc->col_offset = xmalloc (fc->ncols * sizeof (int));
+ fc->col_type = xcmalloc (fc->ncols, sizeof (short int));
+ fc->col_offset = xcmalloc (fc->ncols, sizeof (int));
memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
fc->augmentation = cie->augmentation;
printf (" DW_CFA_remember_state\n");
rs = xmalloc (sizeof (Frame_Chunk));
rs->ncols = fc->ncols;
- rs->col_type = xmalloc (rs->ncols * sizeof (short int));
- rs->col_offset = xmalloc (rs->ncols * sizeof (int));
+ rs->col_type = xcmalloc (rs->ncols, sizeof (short int));
+ rs->col_offset = xcmalloc (rs->ncols, sizeof (int));
memcpy (rs->col_type, fc->col_type, rs->ncols);
memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
rs->next = remembered_state;
case DW_CFA_def_cfa_sf:
fc->cfa_reg = LEB ();
fc->cfa_offset = SLEB ();
+ fc->cfa_offset = fc->cfa_offset * fc->data_factor;
fc->cfa_exp = 0;
if (! do_debug_frames_interp)
printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n",
case DW_CFA_def_cfa_offset_sf:
fc->cfa_offset = SLEB ();
+ fc->cfa_offset = fc->cfa_offset * fc->data_factor;
if (! do_debug_frames_interp)
printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
break;
/* A structure containing the name of a debug section
and a pointer to a function that can decode it. */
-struct
+static struct
{
const char *const name;
int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
{
unsigned char *start;
- start = get_data (NULL, file, section->sh_offset, length,
+ start = get_data (NULL, file, section->sh_offset, 1, length,
_("debug section data"));
if (start == NULL)
{
size_t cnt;
elib = get_data (NULL, file, liblist_offset,
- liblistno * sizeof (Elf32_External_Lib),
+ liblistno, sizeof (Elf32_External_Lib),
_("liblist"));
if (elib)
{
liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
tmp = gmtime (&time);
- sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
- tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
- tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+ snprintf (timebuf, sizeof (timebuf),
+ "%04u-%02u-%02uT%02u:%02u:%02u",
+ tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
printf ("%3lu: ", (unsigned long) cnt);
if (VALID_DYNAMIC_NAME (liblist.l_name))
while (sect->sh_type != SHT_MIPS_OPTIONS)
++sect;
- eopt = get_data (NULL, file, options_offset, sect->sh_size,
+ eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
_("options"));
if (eopt)
{
- iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
+ iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
if (iopt == NULL)
{
error (_("Out of memory"));
return 0;
}
- iconf = malloc (conflictsno * sizeof (*iconf));
+ iconf = cmalloc (conflictsno, sizeof (*iconf));
if (iconf == NULL)
{
error (_("Out of memory"));
Elf32_External_Conflict *econf32;
econf32 = get_data (NULL, file, conflicts_offset,
- conflictsno * sizeof (*econf32), _("conflict"));
+ conflictsno, sizeof (*econf32), _("conflict"));
if (!econf32)
return 0;
Elf64_External_Conflict *econf64;
econf64 = get_data (NULL, file, conflicts_offset,
- conflictsno * sizeof (*econf64), _("conflict"));
+ conflictsno, sizeof (*econf64), _("conflict"));
if (!econf64)
return 0;
Elf_Internal_Shdr *section, *string_sec;
Elf32_External_Lib *elib;
char *strtab;
+ size_t strtab_size;
size_t cnt;
unsigned i;
switch (section->sh_type)
{
case SHT_GNU_LIBLIST:
- elib = get_data (NULL, file, section->sh_offset, section->sh_size,
+ if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
+ break;
+
+ elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
_("liblist"));
if (elib == NULL)
break;
string_sec = SECTION_HEADER (section->sh_link);
- strtab = get_data (NULL, file, string_sec->sh_offset,
+ strtab = get_data (NULL, file, string_sec->sh_offset, 1,
string_sec->sh_size, _("liblist string table"));
+ strtab_size = string_sec->sh_size;
if (strtab == NULL
|| section->sh_entsize != sizeof (Elf32_External_Lib))
liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
tmp = gmtime (&time);
- sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
- tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
- tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+ snprintf (timebuf, sizeof (timebuf),
+ "%04u-%02u-%02uT%02u:%02u:%02u",
+ tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
printf ("%3lu: ", (unsigned long) cnt);
if (do_wide)
- printf ("%-20s", strtab + liblist.l_name);
+ printf ("%-20s", liblist.l_name < strtab_size
+ ? strtab + liblist.l_name : "<corrupt>");
else
- printf ("%-20.20s", strtab + liblist.l_name);
+ printf ("%-20.20s", liblist.l_name < strtab_size
+ ? strtab + liblist.l_name : "<corrupt>");
printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
liblist.l_version, liblist.l_flags);
}
break;
}
- sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
+ snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
return buff;
}
if (e_type < NT_NETBSDCORE_FIRSTMACH)
{
- sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
+ snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
return buff;
}
}
}
- sprintf (buff, _("PT_FIRSTMACH+%d"), e_type - NT_NETBSDCORE_FIRSTMACH);
+ snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
+ e_type - NT_NETBSDCORE_FIRSTMACH);
return buff;
}
if (length <= 0)
return 0;
- pnotes = get_data (NULL, file, offset, length, _("notes"));
+ pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
if (!pnotes)
return 0;
if (((char *) next) > (((char *) pnotes) + length))
{
- warn (_("corrupt note found at offset %x into core notes\n"),
- ((char *) external) - ((char *) pnotes));
- warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"),
+ warn (_("corrupt note found at offset %lx into core notes\n"),
+ (long)((char *)external - (char *)pnotes));
+ warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
inote.type, inote.namesz, inote.descsz);
break;
}
off = strtoul (arhdr.ar_name + 1, NULL, 10);
if (off >= longnames_size)
{
- error (_("%s: invalid archive string table offset %lu\n"), off);
+ error (_("%s: invalid archive string table offset %lu\n"), file_name, off);
ret = 1;
break;
}
if (nameend == NULL)
{
- error (_("%s: bad archive file name\n"));
+ error (_("%s: bad archive file name\n"), file_name);
ret = 1;
break;
}