X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fnm.c;h=1b5122d56ab5c00fc710a775053eb2ee300b0665;hb=a78a19b15254de31c3d38b7e27469aaef0a30e97;hp=fd3f73167e085defd041c04e1a3f487ed93c57f0;hpb=25a0274483cb00c27945b0337005be4f169ff09f;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/nm.c b/binutils/nm.c index fd3f73167e..1b5122d56a 100644 --- a/binutils/nm.c +++ b/binutils/nm.c @@ -1,5 +1,5 @@ /* nm.c -- Describe symbol table of a rel file. - Copyright (C) 1991-2019 Free Software Foundation, Inc. + Copyright (C) 1991-2020 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -67,7 +67,6 @@ struct extended_symbol_info coff_symbol_type *coffinfo; /* FIXME: We should add more fields for Type, Line, Section. */ }; -#define SYM_NAME(sym) (sym->sinfo->name) #define SYM_VALUE(sym) (sym->sinfo->value) #define SYM_TYPE(sym) (sym->sinfo->type) #define SYM_STAB_NAME(sym) (sym->sinfo->stab_name) @@ -77,15 +76,15 @@ struct extended_symbol_info (sym->elfinfo ? sym->elfinfo->internal_elf_sym.st_size: sym->ssize) /* The output formatting functions. */ -static void print_object_filename_bsd (char *); -static void print_object_filename_sysv (char *); -static void print_object_filename_posix (char *); -static void print_archive_filename_bsd (char *); -static void print_archive_filename_sysv (char *); -static void print_archive_filename_posix (char *); -static void print_archive_member_bsd (char *, const char *); -static void print_archive_member_sysv (char *, const char *); -static void print_archive_member_posix (char *, const char *); +static void print_object_filename_bsd (const char *); +static void print_object_filename_sysv (const char *); +static void print_object_filename_posix (const char *); +static void print_archive_filename_bsd (const char *); +static void print_archive_filename_sysv (const char *); +static void print_archive_filename_posix (const char *); +static void print_archive_member_bsd (const char *, const char *); +static void print_archive_member_sysv (const char *, const char *); +static void print_archive_member_posix (const char *, const char *); static void print_symbol_filename_bsd (bfd *, bfd *); static void print_symbol_filename_sysv (bfd *, bfd *); static void print_symbol_filename_posix (bfd *, bfd *); @@ -98,13 +97,13 @@ static void print_symbol_info_posix (struct extended_symbol_info *, bfd *); struct output_fns { /* Print the name of an object file given on the command line. */ - void (*print_object_filename) (char *); + void (*print_object_filename) (const char *); /* Print the name of an archive file given on the command line. */ - void (*print_archive_filename) (char *); + void (*print_archive_filename) (const char *); /* Print the name of an archive member file. */ - void (*print_archive_member) (char *, const char *); + void (*print_archive_member) (const char *, const char *); /* Print the name of the file (and archive, if there is one) containing a symbol. */ @@ -142,6 +141,7 @@ static struct output_fns formats[] = /* The output format to use. */ static struct output_fns *format = &formats[FORMAT_DEFAULT]; static unsigned int print_format = FORMAT_DEFAULT; +static const char *print_format_string = NULL; /* Command options. */ @@ -393,8 +393,11 @@ get_coff_symbol_type (const struct internal_syment *sym) demangling it if requested. */ static void -print_symname (const char *form, const char *name, bfd *abfd) +print_symname (const char *form, struct extended_symbol_info *info, + const char *name, bfd *abfd) { + if (name == NULL) + name = info->sinfo->name; if (do_demangle && *name) { char *res = bfd_demangle (abfd, name, demangle_flags); @@ -408,6 +411,17 @@ print_symname (const char *form, const char *name, bfd *abfd) } printf (form, name); + if (info != NULL && info->elfinfo) + { + const char *version_string; + bfd_boolean hidden; + + version_string + = bfd_get_symbol_version_string (abfd, &info->elfinfo->symbol, + FALSE, &hidden); + if (version_string && version_string[0]) + printf ("%s%s", hidden ? "@" : "@@", version_string); + } } static void @@ -432,12 +446,16 @@ print_symdef_entry (bfd *abfd) bfd_fatal ("bfd_get_elt_at_index"); if (thesym->name != (char *) NULL) { - print_symname ("%s", thesym->name, abfd); + print_symname ("%s", NULL, thesym->name, abfd); printf (" in %s\n", bfd_get_filename (elt)); } } } + +/* True when we can report missing plugin error. */ +bfd_boolean report_plugin_err = TRUE; + /* Choose which symbol entries to print; compact them downward to get rid of the rest. Return the number of symbols to be printed. */ @@ -470,9 +488,13 @@ filter_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, if (sym->name[0] == '_' && sym->name[1] == '_' - && strcmp (sym->name + (sym->name[2] == '_'), "__gnu_lto_slim") == 0) - non_fatal (_("%s: plugin needed to handle lto object"), - bfd_get_filename (abfd)); + && strcmp (sym->name + (sym->name[2] == '_'), "__gnu_lto_slim") == 0 + && report_plugin_err) + { + report_plugin_err = FALSE; + non_fatal (_("%s: plugin needed to handle lto object"), + bfd_get_filename (abfd)); + } if (undefined_only) keep = bfd_is_und_section (sym->section); @@ -584,8 +606,8 @@ numeric_forward (const void *P_x, const void *P_y) if (x == NULL || y == NULL) bfd_fatal (bfd_get_filename (sort_bfd)); - xs = bfd_get_section (x); - ys = bfd_get_section (y); + xs = bfd_asymbol_section (x); + ys = bfd_asymbol_section (y); if (bfd_is_und_section (xs)) { @@ -637,8 +659,8 @@ size_forward1 (const void *P_x, const void *P_y) if (x == NULL || y == NULL) bfd_fatal (bfd_get_filename (sort_bfd)); - xs = bfd_get_section (x); - ys = bfd_get_section (y); + xs = bfd_asymbol_section (x); + ys = bfd_asymbol_section (y); if (bfd_is_und_section (xs)) abort (); @@ -766,7 +788,7 @@ sort_symbols_by_size (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, else next = NULL; - sec = bfd_get_section (sym); + sec = bfd_asymbol_section (sym); /* Synthetic symbols don't have a full type set of data available, thus we can't rely on that information for the symbol size. Ditto for @@ -780,11 +802,11 @@ sort_symbols_by_size (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, else { if (from + size < fromend - && sec == bfd_get_section (next)) + && sec == bfd_asymbol_section (next)) sz = valueof (next) - valueof (sym); else - sz = (bfd_get_section_vma (abfd, sec) - + bfd_section_size (abfd, sec) + sz = (bfd_section_vma (sec) + + bfd_section_size (sec) - valueof (sym)); } @@ -885,9 +907,10 @@ print_symbol (bfd * abfd, bfd_boolean hidden = FALSE; if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0) - version_string = bfd_get_symbol_version_string (abfd, sym, &hidden); + version_string = bfd_get_symbol_version_string (abfd, sym, + TRUE, &hidden); - if (bfd_is_und_section (bfd_get_section (sym))) + if (bfd_is_und_section (bfd_asymbol_section (sym))) hidden = TRUE; if (version_string && *version_string != '\0') @@ -923,7 +946,7 @@ print_symbol (bfd * abfd, lineno_cache_bfd = abfd; } - if (bfd_is_und_section (bfd_get_section (sym))) + if (bfd_is_und_section (bfd_asymbol_section (sym))) { static asection **secs; static arelent ***relocs; @@ -993,10 +1016,10 @@ print_symbol (bfd * abfd, } } } - else if (bfd_get_section (sym)->owner == abfd) + else if (bfd_asymbol_section (sym)->owner == abfd) { if ((bfd_find_line (abfd, syms, sym, &filename, &lineno) - || bfd_find_nearest_line (abfd, bfd_get_section (sym), + || bfd_find_nearest_line (abfd, bfd_asymbol_section (sym), syms, sym->value, &filename, &functionname, &lineno)) && filename != NULL @@ -1162,6 +1185,17 @@ display_rel_file (bfd *abfd, bfd *archive_bfd) *symp = 0; symcount += synth_count; } + if (!dynamic && dyn_syms != NULL) + free (dyn_syms); + } + + /* lto_slim_object is set to false when a bfd is loaded with a compiler + LTO plugin. */ + if (abfd->lto_slim_object) + { + report_plugin_err = FALSE; + non_fatal (_("%s: plugin needed to handle lto object"), + bfd_get_filename (abfd)); } /* Discard the symbols we don't want to print. @@ -1199,6 +1233,51 @@ display_rel_file (bfd *abfd, bfd *archive_bfd) free (symsizes); } +/* Construct a formatting string for printing symbol values. */ + +static const char * +get_print_format (void) +{ + const char * padding; + if (print_format == FORMAT_POSIX) + { + /* POSIX compatible output does not have any padding. */ + padding = ""; + } + else if (print_width == 32) + { + padding ="08"; + } + else /* print_width == 64 */ + { + padding = "016"; + } + + const char * length = "l"; + if (print_width == 64) + { +#if BFD_HOST_64BIT_LONG + ; +#elif BFD_HOST_64BIT_LONG_LONG +#ifndef __MSVCRT__ + length = "ll"; +#else + length = "I64"; +#endif +#endif + } + + const char * radix = NULL; + switch (print_radix) + { + case 8: radix = "o"; break; + case 10: radix = "d"; break; + case 16: radix = "x"; break; + } + + return concat ("%", padding, length, radix, NULL); +} + static void set_print_width (bfd *file) { @@ -1217,6 +1296,8 @@ set_print_width (bfd *file) else print_width = 32; } + free ((char *) print_format_string); + print_format_string = get_print_format (); } static void @@ -1340,14 +1421,14 @@ display_file (char *filename) /* Print the name of an object file given on the command line. */ static void -print_object_filename_bsd (char *filename) +print_object_filename_bsd (const char *filename) { if (filename_per_file && !filename_per_symbol) printf ("\n%s:\n", filename); } static void -print_object_filename_sysv (char *filename) +print_object_filename_sysv (const char *filename) { if (undefined_only) printf (_("\n\nUndefined symbols from %s:\n\n"), filename); @@ -1362,7 +1443,7 @@ Name Value Class Type Size } static void -print_object_filename_posix (char *filename) +print_object_filename_posix (const char *filename) { if (filename_per_file && !filename_per_symbol) printf ("%s:\n", filename); @@ -1371,26 +1452,26 @@ print_object_filename_posix (char *filename) /* Print the name of an archive file given on the command line. */ static void -print_archive_filename_bsd (char *filename) +print_archive_filename_bsd (const char *filename) { if (filename_per_file) printf ("\n%s:\n", filename); } static void -print_archive_filename_sysv (char *filename ATTRIBUTE_UNUSED) +print_archive_filename_sysv (const char *filename ATTRIBUTE_UNUSED) { } static void -print_archive_filename_posix (char *filename ATTRIBUTE_UNUSED) +print_archive_filename_posix (const char *filename ATTRIBUTE_UNUSED) { } /* Print the name of an archive member file. */ static void -print_archive_member_bsd (char *archive ATTRIBUTE_UNUSED, +print_archive_member_bsd (const char *archive ATTRIBUTE_UNUSED, const char *filename) { if (!filename_per_symbol) @@ -1398,7 +1479,7 @@ print_archive_member_bsd (char *archive ATTRIBUTE_UNUSED, } static void -print_archive_member_sysv (char *archive, const char *filename) +print_archive_member_sysv (const char *archive, const char *filename) { if (undefined_only) printf (_("\n\nUndefined symbols from %s[%s]:\n\n"), archive, filename); @@ -1413,7 +1494,7 @@ Name Value Class Type Size } static void -print_archive_member_posix (char *archive, const char *filename) +print_archive_member_posix (const char *archive, const char *filename) { if (!filename_per_symbol) printf ("%s[%s]:\n", archive, filename); @@ -1457,58 +1538,6 @@ print_symbol_filename_posix (bfd *archive_bfd, bfd *abfd) } } -/* Construct a formatting string for printing symbol values. */ - -static const char * -get_print_format (void) -{ - static const char * saved_format = NULL; - - /* See if we have already constructed the format. */ - if (saved_format) - return saved_format; - - const char * padding; - if (print_format == FORMAT_POSIX) - { - /* POSIX compatible output does not have any padding. */ - padding = ""; - } - else if (print_width == 32) - { - padding ="08"; - } - else /* print_width == 64 */ - { - padding = "016"; - } - - const char * length = "l"; - if (print_width == 64) - { -#if BFD_HOST_64BIT_LONG - ; -#elif BFD_HOST_64BIT_LONG_LONG -#ifndef __MSVCRT__ - length = "ll"; -#else - length = "I64"; -#endif -#endif - } - - const char * radix = NULL; - switch (print_radix) - { - case 8: radix = "o"; break; - case 10: radix = "d"; break; - case 16: radix = "x"; break; - } - - saved_format = concat ("%", padding, length, radix, NULL); - return saved_format; -} - /* Print a symbol value. */ static void @@ -1517,12 +1546,12 @@ print_value (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma val) switch (print_width) { case 32: - printf (get_print_format (), (unsigned long) val); + printf (print_format_string, (unsigned long) val); break; case 64: #if BFD_HOST_64BIT_LONG || BFD_HOST_64BIT_LONG_LONG - printf (get_print_format (), val); + printf (print_format_string, val); #else /* We have a 64 bit value to print, but the host is only 32 bit. */ if (print_radix == 16) @@ -1591,13 +1620,13 @@ print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd) printf (desc_format, SYM_STAB_DESC (info)); printf (" %5s", SYM_STAB_NAME (info)); } - print_symname (" %s", SYM_NAME (info), abfd); + print_symname (" %s", info, NULL, abfd); } static void print_symbol_info_sysv (struct extended_symbol_info *info, bfd *abfd) { - print_symname ("%-20s|", SYM_NAME (info), abfd); + print_symname ("%-20s|", info, NULL, abfd); if (bfd_is_undefined_symclass (SYM_TYPE (info))) { @@ -1652,7 +1681,7 @@ print_symbol_info_sysv (struct extended_symbol_info *info, bfd *abfd) static void print_symbol_info_posix (struct extended_symbol_info *info, bfd *abfd) { - print_symname ("%s ", SYM_NAME (info), abfd); + print_symname ("%s ", info, NULL, abfd); printf ("%c ", SYM_TYPE (info)); if (bfd_is_undefined_symclass (SYM_TYPE (info)))