/* readelf.c -- display contents of an ELF format file
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 99, 2000 Free Software Foundation, Inc.
Originally developed by Eric Youngdale <eric@andante.jic.com>
Modifications by Nick Clifton <nickc@cygnus.com>
static const char * get_mips_section_type_name PARAMS ((unsigned int));
static const char * get_parisc_section_type_name PARAMS ((unsigned int));
static const char * get_section_type_name PARAMS ((unsigned int));
-static char * get_symbol_binding PARAMS ((unsigned int));
-static char * get_symbol_type PARAMS ((unsigned int));
+static const char * get_symbol_binding PARAMS ((unsigned int));
+static const char * get_symbol_type PARAMS ((unsigned int));
+static const char * get_symbol_visibility PARAMS ((unsigned int));
+static const char * get_symbol_index_type PARAMS ((unsigned int));
+static const char * get_dynamic_flags PARAMS ((bfd_vma));
static void usage PARAMS ((void));
static void parse_args PARAMS ((int, char **));
static int process_file_header PARAMS ((void));
static int process_relocs PARAMS ((FILE *));
static int process_version_sections PARAMS ((FILE *));
static char * get_ver_flags PARAMS ((unsigned int));
-static char * get_symbol_index_type PARAMS ((unsigned int));
static int get_32bit_section_headers PARAMS ((FILE *));
static int get_64bit_section_headers PARAMS ((FILE *));
static int get_32bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));
break;
case DEC:
+#if BFD_HOST_64BIT_LONG
+ printf ("%ld", vma);
+#else
if (_bfd_int64_high (vma))
/* ugg */
printf ("++%ld", _bfd_int64_low (vma));
else
printf ("%ld", _bfd_int64_low (vma));
+#endif
break;
case DEC_5:
+#if BFD_HOST_64BIT_LONG
+ printf ("%5ld", vma);
+#else
if (_bfd_int64_high (vma))
/* ugg */
printf ("++%ld", _bfd_int64_low (vma));
else
printf ("%5ld", _bfd_int64_low (vma));
+#endif
break;
case UNSIGNED:
+#if BFD_HOST_64BIT_LONG
+ printf ("%lu", vma);
+#else
if (_bfd_int64_high (vma))
/* ugg */
printf ("++%lu", _bfd_int64_low (vma));
else
printf ("%lu", _bfd_int64_low (vma));
+#endif
break;
}
}
case EM_MCORE:
return TRUE;
+ case EM_MMA:
+ case EM_PCP:
+ case EM_NCPU:
+ case EM_NDR1:
+ case EM_STARCORE:
+ case EM_ME16:
+ case EM_ST100:
+ case EM_TINYJ:
+ case EM_FX66:
+ case EM_ST9PLUS:
+ case EM_ST7:
+ case EM_68HC16:
+ case EM_68HC11:
+ case EM_68HC08:
+ case EM_68HC05:
+ case EM_SVX:
+ case EM_ST19:
+ case EM_VAX:
default:
warn (_("Don't know about relocations on this machine architecture\n"));
return FALSE;
case DT_FINI_ARRAY: return "FINI_ARRAY";
case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
+ case DT_RUNPATH: return "RUNPATH";
+ case DT_FLAGS: return "FLAGS";
+
+ case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
+ case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
case DT_PLTPADSZ: return "PLTPADSZ";
case DT_MOVEENT: return "MOVEENT";
get_machine_name (e_machine)
unsigned e_machine;
{
- static char buff [32];
+ static char buff [64]; /* XXX */
switch (e_machine)
{
case EM_88K: return "MC88000";
case EM_486: return "Intel 80486";
case EM_860: return "Intel 80860";
- case EM_MIPS: return "MIPS R3000 big-endian";
- case EM_S370: return "Amdahl";
+ case EM_MIPS: return "MIPS R3000";
+ case EM_S370: return "IBM System/370";
case EM_MIPS_RS4_BE: return "MIPS R4000 big-endian";
case EM_OLD_SPARCV9: return "Sparc v9 (old)";
case EM_PARISC: return "HPPA";
case EM_CYGNUS_MN10200: return "mn10200";
case EM_CYGNUS_FR30: return "Fujitsu FR30";
case EM_PJ: return "picoJava";
+ case EM_MMA: return "Fujitsu Multimedia Accelerator";
+ case EM_PCP: return "Siemens PCP";
+ case EM_NCPU: return "Sony nCPU embedded RISC processor";
+ case EM_NDR1: return "Denso NDR1 microprocesspr";
+ case EM_STARCORE: return "Motorola Star*Core processor";
+ case EM_ME16: return "Toyota ME16 processor";
+ case EM_ST100: return "STMicroelectronics ST100 processor";
+ case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
+ case EM_FX66: return "Siemens FX66 microcontroller";
+ case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
+ case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
+ case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
+ case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
+ case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
+ case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
+ case EM_SVX: return "Silicon Graphics SVx";
+ case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
+ case EM_VAX: return "Digital VAX";
default:
sprintf (buff, _("<unknown>: %x"), e_machine);
return buff;
static char buf [1024];
buf[0] = '\0';
+
if (e_flags)
{
switch (e_machine)
case SHT_REL: return "REL";
case SHT_SHLIB: return "SHLIB";
case SHT_DYNSYM: return "DYNSYM";
+ case SHT_INIT_ARRAY: return "INIT_ARRAY";
+ case SHT_FINI_ARRAY: return "FINI_ARRAY";
+ case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
case SHT_GNU_verdef: return "VERDEF";
case SHT_GNU_verneed: return "VERNEED";
case SHT_GNU_versym: return "VERSYM";
{
case ELFOSABI_SYSV: return _("UNIX - System V");
case ELFOSABI_HPUX: return _("UNIX - HP-UX");
+ case ELFOSABI_LINUX: return _("UNIX - Linux");
case ELFOSABI_STANDALONE: return _("Standalone App");
+ case ELFOSABI_ARM: return _("ARM");
default:
sprintf (buff, _("<unknown: %x>"), osabi);
return buff;
return isyms;
}
+static const char *
+get_elf_section_flags (sh_flags)
+ bfd_vma sh_flags;
+{
+ static char buff [32];
+
+ * buff = 0;
+
+ while (sh_flags)
+ {
+ bfd_vma flag;
+
+ flag = sh_flags & - sh_flags;
+ sh_flags &= ~ flag;
+
+ switch (flag)
+ {
+ 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;
+
+ default:
+ if (flag & SHF_MASKOS)
+ {
+ strcat (buff, "o");
+ sh_flags &= ~ SHF_MASKOS;
+ }
+ else if (flag & SHF_MASKPROC)
+ {
+ strcat (buff, "p");
+ sh_flags &= ~ SHF_MASKPROC;
+ }
+ else
+ strcat (buff, "x");
+ break;
+ }
+ }
+
+ return buff;
+}
+
static int
process_section_headers (file)
FILE * file;
return 1;
printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
+
if (is_32bit_elf)
printf
(_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
(unsigned long) section->sh_offset,
(unsigned long) section->sh_size,
(unsigned long) section->sh_entsize);
-
- printf (" %c%c%c %2ld %3lx %ld\n",
- (section->sh_flags & SHF_WRITE ? 'W' : ' '),
- (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
- (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
+
+ printf (" %3s ", get_elf_section_flags (section->sh_flags));
+
+ printf (" %2ld %3lx %ld\n",
(unsigned long) section->sh_link,
(unsigned long) section->sh_info,
(unsigned long) section->sh_addralign);
printf (" ");
print_vma (section->sh_entsize, LONG_HEX);
- printf (" %c%c%c",
- (section->sh_flags & SHF_WRITE ? 'W' : ' '),
- (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
- (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '));
-
+ printf (" %3s ", get_elf_section_flags (section->sh_flags));
+
printf (" %2ld %3lx %ld\n",
(unsigned long) section->sh_link,
(unsigned long) section->sh_info,
}
}
+ printf (_("Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings)\n"));
+ printf (_(" I (info), L (link order), O (extra OS processing required)\n"));
+ printf (_(" o (os specific), p (processor specific) x (unknown)\n"));
+
return 1;
}
return 1;
}
+static const char *
+get_dynamic_flags (flags)
+ bfd_vma flags;
+{
+ static char buff [64];
+ while (flags)
+ {
+ bfd_vma flag;
+
+ flag = flags & - flags;
+ flags &= ~ flag;
+
+ switch (flag)
+ {
+ case DF_ORIGIN: strcat (buff, "ORIGIN "); break;
+ case DF_SYMBOLIC: strcat (buff, "SYMBOLIC "); break;
+ case DF_TEXTREL: strcat (buff, "TEXTREL "); break;
+ case DF_BIND_NOW: strcat (buff, "BIND_NOW "); break;
+ default: strcat (buff, "unknown "); break;
+ }
+ }
+ return buff;
+}
+
/* Parse and display the contents of the dynamic segment. */
static int
process_dynamic_segment (file)
{
if (do_dynamic)
{
+ const char *dtype;
+
putchar (' ');
print_vma (entry->d_tag, FULL_HEX);
- printf (" (%s)%*s",
- get_dynamic_type (entry->d_tag),
- (is_32bit_elf ? 27 : 19) - strlen (get_dynamic_type (entry->d_tag)),
+ dtype = get_dynamic_type (entry->d_tag);
+ printf (" (%s)%*s", dtype,
+ ((is_32bit_elf ? 27 : 19)
+ - (int) strlen (dtype)),
" ");
}
switch (entry->d_tag)
{
+ case DT_FLAGS:
+ if (do_dynamic)
+ printf ("%s", get_dynamic_flags (entry->d_un.d_val));
+ break;
+
case DT_AUXILIARY:
case DT_FILTER:
if (do_dynamic)
for (cnt = 0; cnt < total; cnt += 4)
{
int j, nn;
+ char *name;
printf (" %03x:", cnt);
{
ivna.vna_name = BYTE_GET (evna.vna_name);
+ name = strtab + ivna.vna_name;
nn += printf ("(%s%-*s",
- strtab + ivna.vna_name,
- 12 - strlen (strtab
- + ivna.vna_name),
+ name,
+ 12 - (int) strlen (name),
")");
break;
}
ivda.vda_name =
BYTE_GET (evda.vda_name);
+ name = strtab + ivda.vda_name;
nn +=
printf ("(%s%-*s",
- strtab + ivda.vda_name,
- 12
- - strlen (strtab
- + ivda.vda_name),
+ name,
+ 12 - (int) strlen (name),
")");
}
}
{
ivna.vna_name = BYTE_GET (evna.vna_name);
+ name = strtab + ivna.vna_name;
nn += printf ("(%s%-*s",
- strtab + ivna.vna_name,
- 12 - strlen (strtab
- + ivna.vna_name),
+ name,
+ 12 - (int) strlen (name),
")");
break;
}
ivda.vda_name = BYTE_GET (evda.vda_name);
+ name = strtab + ivda.vda_name;
nn += printf ("(%s%-*s",
- strtab + ivda.vda_name,
- 12 - strlen (strtab
- + ivda.vda_name),
+ name,
+ 12 - (int) strlen (name),
")");
}
}
return 1;
}
-static char *
+static const char *
get_symbol_binding (binding)
unsigned int binding;
{
}
}
-static char *
+static const char *
get_symbol_type (type)
unsigned int type;
{
case STT_FUNC: return "FUNC";
case STT_SECTION: return "SECTION";
case STT_FILE: return "FILE";
+ case STT_COMMON: return "COMMON";
default:
if (type >= STT_LOPROC && type <= STT_HIPROC)
{
}
}
-static char *
+static const char *
+get_symbol_visibility (visibility)
+ unsigned int visibility;
+{
+ switch (visibility)
+ {
+ case STV_DEFAULT: return "DEFAULT";
+ case STV_INTERNAL: return "INTERNAL";
+ case STV_HIDDEN: return "HIDDEN";
+ case STV_PROTECTED: return "PROTECTED";
+ default: abort ();
+ }
+}
+
+static const char *
get_symbol_index_type (type)
unsigned int type;
{
}
}
-
static int *
get_dynamic_data (file, number)
FILE * file;
printf (_("\nSymbol table for image:\n"));
if (is_32bit_elf)
- printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
+ printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
else
- printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
+ printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
for (hn = 0; hn < nbuckets; hn++)
{
printf (" %3d %3d: ", si, hn);
print_vma (psym->st_value, LONG_HEX);
putchar (' ' );
- print_vma (psym->st_size, DEC_5);
+ print_vma (psym->st_size, DEC_5);
- printf (" %6s %6s %2d ",
- get_symbol_type (ELF_ST_TYPE (psym->st_info)),
- get_symbol_binding (ELF_ST_BIND (psym->st_info)),
- psym->st_other);
-
- printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
-
+ printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
+ printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
+ printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
+ printf (" %3.3s", get_symbol_index_type (psym->st_shndx));
printf (" %s\n", dynamic_strings + psym->st_name);
}
}
SECTION_NAME (section),
(unsigned long) (section->sh_size / section->sh_entsize));
if (is_32bit_elf)
- printf (_(" Num: Value Size Type Bind Ot Ndx Name\n"));
+ printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
else
- printf (_(" Num: Value Size Type Bind Ot Ndx Name\n"));
+ printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
section->sh_size / section->sh_entsize);
print_vma (psym->st_value, LONG_HEX);
putchar (' ');
print_vma (psym->st_size, DEC_5);
- printf (" %-7s %-6s %2d ",
- get_symbol_type (ELF_ST_TYPE (psym->st_info)),
- get_symbol_binding (ELF_ST_BIND (psym->st_info)),
- psym->st_other);
-
- printf ("%4s", get_symbol_index_type (psym->st_shndx));
-
+ printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
+ 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));
printf (" %s", strtab + psym->st_name);
if (section->sh_type == SHT_DYNSYM &&
case DW_FORM_ref_addr:
case DW_FORM_addr:
uvalue = byte_get (data, pointer_size);
- printf (is_ref ? " <%x>" : " %#x", uvalue);
+ printf (is_ref ? " <%lx>" : " %#lx", uvalue);
data += pointer_size;
break;
case DW_FORM_flag:
case DW_FORM_data1:
uvalue = byte_get (data ++, 1);
- printf (is_ref ? " <%x>" : " %d", uvalue);
+ printf (is_ref ? " <%lx>" : " %ld", uvalue);
break;
case DW_FORM_ref2:
case DW_FORM_data2:
uvalue = byte_get (data, 2);
data += 2;
- printf (is_ref ? " <%x>" : " %d", uvalue);
+ printf (is_ref ? " <%lx>" : " %ld", uvalue);
break;
case DW_FORM_ref4:
case DW_FORM_data4:
uvalue = byte_get (data, 4);
data += 4;
- printf (is_ref ? " <%x>" : " %d", uvalue);
+ printf (is_ref ? " <%lx>" : " %ld", uvalue);
break;
case DW_FORM_ref8:
GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
elib, Elf32_External_Lib *, "liblist");
- printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
+ printf ("\nSection '.liblist' contains %lu entries:\n",
+ (unsigned long) liblistno);
fputs (" Library Time Stamp Checksum Version Flags\n",
stdout);
strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
- printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
+ printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
dynamic_strings + liblist.l_name, timebuf,
liblist.l_checksum, liblist.l_version);
if (options_offset != 0)
{
Elf_External_Options * eopt;
- Elf_Internal_Shdr * sect = section_headers;
+ Elf_Internal_Shdr * sect = section_headers;
Elf_Internal_Options * iopt;
Elf_Internal_Options * option;
size_t offset;
/* Find the section header so that we get the size. */
while (sect->sh_type != SHT_MIPS_OPTIONS)
- ++sect;
+ ++ sect;
GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
Elf_External_Options *, "options");
offset = cnt = 0;
option = iopt;
+
while (offset < sect->sh_size)
{
Elf_External_Options * eoption;
option->info = BYTE_GET (eoption->info);
offset += option->size;
+
++option;
++cnt;
}
string_table + sect->sh_name, cnt);
option = iopt;
+
while (cnt-- > 0)
{
size_t len;
{
Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
- printf ("%5u: %8lu ", cnt, iconf[cnt]);
+ printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
print_vma (psym->st_value, FULL_HEX);
printf (" %s\n", dynamic_strings + psym->st_name);
}
case NT_FPREGSET: return _("NT_FPREGSET (floating point registers)");
case NT_PRPSINFO: return _("NT_PRPSINFO (prpsinfo structure)");
case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
+ case NT_PRXFPREG: return _("NT_PRXFPREG (user_xfpregs structure)");
case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)");
case NT_FPREGS: return _("NT_FPREGS (floating point registers)");
case NT_PSINFO: return _("NT_PSINFO (psinfo structure)");
case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)");
+ case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
default:
sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
return buff;
external = pnotes;
- printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"), offset, length);
+ printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
+ (unsigned long) offset,
+ (unsigned long) length);
printf (_(" Owner\t\tData size\tDescription\n"));
while (external < (Elf_External_Note *)((char *) pnotes + length))