📄 nm.c
字号:
static voidprint_symname (format, name, abfd) const char *format; const char *name; bfd *abfd;{ if (do_demangle && *name) { char *res; /* In this mode, give a user-level view of the symbol name even if it's not mangled; strip off any leading underscore. */ if (bfd_get_symbol_leading_char (abfd) == name[0]) name++; res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); if (res) { printf (format, res); free (res); return; } } printf (format, name);}/* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */static voidprint_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd) bfd *abfd; boolean dynamic; PTR minisyms; long symcount; unsigned int size; bfd *archive_bfd;{ asymbol *store; bfd_byte *from, *fromend; store = bfd_make_empty_symbol (abfd); if (store == NULL) bfd_fatal (bfd_get_filename (abfd)); from = (bfd_byte *) minisyms; fromend = from + symcount * size; for (; from < fromend; from += size) { asymbol *sym; sym = bfd_minisymbol_to_symbol (abfd, dynamic, from, store); if (sym == NULL) bfd_fatal (bfd_get_filename (abfd)); print_symbol (abfd, sym, archive_bfd); }}/* Print the symbols when sorting by size. */static void print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd) bfd *abfd; boolean dynamic; struct size_sym *symsizes; long symcount; bfd *archive_bfd;{ asymbol *store; struct size_sym *from, *fromend; store = bfd_make_empty_symbol (abfd); if (store == NULL) bfd_fatal (bfd_get_filename (abfd)); from = symsizes; fromend = from + symcount; for (; from < fromend; from++) { asymbol *sym; sym = bfd_minisymbol_to_symbol (abfd, dynamic, from->minisym, store); if (sym == NULL) bfd_fatal (bfd_get_filename (abfd)); /* Set the symbol value so that we actually display the symbol size. */ sym->value = from->size - bfd_section_vma (abfd, bfd_get_section (sym)); print_symbol (abfd, sym, archive_bfd); }}/* Print a single symbol. */static voidprint_symbol (abfd, sym, archive_bfd) bfd *abfd; asymbol *sym; bfd *archive_bfd;{ PROGRESS (1); (*format->print_symbol_filename) (archive_bfd, abfd); if (undefined_only) { if (bfd_is_und_section (bfd_get_section (sym))) print_symname ("%s", bfd_asymbol_name (sym), abfd); } else { symbol_info syminfo; bfd_get_symbol_info (abfd, sym, &syminfo); (*format->print_symbol_info) (&syminfo, abfd); } if (line_numbers) { static asymbol **syms; static long symcount; const char *filename, *functionname; unsigned int lineno; /* We need to get the canonical symbols in order to call bfd_find_nearest_line. This is inefficient, but, then, you don't have to use --line-numbers. */ if (abfd != lineno_cache_bfd && syms != NULL) { free (syms); syms = NULL; } if (syms == NULL) { long symsize; symsize = bfd_get_symtab_upper_bound (abfd); if (symsize < 0) bfd_fatal (bfd_get_filename (abfd)); syms = (asymbol **) xmalloc (symsize); symcount = bfd_canonicalize_symtab (abfd, syms); if (symcount < 0) bfd_fatal (bfd_get_filename (abfd)); lineno_cache_bfd = abfd; } if (bfd_is_und_section (bfd_get_section (sym))) { static asection **secs; static arelent ***relocs; static long *relcount; static unsigned int seccount; unsigned int i; const char *symname; /* For an undefined symbol, we try to find a reloc for the symbol, and print the line number of the reloc. */ if (abfd != lineno_cache_rel_bfd && relocs != NULL) { for (i = 0; i < seccount; i++) if (relocs[i] != NULL) free (relocs[i]); free (secs); free (relocs); free (relcount); secs = NULL; relocs = NULL; relcount = NULL; } if (relocs == NULL) { struct get_relocs_info info; seccount = bfd_count_sections (abfd); secs = (asection **) xmalloc (seccount * sizeof *secs); relocs = (arelent ***) xmalloc (seccount * sizeof *relocs); relcount = (long *) xmalloc (seccount * sizeof *relcount); info.secs = secs; info.relocs = relocs; info.relcount = relcount; info.syms = syms; bfd_map_over_sections (abfd, get_relocs, (PTR) &info); lineno_cache_rel_bfd = abfd; } symname = bfd_asymbol_name (sym); for (i = 0; i < seccount; i++) { long j; for (j = 0; j < relcount[i]; j++) { arelent *r; r = relocs[i][j]; if (r->sym_ptr_ptr != NULL && (*r->sym_ptr_ptr)->section == sym->section && (*r->sym_ptr_ptr)->value == sym->value && strcmp (symname, bfd_asymbol_name (*r->sym_ptr_ptr)) == 0 && bfd_find_nearest_line (abfd, secs[i], syms, r->address, &filename, &functionname, &lineno)) { /* We only print the first one we find. */ printf ("\t%s:%u", filename, lineno); i = seccount; break; } } } } else if (bfd_get_section (sym)->owner == abfd) { if (bfd_find_nearest_line (abfd, bfd_get_section (sym), syms, sym->value, &filename, &functionname, &lineno) && filename != NULL && lineno != 0) { printf ("\t%s:%u", filename, lineno); } } } putchar ('\n');}/* The following 3 groups of functions are called unconditionally, once at the start of processing each file of the appropriate type. They should check `filename_per_file' and `filename_per_symbol', as appropriate for their output format, to determine whether to print anything. *//* Print the name of an object file given on the command line. */static voidprint_object_filename_bsd (filename) char *filename;{ if (filename_per_file && !filename_per_symbol) printf ("\n%s:\n", filename);}static voidprint_object_filename_sysv (filename) char *filename;{ if (undefined_only) printf (_("\n\nUndefined symbols from %s:\n\n"), filename); else printf (_("\n\nSymbols from %s:\n\n"), filename); printf (_("\Name Value Class Type Size Line Section\n\n"));}static voidprint_object_filename_posix (filename) char *filename;{ if (filename_per_file && !filename_per_symbol) printf ("%s:\n", filename);}/* Print the name of an archive file given on the command line. */static voidprint_archive_filename_bsd (filename) char *filename;{ if (filename_per_file) printf ("\n%s:\n", filename);}static voidprint_archive_filename_sysv (filename) char *filename ATTRIBUTE_UNUSED;{}static voidprint_archive_filename_posix (filename) char *filename ATTRIBUTE_UNUSED;{}/* Print the name of an archive member file. */static voidprint_archive_member_bsd (archive, filename) char *archive ATTRIBUTE_UNUSED; CONST char *filename;{ if (!filename_per_symbol) printf ("\n%s:\n", filename);}static voidprint_archive_member_sysv (archive, filename) char *archive; CONST char *filename;{ if (undefined_only) printf (_("\n\nUndefined symbols from %s[%s]:\n\n"), archive, filename); else printf (_("\n\nSymbols from %s[%s]:\n\n"), archive, filename); printf (_("\Name Value Class Type Size Line Section\n\n"));}static voidprint_archive_member_posix (archive, filename) char *archive; CONST char *filename;{ if (!filename_per_symbol) printf ("%s[%s]:\n", archive, filename);}/* Print the name of the file (and archive, if there is one) containing a symbol. */static voidprint_symbol_filename_bsd (archive_bfd, abfd) bfd *archive_bfd, *abfd;{ if (filename_per_symbol) { if (archive_bfd) printf ("%s:", bfd_get_filename (archive_bfd)); printf ("%s:", bfd_get_filename (abfd)); }}static voidprint_symbol_filename_sysv (archive_bfd, abfd) bfd *archive_bfd, *abfd;{ if (filename_per_symbol) { if (archive_bfd) printf ("%s:", bfd_get_filename (archive_bfd)); printf ("%s:", bfd_get_filename (abfd)); }}static voidprint_symbol_filename_posix (archive_bfd, abfd) bfd *archive_bfd, *abfd;{ if (filename_per_symbol) { if (archive_bfd) printf ("%s[%s]: ", bfd_get_filename (archive_bfd), bfd_get_filename (abfd)); else printf ("%s: ", bfd_get_filename (abfd)); }}/* Print a symbol value. */static voidprint_value (val) bfd_vma val;{#if ! defined (BFD64) || BFD_HOST_64BIT_LONG printf (value_format, val);#else /* We have a 64 bit value to print, but the host is only 32 bit. */ if (print_radix == 16) fprintf_vma (stdout, val); else { char buf[30]; char *s; s = buf + sizeof buf; *--s = '\0'; while (val > 0) { *--s = (val % print_radix) + '0'; val /= print_radix; } while ((buf + sizeof buf - 1) - s < 16) *--s = '0'; printf ("%s", s); }#endif}/* Print a line of information about a symbol. */static voidprint_symbol_info_bsd (info, abfd) symbol_info *info; bfd *abfd;{ if (bfd_is_undefined_symclass (info->type)) {#ifdef BFD64 printf (" ");#endif printf (" "); } else print_value (info->value); printf (" %c", info->type); if (info->type == '-') { /* A stab. */ printf (" "); printf (other_format, info->stab_other); printf (" "); printf (desc_format, info->stab_desc); printf (" %5s", info->stab_name); } print_symname (" %s", info->name, abfd);}static voidprint_symbol_info_sysv (info, abfd) symbol_info *info; bfd *abfd;{ print_symname ("%-20s|", info->name, abfd); /* Name */ if (bfd_is_undefined_symclass (info->type)) printf (" "); /* Value */ else print_value (info->value); printf ("| %c |", info->type); /* Class */ if (info->type == '-') { /* A stab. */ printf ("%18s| ", info->stab_name); /* (C) Type */ printf (desc_format, info->stab_desc); /* Size */ printf ("| |"); /* Line, Section */ } else printf (" | | |"); /* Type, Size, Line, Section */}static voidprint_symbol_info_posix (info, abfd) symbol_info *info; bfd *abfd;{ print_symname ("%s ", info->name, abfd); printf ("%c ", info->type); if (bfd_is_undefined_symclass (info->type)) printf (" "); else print_value (info->value); /* POSIX.2 wants the symbol size printed here, when applicable; BFD currently doesn't provide it, so we take the easy way out by considering it to never be applicable. */}static voidprint_symdef_entry (abfd) bfd *abfd;{ symindex idx = BFD_NO_MORE_SYMBOLS; carsym *thesym; boolean everprinted = false; for (idx = bfd_get_next_mapent (abfd, idx, &thesym); idx != BFD_NO_MORE_SYMBOLS; idx = bfd_get_next_mapent (abfd, idx, &thesym)) { bfd *elt; if (!everprinted) { printf (_("\nArchive index:\n")); everprinted = true; } elt = bfd_get_elt_at_index (abfd, idx); if (elt == NULL) bfd_fatal ("bfd_get_elt_at_index"); if (thesym->name != (char *) NULL) { print_symname ("%s", thesym->name, abfd); printf (" in %s\n", bfd_get_filename (elt)); } }}/* This function is used to get the relocs for a particular section. It is called via bfd_map_over_sections. */static voidget_relocs (abfd, sec, dataarg) bfd *abfd; asection *sec; PTR dataarg;{ struct get_relocs_info *data = (struct get_relocs_info *) dataarg; *data->secs = sec; if ((sec->flags & SEC_RELOC) == 0) { *data->relocs = NULL; *data->relcount = 0; } else { long relsize; relsize = bfd_get_reloc_upper_bound (abfd, sec); if (relsize < 0) bfd_fatal (bfd_get_filename (abfd)); *data->relocs = (arelent **) xmalloc (relsize); *data->relcount = bfd_canonicalize_reloc (abfd, sec, *data->relocs, data->syms); if (*data->relcount < 0) bfd_fatal (bfd_get_filename (abfd)); } ++data->secs; ++data->relocs; ++data->relcount;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -