mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-13 21:49:40 +00:00
Added +version (-V) option to print version number.
This commit is contained in:
parent
8fb94c7a78
commit
249c6fc0d6
172
binutils/nm.c
172
binutils/nm.c
@ -1,5 +1,5 @@
|
||||
/* nm.c -- Describe symbol table of a rel file.
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
Copyright 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
@ -24,17 +24,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "aout/stab_gnu.h"
|
||||
#include "aout/ranlib.h"
|
||||
|
||||
static boolean
|
||||
display_file PARAMS ((char *filename));
|
||||
|
||||
static void
|
||||
do_one_rel_file PARAMS ((bfd *file));
|
||||
|
||||
PROTO(static boolean, display_file, (char *filename));
|
||||
PROTO(static void, do_one_rel_file, (bfd *file));
|
||||
PROTO(static unsigned int, filter_symbols, (bfd *file, asymbol **syms,
|
||||
unsigned long symcount));
|
||||
static unsigned int
|
||||
filter_symbols PARAMS ((bfd *file, asymbol **syms, unsigned long symcount));
|
||||
|
||||
PROTO(static void, print_symbols, (bfd *file, asymbol **syms,
|
||||
unsigned long symcount));
|
||||
extern PROTO(int, (*sorters[2][2]), (char *x, char *y));
|
||||
PROTO(static void, print_symdef_entry, (bfd * abfd));
|
||||
static void
|
||||
print_symbols PARAMS ((bfd *file, asymbol **syms, unsigned long symcount));
|
||||
|
||||
static void
|
||||
print_symdef_entry PARAMS ((bfd * abfd));
|
||||
|
||||
/* Command options. */
|
||||
|
||||
@ -46,6 +49,7 @@ int print_armap = 0; /* describe __.SYMDEF data in archive files. */
|
||||
int reverse_sort = 0; /* sort in downward(alpha or numeric) order */
|
||||
int sort_numerically = 0; /* sort in numeric rather than alpha order */
|
||||
int undefined_only = 0; /* print undefined symbols only */
|
||||
int show_version = 0; /* show the version number */
|
||||
|
||||
boolean print_each_filename = false; /* Ick. Used in archives. */
|
||||
|
||||
@ -53,6 +57,7 @@ boolean print_each_filename = false; /* Ick. Used in archives. */
|
||||
extern char *program_name;
|
||||
extern char *program_version;
|
||||
extern char *target;
|
||||
extern int print_version;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"debug-syms", no_argument, &print_debug_syms, 1},
|
||||
@ -64,6 +69,7 @@ struct option long_options[] = {
|
||||
{"reverse-sort", no_argument, &reverse_sort, 1},
|
||||
{"target", optional_argument, (int *)NULL, 0},
|
||||
{"undefined-only", no_argument, &undefined_only, 1},
|
||||
{"version", no_argument, &show_version, 1},
|
||||
{0, no_argument, 0, 0}
|
||||
};
|
||||
|
||||
@ -74,7 +80,7 @@ int show_names = 0;
|
||||
void
|
||||
usage ()
|
||||
{
|
||||
fprintf(stderr, "nm %s\nUsage: %s [-agnoprsu] filename...\n",
|
||||
fprintf(stderr, "nm %s\nUsage: %s [-agnoprsuV] filename...\n",
|
||||
program_version, program_name);
|
||||
exit(0);
|
||||
}
|
||||
@ -86,12 +92,12 @@ main (argc, argv)
|
||||
{
|
||||
int c; /* sez which option char */
|
||||
int option_index = 0; /* used by getopt and ignored by us */
|
||||
int retval;
|
||||
int retval;
|
||||
program_name = *argv;
|
||||
|
||||
bfd_init();
|
||||
|
||||
while ((c = getopt_long(argc, argv, "agnoprsu", long_options, &option_index)) != EOF) {
|
||||
while ((c = getopt_long(argc, argv, "agnoprsuV", long_options, &option_index)) != EOF) {
|
||||
switch (c) {
|
||||
case 'a': print_debug_syms = 1; break;
|
||||
case 'g': external_only = 1; break;
|
||||
@ -101,25 +107,29 @@ main (argc, argv)
|
||||
case 'r': reverse_sort = 1; break;
|
||||
case 's': print_armap = 1; break;
|
||||
case 'u': undefined_only = 1; break;
|
||||
|
||||
case 'V': show_version = 1; break;
|
||||
|
||||
case 0:
|
||||
if (!strcmp("target",(long_options[option_index]).name)) {
|
||||
target = optarg;
|
||||
}
|
||||
|
||||
|
||||
break; /* we've been given a long option */
|
||||
|
||||
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (show_version)
|
||||
printf ("%s version %s\n", program_name, program_version);
|
||||
|
||||
/* Strangely, for the shell you should return only a nonzero value
|
||||
on sucess -- the inverse of the C sense. */
|
||||
|
||||
|
||||
/* OK, all options now parsed. If no filename specified, do a.out. */
|
||||
if (option_index == argc) return !display_file ("a.out");
|
||||
|
||||
|
||||
retval = 0;
|
||||
show_names = (argc -optind)>1;
|
||||
/* We were given several filenames to do: */
|
||||
@ -132,7 +142,7 @@ main (argc, argv)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** Display a file's stats */
|
||||
/* Display a file's stats */
|
||||
|
||||
/* goto here is marginally cleaner than the nested if syntax */
|
||||
|
||||
@ -143,23 +153,19 @@ display_file (filename)
|
||||
boolean retval = true;
|
||||
bfd *file;
|
||||
bfd *arfile = NULL;
|
||||
|
||||
|
||||
file = bfd_openr(filename, target);
|
||||
if (file == NULL) {
|
||||
fprintf (stderr, "\n%s: can't open '%s'.\n", program_name, filename);
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (bfd_check_format(file, bfd_object))
|
||||
if (bfd_check_format(file, bfd_object))
|
||||
{
|
||||
if (show_names) {
|
||||
printf ("\n%s:\n",filename);
|
||||
}
|
||||
do_one_rel_file (file);
|
||||
|
||||
}
|
||||
else if (bfd_check_format (file, bfd_archive)) {
|
||||
if (!bfd_check_format (file, bfd_archive)) {
|
||||
@ -178,7 +184,7 @@ display_file (filename)
|
||||
bfd_fatal (filename);
|
||||
goto closer;
|
||||
}
|
||||
|
||||
|
||||
if (!bfd_check_format(arfile, bfd_object))
|
||||
printf("%s: not an object file\n", arfile->filename);
|
||||
else {
|
||||
@ -192,7 +198,6 @@ display_file (filename)
|
||||
retval = false;
|
||||
}
|
||||
|
||||
|
||||
closer:
|
||||
if (bfd_close(file) == false)
|
||||
bfd_fatal (filename);
|
||||
@ -200,7 +205,49 @@ display_file (filename)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Symbol-sorting predicates */
|
||||
#define valueof(x) ((x)->section->vma + (x)->value)
|
||||
int
|
||||
numeric_forward (x, y)
|
||||
CONST void *x;
|
||||
CONST void *y;
|
||||
{
|
||||
return (valueof(*(asymbol **)x) - valueof(*(asymbol **) y));
|
||||
}
|
||||
|
||||
int
|
||||
numeric_reverse (x, y)
|
||||
CONST void *x;
|
||||
CONST void *y;
|
||||
{
|
||||
return (valueof(*(asymbol **)y) - valueof(*(asymbol **) x));
|
||||
}
|
||||
|
||||
int
|
||||
non_numeric_forward (x, y)
|
||||
CONST void *x;
|
||||
CONST void *y;
|
||||
{
|
||||
CONST char *xn = (*(asymbol **) x)->name;
|
||||
CONST char *yn = (*(asymbol **) y)->name;
|
||||
|
||||
return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
|
||||
((yn == NULL) ? 1 : strcmp (xn, yn)));
|
||||
}
|
||||
|
||||
int
|
||||
non_numeric_reverse (x, y)
|
||||
CONST void *x;
|
||||
CONST void *y;
|
||||
{
|
||||
return -(non_numeric_forward (x, y));
|
||||
}
|
||||
|
||||
int (*(sorters[2][2])) PARAMS ((CONST void *, CONST void *)) = {
|
||||
{non_numeric_forward, non_numeric_reverse},
|
||||
{numeric_forward, numeric_reverse},
|
||||
};
|
||||
|
||||
static void
|
||||
do_one_rel_file (abfd)
|
||||
bfd *abfd;
|
||||
@ -214,7 +261,6 @@ do_one_rel_file (abfd)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
storage = get_symtab_upper_bound (abfd);
|
||||
if (storage == 0) {
|
||||
nosymz:
|
||||
@ -233,65 +279,18 @@ do_one_rel_file (abfd)
|
||||
(after printing) */
|
||||
|
||||
symcount = filter_symbols (abfd, syms, symcount);
|
||||
|
||||
if (!no_sort)
|
||||
|
||||
if (!no_sort)
|
||||
qsort((char *) syms, symcount, sizeof (asymbol *),
|
||||
sorters[sort_numerically][reverse_sort]);
|
||||
|
||||
if (print_each_filename && !file_on_each_line)
|
||||
printf("\n%s:\n", bfd_get_filename(abfd));
|
||||
|
||||
|
||||
print_symbols (abfd, syms, symcount);
|
||||
free (syms);
|
||||
|
||||
}
|
||||
|
||||
/* Symbol-sorting predicates */
|
||||
#define valueof(x) ((x)->section->vma + (x)->value)
|
||||
int
|
||||
numeric_forward (x, y)
|
||||
char *x;
|
||||
char *y;
|
||||
{
|
||||
|
||||
return (valueof(*(asymbol **)x) - valueof(*(asymbol **) y));;
|
||||
}
|
||||
|
||||
int
|
||||
numeric_reverse (x, y)
|
||||
char *x;
|
||||
char *y;
|
||||
{
|
||||
return (valueof(*(asymbol **)y) - valueof(*(asymbol **) x));
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
non_numeric_forward (x, y)
|
||||
char *x;
|
||||
char *y;
|
||||
{
|
||||
CONST char *xn = (*(asymbol **) x)->name;
|
||||
CONST char *yn = (*(asymbol **) y)->name;
|
||||
|
||||
return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
|
||||
((yn == NULL) ? 1 : strcmp (xn, yn)));
|
||||
}
|
||||
|
||||
int
|
||||
non_numeric_reverse (x, y)
|
||||
char *x;
|
||||
char *y;
|
||||
{
|
||||
return -(non_numeric_forward (x, y));
|
||||
}
|
||||
|
||||
int (*sorters[2][2])() = {
|
||||
{non_numeric_forward, non_numeric_reverse},
|
||||
{numeric_forward, numeric_reverse},
|
||||
};
|
||||
|
||||
|
||||
/* Choose which symbol entries to print;
|
||||
compact them downward to get rid of the rest.
|
||||
Return the number of symbols to be printed. */
|
||||
@ -304,26 +303,23 @@ filter_symbols (abfd, syms, symcount)
|
||||
asymbol **from, **to;
|
||||
unsigned int dst_count = 0;
|
||||
asymbol *sym;
|
||||
|
||||
|
||||
unsigned int src_count;
|
||||
for (from = to = syms, src_count = 0; src_count <symcount; src_count++) {
|
||||
int keep = 0;
|
||||
|
||||
|
||||
|
||||
flagword flags = (from[src_count])->flags;
|
||||
sym = from[src_count];
|
||||
if (undefined_only) {
|
||||
keep = sym->section == &bfd_und_section;
|
||||
} else if (external_only) {
|
||||
keep = ((flags & BSF_GLOBAL)
|
||||
|| (sym->section == &bfd_und_section)
|
||||
keep = ((flags & BSF_GLOBAL)
|
||||
|| (sym->section == &bfd_und_section)
|
||||
|| (sym->section == &bfd_com_section));
|
||||
|
||||
} else {
|
||||
keep = 1;
|
||||
}
|
||||
|
||||
|
||||
if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0)) {
|
||||
keep = 0;
|
||||
}
|
||||
@ -332,7 +328,7 @@ filter_symbols (abfd, syms, symcount)
|
||||
to[dst_count++] = from[src_count];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return dst_count;
|
||||
}
|
||||
|
||||
@ -379,7 +375,7 @@ print_symdef_entry (abfd)
|
||||
}
|
||||
elt = bfd_get_elt_at_index (abfd, idx);
|
||||
if (thesym->name != (char *)NULL) {
|
||||
printf ("%s in %s\n", thesym->name, bfd_get_filename (elt));
|
||||
}
|
||||
printf ("%s in %s\n", thesym->name, bfd_get_filename (elt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,8 +45,10 @@ char *xmalloc ();
|
||||
|
||||
char *default_target = NULL; /* default at runtime */
|
||||
|
||||
extern *program_version;
|
||||
char *program_name = NULL;
|
||||
|
||||
int show_version = 0; /* show the version number */
|
||||
int dump_section_contents; /* -s */
|
||||
int dump_section_headers; /* -h */
|
||||
boolean dump_file_header; /* -f */
|
||||
@ -94,6 +96,7 @@ static struct option long_options[]=
|
||||
{"syms", no_argument, &dump_symtab, 1},
|
||||
{"reloc", no_argument, &dump_reloc_info, 1},
|
||||
{"header", no_argument, &dump_section_headers, 1},
|
||||
{"version", no_argument, &show_version, 1},
|
||||
#ifdef ELF_STAB_DISPLAY
|
||||
{"stabs", no_argument, &dump_stab_section_info, 1},
|
||||
#endif
|
||||
@ -476,6 +479,8 @@ struct stab_print stab_print[] = {
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
void dump_elf_stabs_1 ();
|
||||
|
||||
/* This is a kludge for dumping the stabs section from an ELF file that
|
||||
uses Sun stabs encoding. It has to use some hooks into BFD because
|
||||
string table sections are not normally visible to BFD callers. */
|
||||
@ -484,10 +489,7 @@ void
|
||||
dump_elf_stabs (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
|
||||
char *strtab;
|
||||
struct internal_nlist *stabs, *stabs_end;
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
/* Initialize stab name array if first time. */
|
||||
if (stab_name[0][0] == 0)
|
||||
@ -508,19 +510,35 @@ dump_elf_stabs (abfd)
|
||||
return;
|
||||
}
|
||||
|
||||
stab_hdr = bfd_elf_find_section (abfd, ".stab");
|
||||
dump_elf_stabs_1 (abfd, ".stab", ".stabstr");
|
||||
dump_elf_stabs_1 (abfd, ".stab.excl", ".stab.exclstr");
|
||||
dump_elf_stabs_1 (abfd, ".stab.index", ".stab.indexstr");
|
||||
}
|
||||
|
||||
void
|
||||
dump_elf_stabs_1 (abfd, name1, name2)
|
||||
bfd *abfd;
|
||||
char *name1; /* Section name of .stab */
|
||||
char *name2; /* Section name of its string section */
|
||||
{
|
||||
Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
|
||||
char *strtab;
|
||||
struct internal_nlist *stabs, *stabs_end;
|
||||
int i;
|
||||
unsigned file_string_table_offset, next_file_string_table_offset;
|
||||
|
||||
stab_hdr = bfd_elf_find_section (abfd, name1);
|
||||
if (0 == stab_hdr)
|
||||
{
|
||||
fprintf (stderr, "%s: %s has no .stab section.\n", program_name,
|
||||
abfd->filename);
|
||||
printf ("Contents of %s section: none.\n\n", name1);
|
||||
return;
|
||||
}
|
||||
|
||||
stabstr_hdr = bfd_elf_find_section (abfd, ".stabstr");
|
||||
stabstr_hdr = bfd_elf_find_section (abfd, name2);
|
||||
if (0 == stabstr_hdr)
|
||||
{
|
||||
fprintf (stderr, "%s: %s has no .stabstr section.\n", program_name,
|
||||
abfd->filename);
|
||||
fprintf (stderr, "%s: %s has no %s section.\n", program_name,
|
||||
abfd->filename, name2);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -531,8 +549,8 @@ dump_elf_stabs (abfd)
|
||||
if (bfd_seek (abfd, stab_hdr->sh_offset, L_SET) < 0 ||
|
||||
stab_hdr->sh_size != bfd_read ((PTR)stabs, stab_hdr->sh_size, 1, abfd))
|
||||
{
|
||||
fprintf (stderr, "%s: reading .stab section of %s failed.\n",
|
||||
program_name,
|
||||
fprintf (stderr, "%s: reading %s section of %s failed.\n",
|
||||
program_name, name1,
|
||||
abfd->filename);
|
||||
return;
|
||||
}
|
||||
@ -541,8 +559,8 @@ dump_elf_stabs (abfd)
|
||||
stabstr_hdr->sh_size != bfd_read ((PTR)strtab, stabstr_hdr->sh_size,
|
||||
1, abfd))
|
||||
{
|
||||
fprintf (stderr, "%s: reading .stabstr section of %s failed.\n",
|
||||
program_name,
|
||||
fprintf (stderr, "%s: reading %s section of %s failed.\n",
|
||||
program_name, name2,
|
||||
abfd->filename);
|
||||
return;
|
||||
}
|
||||
@ -557,11 +575,17 @@ dump_elf_stabs (abfd)
|
||||
(unsigned char *)&(symp)->n_value); \
|
||||
}
|
||||
|
||||
printf ("Contents of .stab section:\n\n");
|
||||
printf ("Contents of %s section:\n\n", name1);
|
||||
printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
|
||||
|
||||
/* We start the index at -1 because there is a dummy symbol on
|
||||
file_string_table_offset = 0;
|
||||
next_file_string_table_offset = 0;
|
||||
|
||||
/* Loop through all symbols and print them.
|
||||
|
||||
We start the index at -1 because there is a dummy symbol on
|
||||
the front of Sun's stabs-in-elf sections. */
|
||||
|
||||
for (i = -1; stabs < stabs_end; stabs++, i++)
|
||||
{
|
||||
SWAP_SYMBOL (stabs, abfd);
|
||||
@ -569,14 +593,29 @@ dump_elf_stabs (abfd)
|
||||
stab_name [stabs->n_type],
|
||||
stabs->n_other, stabs->n_desc, stabs->n_value,
|
||||
stabs->n_strx);
|
||||
if (stabs->n_strx < stabstr_hdr->sh_size)
|
||||
printf (" %s", &strtab[stabs->n_strx]);
|
||||
|
||||
/* Symbols with type == 0 (N_UNDF) specify the length of the
|
||||
string table associated with this file. We use that info
|
||||
to know how to relocate the *next* file's string table indices. */
|
||||
|
||||
if (stabs->n_type == N_UNDF)
|
||||
{
|
||||
file_string_table_offset = next_file_string_table_offset;
|
||||
next_file_string_table_offset += stabs->n_value;
|
||||
}
|
||||
|
||||
/* Now, using the possibly updated string table offset, print the
|
||||
string (if any) associated with this symbol. */
|
||||
|
||||
if ((stabs->n_strx + file_string_table_offset) < stabstr_hdr->sh_size)
|
||||
printf (" %s", &strtab[stabs->n_strx + file_string_table_offset]);
|
||||
else
|
||||
printf (" *");
|
||||
}
|
||||
printf ("\n\n");
|
||||
}
|
||||
#endif /* ELF_STAB_DISPLAY */
|
||||
|
||||
void
|
||||
|
||||
display_bfd (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
@ -610,6 +649,7 @@ display_bfd (abfd)
|
||||
PF (DYNAMIC, "DYNAMIC");
|
||||
PF (WP_TEXT, "WP_TEXT");
|
||||
PF (D_PAGED, "D_PAGED");
|
||||
PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
|
||||
printf ("\nstart address 0x");
|
||||
printf_vma (abfd->start_address);
|
||||
}
|
||||
@ -881,7 +921,9 @@ DEFUN (display_info_table, (first, last),
|
||||
bfd_target *p = target_vector[i];
|
||||
bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
|
||||
int l = strlen (p->name);
|
||||
int ok = bfd_set_arch_mach (abfd, j, 0);
|
||||
int ok;
|
||||
bfd_set_format (abfd, bfd_object);
|
||||
ok = bfd_set_arch_mach (abfd, j, 0);
|
||||
|
||||
if (ok)
|
||||
printf ("%s ", p->name);
|
||||
@ -909,7 +951,7 @@ DEFUN_VOID (display_info)
|
||||
{
|
||||
bfd_target *p = target_vector[i];
|
||||
bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
|
||||
|
||||
bfd_set_format (abfd, bfd_object);
|
||||
printf ("%s\n (header %s, data %s)\n", p->name,
|
||||
p->header_byteorder_big_p ? "big endian" : "little endian",
|
||||
p->byteorder_big_p ? "big endian" : "little endian");
|
||||
@ -952,7 +994,7 @@ main (argc, argv)
|
||||
bfd_init ();
|
||||
program_name = *argv;
|
||||
|
||||
while ((c = getopt_long (argc, argv, "ib:m:dlfahrtxsj:", long_options, &ind))
|
||||
while ((c = getopt_long (argc, argv, "ib:m:Vdlfahrtxsj:", long_options, &ind))
|
||||
!= EOF)
|
||||
{
|
||||
seenflag = true;
|
||||
@ -1003,11 +1045,17 @@ main (argc, argv)
|
||||
case 'h':
|
||||
dump_section_headers = 1;
|
||||
break;
|
||||
case 'V':
|
||||
show_version = 1;
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
if (show_version)
|
||||
printf ("%s version %s\n", program_name, program_version);
|
||||
|
||||
if (seenflag == false)
|
||||
usage ();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user