dump.c revision 0bc07c75e71baa4cc26f90611864f7e60dcea093
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>
#include <libelf.h>
#include <link.h>
#include <sys/elf_SPARC.h>
#include <sys/elf_amd64.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "sgs.h"
#include "conv.h"
#include "dump.h"
const char *UNKNOWN = "<unknown>";
static int
x_flag = 0, /* option requires section header table */
z_flag = 0, /* process files within an archive */
rn_flag = 0; /* dump named relocation information */
static int
/* flags: ?_flag corresponds to ? option */
a_flag = 0, /* dump archive header of each member of archive */
g_flag = 0, /* dump archive symbol table */
c_flag = 0, /* dump the string table */
d_flag = 0, /* dump range of sections */
f_flag = 0, /* dump each file header */
h_flag = 0, /* dump section headers */
n_flag = 0, /* dump named section */
o_flag = 0, /* dump each program execution header */
r_flag = 0, /* dump relocation information */
s_flag = 0, /* dump section contents */
t_flag = 0, /* dump symbol table entries */
C_flag = 0, /* dump decoded C++ symbol names */
L_flag = 0, /* dump dynamic linking information */
T_flag = 0, /* dump symbol table range */
V_flag = 0; /* dump version information */
int p_flag = 0, /* suppress printing of headings */
v_flag = 0; /* print information in verbose form */
static int
d_low = 0, /* range for use with -d */
d_hi = 0,
d_num = 0;
static int
T_low = 0, /* range for use with -T */
T_hi = 0,
T_num = 0;
char *prog_name;
static int errflag = 0;
static struct stab_list_s {
struct stab_list_s *next;
char *strings;
} *StringTableList = (void *)0;
extern void ar_sym_read();
extern void dump_exec_header();
/*
* Get the section descriptor and set the size of the
* data returned. Data is byte-order converted.
*/
void *
{
p_data = 0;
return (NULL);
}
}
/*
* Get the section descriptor and set the size of the
* data returned. Data is raw (i.e., not byte-order converted).
*/
static void *
{
p_data = 0;
return (NULL);
}
}
/*
* Print out a usage message in short form when program is invoked
* with insufficient or no arguments, and in long form when given
* either a ? or an invalid option.
*/
static void
usage()
{
if (errflag) {
"\t\t[-a dump archive header of each member of archive]\n\
[-g dump archive global symbol table]\n\
[-c dump the string table]\n\
[-d dump range of sections]\n\
[-f dump each file header]\n\
[-h dump section headers]\n\
[-n dump named section]\n\
[-o dump each program execution header]\n\
[-p suppress printing of headings]\n\
[-r dump relocation information]\n\
[-s dump section contents]\n\
[-t dump symbol table entries]\n\
[-v print information in verbose form]\n\
[-C dump decoded C++ symbol names]\n\
[-L dump the .dynamic structure]\n\
[-T dump symbol table range]\n\
[-V dump version information]\n");
}
}
/*
* Set a range. Input is a character string, a lower
* bound and an upper bound. This function converts
* a character string into its correct integer values,
* setting the first value as the lower bound, and
* the second value as the upper bound. If more values
* are given they are ignored with a warning.
*/
static void
{
char *w;
char *lasts;
if (!(*low))
/* LINTED */
else
if (!(*high))
/* LINTED */
else {
"%s: too many arguments - %s ignored\n",
prog_name, w);
return;
}
s = NULL;
} /* end while */
}
/*
* Print static shared library information.
*/
static void
{
unsigned char *strtab;
unsigned long *temp;
(void) printf("\n **** STATIC SHARED LIBRARY INFORMATION ****\n");
(void) printf("\t");
section_size = 0;
if ((strtab = (unsigned char *)
return;
}
while (section_size != 0) {
/* LINTED */
section_size -= (total*sizeof (long));
}
}
/*
* Print raw data in hexidecimal. Input is the section data to
* be printed out and the size of the data. Output is relative
* to a table lookup in dumpmap.h.
*/
static void
{
size_t j;
count = 1;
(void) printf("\t");
p_sec += 2;
if (count == 12) {
(void) printf("\n\t");
count = 0;
}
}
/*
* take care of last byte if odd byte section
*/
(void) printf("\n");
}
/*
* Print relocation data of type SHT_RELA
* If d_flag, print data corresponding only to
* the section or range of sections specified.
* If n_flag, print data corresponding only to
* the named section.
*/
static void
{
static int n_title = 0;
int ndx = 0;
char *sym_name;
int adj = 0;
adj = 8;
if ((rel_entsize == 0) ||
}
while (no_entries--) {
/* LINTED */
/* LINTED */
/* LINTED */
ndx++;
continue;
}
ndx++;
continue;
}
if (!n_title) {
(void) printf("%-*s%-*s%-*s%s\n\n",
16, "Type", "Addend");
n_title = 1;
}
}
if (d_flag) {
if (!d_hi)
ndx++;
continue;
}
}
if (!v_flag) {
} else {
char tmpstr[10];
if (len > 22) {
/* LINTED */
(int)len);
} else
} else
}
ndx++;
}
}
/*
* Print relocation data of type SHT_REL.
* If d_flag, print data corresponding only to
* the section or range of sections specified.
* If n_flag, print data corresponding only to
* the named section.
*/
static void
{
static int n_title = 0;
int ndx = 0;
char *sym_name;
int adj = 0;
adj = 8;
if ((rel_entsize == 0) ||
}
while (no_entries--) {
/* LINTED */
/* LINTED */
/* LINTED */
ndx++;
continue;
}
ndx++;
continue;
}
if (!n_title) {
(void) printf("%-*s%-*s%s\n\n",
n_title = 1;
}
}
if (d_flag) {
if (!d_hi)
ndx++;
continue;
}
}
if (!v_flag) {
} else {
else
}
(void) printf("\n");
ndx++;
}
}
/* demangle C++ names */
static char *
demangled_name(char *s)
{
char *dn;
dn = sgs_demangle(s);
/*
* If not demangled, just return the symbol name
*/
return (s);
/*
* Demangled. Format it
*/
return (s);
return (buf);
}
/*
* Print the symbol table. Input is an ELF file descriptor, a
* pointer to the symbol table SCNTAB structure,
* the number of symbols, a range of symbols to print,
* an index which is the number of the
* section in the file, and the filename. The number of sections,
* the range, and the index are set in
* dump_symbol_table, depending on whether -n or -T were set.
*/
static void
{
int adj = 0; /* field adjustment for elf64 */
Elf32_Word *symshndx = 0;
unsigned int nosymshndx = 0;
adj = 8;
while (range > 0) {
char *sym_name = (char *)0;
int specsec;
unsigned int shndx;
(symshndx == 0) && (nosymshndx == 0)) {
_scn = 0;
break;
/* LINTED */
continue;
nosymshndx = 0;
break;
}
}
nosymshndx = 1;
}
specsec = 0;
} else {
specsec = 1;
else
specsec = 0;
}
/*
* The strings "REG_G1" through "REG_G7" are intended
* to be consistent with output from elfdump(1).
*/
case STO_SPARC_REGISTER_G1:
break;
case STO_SPARC_REGISTER_G2:
break;
case STO_SPARC_REGISTER_G3:
break;
case STO_SPARC_REGISTER_G4:
break;
case STO_SPARC_REGISTER_G5:
break;
case STO_SPARC_REGISTER_G6:
break;
case STO_SPARC_REGISTER_G7:
break;
default:
}
} else
if (!v_flag) {
(void) printf("%d\t\t%d\t%d\t%#x\t",
} else {
switch (type) {
case STT_NOTYPE:
break;
case STT_OBJECT:
break;
case STT_FUNC:
break;
case STT_SECTION:
break;
case STT_FILE:
break;
case STT_SPARC_REGISTER:
break;
case STT_COMMON:
break;
case STT_TLS:
break;
default:
}
switch (bind) {
case STB_LOCAL:
(void) printf("LOCL");
break;
case STB_GLOBAL:
(void) printf("GLOB");
break;
case STB_WEAK:
(void) printf("WEAK");
break;
default:
}
if (specsec) {
switch (shndx) {
case SHN_UNDEF:
(void) printf("UNDEF");
break;
case SHN_ABS:
(void) printf("ABS");
break;
case SHN_COMMON:
(void) printf("COMMON");
break;
case SHN_XINDEX:
(void) printf("XINDEX");
break;
default:
}
} else
(void) printf("\t");
}
/* support machines where NULL-deref causes core dump */
else
if (C_flag)
(char *)elf_strptr(elf_file,
else
range--;
} /* end while */
}
/*
* Print the section header table. Input is the SCNTAB structure,
* the number of sections, an index which is the number of the
* section in the file, and the filename. The values of the SCNTAB
* structure, the number of sections, and the index are set in
* dump_shdr depending on whether the -n or -d modifiers were set.
*/
static void
{
SCNTAB *p;
int num;
int field;
field = 21;
else
field = 13;
p = s;
if (!v_flag) {
(void) printf("%u\t%llu\t",
} else {
case SHT_NULL:
(void) printf("NULL");
break;
case SHT_PROGBITS:
(void) printf("PBIT");
break;
case SHT_SYMTAB:
(void) printf("SYMT");
break;
case SHT_STRTAB:
(void) printf("STRT");
break;
case SHT_RELA:
(void) printf("RELA");
break;
case SHT_HASH:
(void) printf("HASH");
break;
case SHT_DYNAMIC:
(void) printf("DYNM");
break;
case SHT_NOTE:
(void) printf("NOTE");
break;
case SHT_NOBITS:
(void) printf("NOBI");
break;
case SHT_REL:
(void) printf("REL ");
break;
case SHT_DYNSYM:
(void) printf("DYNS");
break;
case ((GElf_Word) SHT_LOUSER):
(void) printf("LUSR");
break;
case ((GElf_Word) SHT_HIUSER):
(void) printf("HUSR");
break;
case SHT_SHLIB:
(void) printf("SHLB");
break;
case SHT_SUNW_SIGNATURE:
(void) printf("SIGN");
break;
case SHT_SUNW_ANNOTATE:
(void) printf("ANOT");
break;
case SHT_SUNW_DEBUGSTR:
(void) printf("DBGS");
break;
case SHT_SUNW_DEBUG:
(void) printf("DBG ");
break;
case SHT_SUNW_move:
(void) printf("MOVE");
break;
case SHT_SUNW_verdef:
(void) printf("VERD");
break;
case SHT_SUNW_verneed:
(void) printf("VERN");
break;
case SHT_SUNW_versym:
(void) printf("VERS");
break;
case SHT_SUNW_syminfo:
(void) printf("SYMI");
break;
case SHT_SUNW_COMDAT:
(void) printf("COMD");
break;
case SHT_AMD64_UNWIND:
(void) printf("UNWD");
break;
case SHT_SPARC_GOTDATA:
(void) printf("GOTD");
break;
default:
break;
}
(void) printf(" ");
(void) printf("W");
else
(void) printf("-");
(void) printf("A");
else
(void) printf("-");
(void) printf("I");
else
(void) printf("-");
(void) printf("O");
(void) printf("E");
(void) printf("\t");
}
(void) printf("%-#*llx%-#*llx%-#*llx%s%s\n",
/* compatibility: tab for elf32 */
(void) printf("\t%u\t%u\t%-#*llx%-#*llx\n\n",
}
}
/*
* Check that a range of numbers is valid. Input is
* a lower bound, an upper bound, a boundary condition,
* and the filename. Negative numbers and numbers greater
* than the bound are invalid. low must be smaller than hi.
* The returned integer is the number of items in the
* range if it is valid and -1 otherwise.
*/
static int
{
"%s: %s: number out of range, %d\n",
return (-1);
}
"%s: %s: number out of range, %d\n",
return (-1);
}
"%s: %s: invalid range, %d,%d\n",
return (-1);
}
if (hi)
else
return (1);
}
/*
* Print relocation information. Since this information is
* machine dependent, new sections must be added for each machine
* that is supported. Input is an ELF file descriptor, the ELF header,
* the SCNTAB structure, the number of sections, and a filename.
* Set up necessary information to print relocation information
* and call the appropriate print function depending on the
* type of relocation information. If the symbol table is
* absent, no relocation data is processed. Input is an
* ELF file descriptor, the ELF header, the SCNTAB structure,
* and the filename. Set range of d_flag and name if n_flag.
*/
static void
{
int r_title = 0;
int adj = 0;
adj = 8;
(void) printf("\n **** RELOCATION INFORMATION ****\n");
r_title = 1;
}
while (num_scns-- > 0) {
p_scns++;
continue;
}
"%s: %s: elf_getshnum failed: %s\n",
return;
}
/* LINTED */
"section #: %d sh_link: %d\n",
/* LINTED */
return;
}
} else {
return;
}
sym_size = 0;
reloc_size = 0;
return;
}
return;
}
(void) printf("%-*s%-*s%-*s%s\n\n",
18, "Type", "Addend");
return;
}
if (n_flag) {
rn_flag = 1;
}
if (d_flag) {
rn_flag = 0;
}
} else {
(void) printf("%-*s%-*s%s\n\n",
}
== NULL) {
return;
}
if (n_flag) {
rn_flag = 1;
}
if (d_flag) {
rn_flag = 0;
}
}
}
p_scns++;
}
}
/*
* Print out the string tables. Input is an opened ELF file,
* the SCNTAB structure, the number of sections, and the filename.
* Since there can be more than one string table, all sections are
* examined and any with the correct type are printed out.
*/
static void
{
unsigned char *strtab;
int beg_of_string;
int counter = 0;
int str_off;
int i;
if (!p_flag) {
(void) printf("\n **** STRING TABLE INFORMATION ****\n");
}
for (i = 0; i < num_scns; i++, s++) {
continue;
str_off = 0;
if (!p_flag) {
(void) printf(" <offset> \tName\n");
}
section_size = 0;
if ((strtab = (unsigned char *)
continue;
}
if (section_size != 0) {
beg_of_string = 0;
while (section_size--) {
unsigned char c = *strtab++;
if (beg_of_string) {
counter++;
beg_of_string = 0;
}
str_off++;
switch (c) {
case '\0':
(void) printf("\n");
beg_of_string = 1;
break;
default:
(void) putchar(c);
}
}
}
}
(void) printf("\n");
}
/*
* Print the symbol table. This function does not print the contents
* of the symbol table but sets up the parameters and then calls
* print_symtab to print the symbols. Calling another function to print
* the symbols allows both -T and -n to work correctly
* simultaneously. Input is an opened ELF file, a pointer to the
* symbol table SCNTAB structure, and the filename.
* Set the range of symbols to print if T_flag, and set
* name of symbol to print if n_flag.
*/
static void
{
int index = 1;
int found_it = 0;
int i;
int adj = 0; /* field adjustment for elf64 */
adj = 8;
return;
}
/* get symbol table data */
sym_size = 0;
if ((sym_data =
(void) printf("No symbol table data\n");
return;
}
/* LINTED */
for (i = 1; i < count; i++) {
continue;
} else {
found_it = 1;
if (!p_flag) {
(void) printf(
"\n ***** SYMBOL TABLE INFORMATION *****\n");
(void) printf(
"[Index] %-*s%-*sType\tBind\tOther\tShndx\tName",
}
1, i);
}
} /* end for */
if (!found_it) {
}
} else if (T_flag) {
if (T_num < 0)
return;
if (!p_flag) {
(void) printf(
"\n ***** SYMBOL TABLE INFORMATION *****\n");
(void) printf(
"[Index] %-*s%-*sType\tBind\tOther\tShndx\tName",
}
} else {
if (!p_flag) {
(void) printf(
"\n ***** SYMBOL TABLE INFORMATION *****\n");
(void) printf(
"[Index] %-*s%-*sType\tBind\tOther\tShndx\tName",
}
}
}
/*
* Print dynamic linking information. Input is an ELF
* file descriptor, the SCNTAB structure, the number of
* sections, and the filename.
*/
static void
{
char *dt_name;
int index = 1;
int header_num = 0;
#define Fmttag "%-15.15s "
#define Fmtptr "%#llx"
if (!p_flag)
(void) printf("\n **** DYNAMIC SECTION INFORMATION ****\n");
int ii;
continue;
if (!p_flag) {
(void) printf("[INDEX]\tTag Value\n");
}
return;
}
ii = 0;
char value[256];
/*
* Start of generic flags.
*/
case (DT_NEEDED):
if (v_flag)
else
break;
case (DT_PLTRELSZ):
break;
case (DT_PLTGOT):
break;
case (DT_HASH):
break;
case (DT_STRTAB):
break;
case (DT_SYMTAB):
break;
case (DT_RELA):
break;
case (DT_RELASZ):
break;
case (DT_RELAENT):
break;
case (DT_STRSZ):
break;
case (DT_SYMENT):
break;
case (DT_INIT):
break;
case (DT_FINI):
break;
case (DT_SONAME):
if (v_flag)
else
break;
case (DT_RPATH):
if (v_flag)
else
break;
case (DT_SYMBOLIC):
break;
case (DT_REL):
break;
case (DT_RELSZ):
break;
case (DT_RELENT):
break;
case (DT_PLTREL):
break;
case (DT_DEBUG):
break;
case (DT_TEXTREL):
break;
case (DT_JMPREL):
break;
case (DT_BIND_NOW):
break;
case (DT_INIT_ARRAY):
(const char *)"INIT_ARRAY");
break;
case (DT_FINI_ARRAY):
(const char *)"FINI_ARRAY");
break;
case (DT_INIT_ARRAYSZ):
(const char *)"INIT_ARRAYSZ");
break;
case (DT_FINI_ARRAYSZ):
(const char *)"FINI_ARRAYSZ");
break;
case (DT_RUNPATH):
if (v_flag)
else
break;
case (DT_FLAGS):
(const char *)"FLAGS");
value[0] = '\0';
if (v_flag) {
(const char *)"ORIGIN ");
(const char *)"SYMBOLIC ");
(const char *)"TEXTREL ");
(const char *)"BIND_NOW ");
(const char *)"STATIC_TLS ");
}
else
break;
case (DT_PREINIT_ARRAY):
(const char *)"PRINIT_ARRAY");
break;
case (DT_PREINIT_ARRAYSZ):
(const char *)"PRINIT_ARRAYSZ");
break;
/*
* DT_LOOS - DT_HIOS range.
*/
case (DT_SUNW_AUXILIARY):
(const char *)"SUNW_AUXILIARY");
if (v_flag)
else
break;
case (DT_SUNW_RTLDINF):
(const char *)"SUNW_RTLDINF");
break;
case (DT_SUNW_FILTER):
(const char *)"SUNW_FILTER");
if (v_flag)
else
break;
case (DT_SUNW_CAP):
(const char *)"SUNW_CAP");
break;
/*
* SUNW: DT_VALRNGLO - DT_VALRNGHI range.
*/
case (DT_CHECKSUM):
(const char *)"CHECKSUM");
break;
case (DT_PLTPADSZ):
(const char *)"PLTPADSZ");
break;
case (DT_MOVEENT):
(const char *)"MOVEENT");
break;
case (DT_MOVESZ):
(const char *)"MOVESZ");
break;
case (DT_FEATURE_1):
(const char *)"FEATURE_1");
value[0] = '\0';
if (v_flag) {
(const char *)"PARINIT ");
(const char *)"CONFEXP ");
}
else
break;
case (DT_POSFLAG_1):
(const char *)"POSFLAG_1");
value[0] = '\0';
if (v_flag) {
(const char *)"LAZYLOAD ");
(const char *)"GROUPPERM ");
}
else
break;
case (DT_SYMINSZ):
(const char *)"SYMINSZ");
break;
case (DT_SYMINENT):
(const char *)"SYMINENT");
break;
/*
* SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range.
*/
case (DT_CONFIG):
if (v_flag)
else
break;
case (DT_DEPAUDIT):
(const char *)"DEPAUDIT");
if (v_flag)
else
break;
case (DT_AUDIT):
(const char *)"AUDIT");
if (v_flag)
else
break;
case (DT_PLTPAD):
(const char *)"PLTPAD");
break;
case (DT_MOVETAB):
(const char *)"MOVETAB");
break;
case (DT_SYMINFO):
(const char *)"SYMINFO");
break;
/*
* SUNW: generic range.
*/
case (DT_RELACOUNT):
(const char *)"RELACOUNT");
break;
case (DT_RELCOUNT):
(const char *)"RELCOUNT");
break;
case (DT_FLAGS_1):
(const char *)"FLAGS_1");
value[0] = '\0';
if (v_flag) {
(const char *)"NOW ");
(const char *)"GLOBAL ");
(const char *)"GROUP ");
(const char *)"NODELETE ");
(const char *)"LOADFLTR ");
(const char *)"INITFIRST ");
(const char *)"NOOPEN ");
(const char *)"ORIGIN ");
(const char *)"DIRECT ");
(const char *)"TRANS ");
(const char *)"INTERPOSE ");
(const char *)"NODEFLIB ");
(const char *)"NODUMP ");
(const char *)"CONFALT ");
(const char *)"ENDFILTEE ");
(const char *)"DISPRELDONE ");
(const char *)"DISPRELPND ");
(const char *)"IGNMULDEF ");
(const char *)"NOKSYMS ");
(const char *)"NORELOC ");
}
else
break;
case (DT_VERSYM):
break;
case (DT_VERDEF):
break;
case (DT_VERDEFNUM):
(const char *)"VERDEFNUM");
break;
case (DT_VERNEED):
break;
case (DT_VERNEEDNUM):
(const char *)"VERNEEDNUM");
break;
case (DT_AUXILIARY):
(const char *)"AUXILIARY");
if (v_flag)
else
break;
case (DT_USED):
if (v_flag)
else
break;
case (DT_FILTER):
if (v_flag)
else
break;
/*
* SUNW: machine specific range.
*/
case (DT_SPARC_REGISTER):
(const char *)"REGISTER");
break;
case (DT_DEPRECATED_SPARC_REGISTER):
(const char *)"REGISTER");
(void) printf("%#llx (deprecated value)",
break;
default:
break;
}
(void) printf("\n");
}
}
/*
* Check for existence of static shared library information.
*/
while (--lib_scns > 0) {
}
l_scns++;
}
}
header_num++;
}
}
/*
* Print the ELF header. Input is an ELF file descriptor
* and the filename. If f_flag is set, the ELF header is
* printed to stdout, otherwise the function returns after
* setting the pointer to the ELF header. Any values which
* are not known are printed in decimal. Fields must be updated
* as new values are added.
*/
static GElf_Ehdr *
{
int field;
elf_errmsg(-1));
return (NULL);
}
if (class == ELFCLASS64)
field = 21;
else
field = 13;
if (!f_flag)
return (elf_head_p);
if (!p_flag) {
(void) printf("\n **** ELF HEADER ****\n");
(void) printf("%-*s%-11s%-*sMachine Version\n",
(void) printf("%-*s%-11s%-*sFlags Ehsize\n",
(void) printf("%-*s%-11s%-*sShnum Shstrndx\n\n",
}
if (!v_flag) {
(void) printf("%-*d%-11d%-*d%-12d%d\n",
(int)elf_head_p->e_machine,
} else {
switch (class) {
case ELFCLASSNONE:
break;
case ELFCLASS32:
break;
case ELFCLASS64:
break;
default:
break;
}
switch (data) {
case ELFDATANONE:
break;
case ELFDATA2LSB:
break;
case ELFDATA2MSB:
break;
default:
break;
}
switch (elf_head_p->e_type) {
case ET_NONE:
break;
case ET_REL:
break;
case ET_EXEC:
break;
case ET_DYN:
break;
case ET_CORE:
break;
default:
break;
}
switch (elf_head_p->e_machine) {
case EM_NONE:
break;
case EM_M32:
break;
case EM_SPARC:
break;
case EM_SPARCV9:
break;
case EM_386:
break;
case EM_68K:
break;
case EM_88K:
break;
case EM_486:
break;
case EM_860:
break;
case EM_MIPS:
break;
case EM_MIPS_RS3_LE:
break;
case EM_RS6000:
break;
case EM_PA_RISC:
break;
case EM_nCUBE:
break;
case EM_VPP500:
break;
case EM_SPARC32PLUS:
break;
case EM_PPC:
break;
case EM_IA_64:
break;
default:
}
switch (elf_head_p->e_version) {
case EV_NONE:
(void) printf("Invalid\n");
break;
case EV_CURRENT:
(void) printf("Current\n");
break;
default:
}
}
(void) printf("%-#*llx%-#11llx%-#*llx%-#12x%#x\n",
(void) printf("%-#*x%-11u%-#*x%-12u%u\n",
} else {
(void) printf("%-#*x%-11u%-#*x%-12uXINDEX\n",
}
int field;
field = 21;
else
field = 13;
if (!p_flag) {
(void) printf("\n **** SECTION HEADER[0] "
"{Elf Extensions} ****\n");
(void) printf(
"[No]\tType\tFlags\t%-*s %-*s%-*s%sName\n",
"Size(shnum)",
/* compatibility: tab for elf32 */
(void) printf("\tLn(strndx) Info\t%-*s Entsize\n",
field, "Adralgn");
}
"%s: %s: elf_getscn failed: %s\n",
return (NULL);
}
"%s: %s: gelf_getshdr: %s\n",
return (NULL);
}
/*
* LINTED - field and EC_XWORD cause -#*llu complaints that
* even this comment can't shutup.
*/
(void) printf("%-#*llx %-#*llx%-#*llu%s%-#*u\n",
/* compatibility: tab for elf32 */
(void) printf("\t%u\t%u\t%-#*llx %-#*llx\n",
}
(void) printf("\n");
return (elf_head_p);
}
/*
* Print section contents. Input is an ELF file descriptor,
* the ELF header, the SCNTAB structure,
* the number of symbols, and the filename.
* The number of sections,
* and the offset into the SCNTAB structure will be
* set in dump_section if d_flag or n_flag are set.
* If v_flag is set, sections which can be interpreted will
* be interpreted, otherwise raw data will be output in hexidecimal.
*/
static void
{
unsigned char *p_sec;
int i;
for (i = 0; i < num_scns; i++, p++) {
size = 0;
else
continue;
}
continue;
}
continue;
}
continue;
}
dump_string_table(p, 1);
continue;
}
continue;
}
continue;
}
continue;
}
}
(void) printf("\n");
}
/*
* Print section contents. This function does not print the contents
* of the sections but sets up the parameters and then calls
* print_section to print the contents. Calling another function to print
* the contents allows both -d and -n to work correctly
* simultaneously. Input is an ELF file descriptor, the ELF header,
* the SCNTAB structure, the number of sections, and the filename.
* Set the range of sections if d_flag, and set section name if
* n_flag.
*/
static void
{
int i;
int found_it = 0; /* for use with -n section_name */
if (n_flag) {
n_range = s;
continue;
else {
found_it = 1;
}
}
if (!found_it) {
}
} /* end n_flag */
if (d_flag) {
d_range = s;
if (d_num < 0)
return;
} /* end d_flag */
}
/*
* Print the section header table. This function does not print the contents
* of the section headers but sets up the parameters and then calls
* print_shdr to print the contents. Calling another function to print
* the contents allows both -d and -n to work correctly
* simultaneously. Input is the SCNTAB structure,
* the number of sections from the ELF header, and the filename.
* Set the range of section headers to print if d_flag, and set
* name of section header to print if n_flag.
*/
static void
{
int field;
int i;
int found_it = 0; /* for use with -n section_name */
field = 21;
else
field = 13;
if (!p_flag) {
(void) printf("\n **** SECTION HEADER TABLE ****\n");
(void) printf("[No]\tType\tFlags\t%-*s %-*s %-*s%sName\n",
/* compatibility: tab for elf32 */
(void) printf("\tLink\tInfo\t%-*s Entsize\n\n",
field, "Adralgn");
}
if (n_flag) {
n_range = s;
continue;
else {
found_it = 1;
}
}
if (!found_it) {
}
} /* end n_flag */
if (d_flag) {
d_range = s;
if (d_num < 0)
return;
} /* end d_flag */
}
/*
* Process all of the command line options (except
* for -a, -g, -f, and -o). All of the options processed
* by this function require the presence of the section
* header table and will not be processed if it is not present.
* Set up a buffer containing section name, section header,
* and section descriptor for each section in the file. This
* structure is used to avoid duplicate calls to libelf functions.
* Structure members for the symbol table, the debugging information,
* and the line number information are global. All of the
* rest are local.
*/
static void
{
int found = 0;
unsigned int num_scns;
"%s: %s: elf_getshnum failed: %s\n",
return;
}
"%s: %s: elf_getshstrndx failed: %s\n",
return;
}
return;
}
/* LINTED */
return;
}
found += 1;
}
buffer++;
}
/*
* These functions depend upon the presence of the section header table
* and will not be invoked in its absence
*/
if (h_flag) {
}
}
if (c_flag) {
}
if (r_flag) {
}
if (L_flag) {
}
if (s_flag) {
}
}
/*
* Load the archive string table(s) (for extended-length strings)
*/
static struct stab_list_s *
{
if (p_ar) {
if (!STabList)
else {
}
}
}
}
return (STabList);
}
/*
* Print the archive header for each member of an archive.
* Also call ar_sym_read to print the symbols in the
* archive symbol table if g_flag. Input is a file descriptor,
* an ELF file descriptor, and the filename. Putting the call
* to dump the archive symbol table in this function is more
* efficient since it is necessary to examine the archive member
* name in the archive header to determine which member is the
* symbol table.
*/
static void
{
int title = 0;
int err = 0;
cmd = ELF_C_READ;
continue;
}
if (g_flag)
filename);
continue;
} else {
if (a_flag) {
if (!v_flag)
(void) printf(
"\n\n\t\t\t***ARCHIVE HEADER***"
"\n Date Uid Gid Mode Size Member Name\n\n");
else
(void) printf(
"\n\n\t\t\t***ARCHIVE HEADER***"
"\n Date Uid Gid Mode Size Member Name\n\n");
title = 1;
}
if (!v_flag) {
(void) printf(
"\t0x%.8lx %6d %6d 0%.6ho 0x%.8lx %-s\n\n",
} else {
"%b %d %H:%M:%S %Y",
exit(1);
}
(void) printf(
"\t%s %6d %6d 0%.6ho 0x%.8lx %-s\n\n",
buf,
}
}
}
} /* end while */
if (err != 0) {
}
}
/*
* Process member files of an archive. This function provides
* a loop through an archive equivalent the processing of
* each_file for individual object files.
*/
static void
{
char *fullname;
cmd = ELF_C_READ;
"%s: %s: %s\n",
return;
}
continue;
}
return;
return;
if (o_flag)
if (x_flag)
} else {
"%s: %s: invalid file type\n",
continue;
}
} /* end while */
}
/*
* Takes a filename as input. Test first for a valid version
* of libelf.a and exit on error. Process each valid file
* or archive given as input on the command line. Check
* for file type. If it is an archive, process the archive-
* specific options first, then files within the archive.
* If it is an ELF object file, process it; otherwise
* warn that it is an invalid file type.
* All options except the archive-specific and program
* execution header are processed in the function, dump_section_table.
*/
static void
{
int fd;
errno = 0;
return;
}
filename);
return;
}
cmd = ELF_C_READ;
elf_errmsg(-1));
return;
}
}
if (z_flag)
} else {
if (o_flag)
filename);
if (x_flag)
}
} else {
}
}
}
/*
* Sets up flags for command line options given and then
* calls each_file() to process each file.
*/
int
{
int optchar;
/*
* Check for a binary that better fits this architecture.
*/
switch (optchar) {
case 'a':
a_flag = 1;
x_flag = 1;
break;
case 'g':
g_flag = 1;
x_flag = 1;
break;
case 'v':
v_flag = 1;
break;
case 'p':
p_flag = 1;
break;
case 'f':
f_flag = 1;
z_flag = 1;
break;
case 'o':
o_flag = 1;
z_flag = 1;
break;
case 'h':
h_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 's':
s_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 'd':
d_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 'n':
n_flag++;
x_flag = 1;
z_flag = 1;
break;
case 'r':
r_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 't':
t_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 'C':
C_flag = 1;
t_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 'T':
T_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 'c':
c_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 'L':
L_flag = 1;
x_flag = 1;
z_flag = 1;
break;
case 'V':
V_flag = 1;
(const char *)SGU_PKG,
(const char *)SGU_REL);
break;
case '?':
errflag += 1;
break;
default:
break;
}
}
usage();
exit(269);
}
}
exit(101);
}
optind++;
}
return (0);
}