dump.c revision 9039eeaf76678a41be39feb97b4f724272ef7e18
/*
* 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"
/* Get definitions for the relocation types supported. */
#define ELF_TARGET_ALL
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>
#include <libelf.h>
#include <link.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "sgs.h"
#include "conv.h"
#include "dump.h"
/*
* DUMP_CONVFMT defines the libconv formatting options we want to use:
* - Unknown items to be printed as integers using decimal formatting
* - The "Dump Style" versions of strings.
*/
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);
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
} else
} else {
}
(void) printf("%-20s",
type, DUMP_CONVFMT));
}
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("%-20s",
type, DUMP_CONVFMT));
}
(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).
*/
} else {
}
if (!v_flag) {
(void) printf("%d\t\t%d\t%d\t%#x\t",
} else {
(void) printf("%s\t",
DUMP_CONVFMT));
(void) printf("%s",
if (specsec) {
} 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 {
/*LINTED: E_SEC_PRINTF_VAR_FMT*/
(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
{
#define pdyn_Fmtptr "%#llx"
int index = 1;
int header_num = 0;
const char *str;
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;
DUMP_CONVFMT));
/*
* It would be nice to use a table driven loop
* here, but the address space is too sparse
* and irregular. A switch is simple and robust.
*/
/*
* Items with an address value
*/
case DT_PLTGOT:
case DT_HASH:
case DT_STRTAB:
case DT_RELA:
case DT_SYMTAB:
case DT_INIT:
case DT_FINI:
case DT_REL:
case DT_DEBUG:
case DT_TEXTREL:
case DT_JMPREL:
case DT_INIT_ARRAY:
case DT_FINI_ARRAY:
case DT_INIT_ARRAYSZ:
case DT_FINI_ARRAYSZ:
case DT_PREINIT_ARRAY:
case DT_PREINIT_ARRAYSZ:
case DT_SUNW_RTLDINF:
case DT_SUNW_CAP:
case DT_SUNW_SYMTAB:
case DT_PLTPAD:
case DT_MOVETAB:
case DT_SYMINFO:
case DT_RELACOUNT:
case DT_RELCOUNT:
case DT_VERSYM:
case DT_VERDEF:
case DT_VERDEFNUM:
case DT_VERNEED:
(void) printf(pdyn_Fmtptr,
break;
/*
* Items with a string value
*/
case DT_NEEDED:
case DT_SONAME:
case DT_RPATH:
case DT_RUNPATH:
case DT_SUNW_AUXILIARY:
case DT_SUNW_FILTER:
case DT_CONFIG:
case DT_DEPAUDIT:
case DT_AUDIT:
case DT_AUXILIARY:
case DT_USED:
case DT_FILTER:
if (v_flag) { /* Look up the string */
} else { /* Show the address */
(void) printf(pdyn_Fmtptr,
}
break;
/*
* Items with a literal value
*/
case DT_PLTRELSZ:
case DT_RELASZ:
case DT_RELAENT:
case DT_STRSZ:
case DT_SYMENT:
case DT_RELSZ:
case DT_RELENT:
case DT_PLTREL:
case DT_BIND_NOW:
case DT_CHECKSUM:
case DT_PLTPADSZ:
case DT_MOVEENT:
case DT_MOVESZ:
case DT_SYMINSZ:
case DT_SYMINENT:
case DT_VERNEEDNUM:
case DT_SPARC_REGISTER:
case DT_SUNW_SYMSZ:
(void) printf(pdyn_Fmtptr,
break;
/*
* Items that are bitmasks
*/
case DT_FLAGS:
case DT_FEATURE_1:
case DT_POSFLAG_1:
case DT_FLAGS_1:
if (v_flag) {
case DT_FLAGS:
str = conv_dyn_flag(
break;
case DT_FEATURE_1:
break;
case DT_POSFLAG_1:
break;
case DT_FLAGS_1:
break;
}
}
if (str) { /* Show as string */
} else { /* Numeric form */
(void) printf(pdyn_Fmtptr,
}
break;
/*
* Depreciated items with a literal value
*/
(void) printf(pdyn_Fmtptr
" (deprecated value)",
break;
/* Ignored items */
case DT_SYMBOLIC:
(void) printf("(ignored)");
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 class;
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 {
(void) printf("%-11s",
(void) printf("%-12s",
(void) printf("%s\n",
}
(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);
}
(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);
}