1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print symbol information from ELF file in human-readable form. 2587c4b3e94c6ef877137d067d5d0f574f69b1391Mark Wielaard Copyright (C) 2000-2008, 2009, 2011, 2012, 2014, 2015 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2000. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of the GNU General Public License as published by 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the Free Software Foundation; either version 3 of the License, or 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard (at your option) any later version. 10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard GNU General Public License for more details. 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received a copy of the GNU General Public License 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <ar.h> 24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h> 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <ctype.h> 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <dwarf.h> 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <errno.h> 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h> 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <gelf.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <inttypes.h> 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libdw.h> 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <locale.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <obstack.h> 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <search.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio.h> 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio_ext.h> 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/param.h> 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <system.h> 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "../libebl/libeblP.h" 4870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard#include "../libdwfl/libdwflP.h" 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program. */ 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state); 53fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address. */ 56fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Values for the parameters which have no short form. */ 602356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper#define OPT_DEFINED 0x100 612356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper#define OPT_MARK_SPECIAL 0x101 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions. */ 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] = 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Output selection:"), 0 }, 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "debug-syms", 'a', NULL, 0, N_("Display debugger-only symbols"), 0 }, 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "defined-only", OPT_DEFINED, NULL, 0, N_("Display only defined symbols"), 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 0 }, 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "dynamic", 'D', NULL, 0, 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Display dynamic symbols instead of normal symbols"), 0 }, 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "extern-only", 'g', NULL, 0, N_("Display only external symbols"), 0 }, 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "undefined-only", 'u', NULL, 0, N_("Display only undefined symbols"), 0 }, 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "print-armap", 's', NULL, 0, 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Include index for symbols from archive members"), 0 }, 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Output format:"), 0 }, 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "print-file-name", 'A', NULL, 0, 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Print name of the input file before every symbol"), 0 }, 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 'o', NULL, OPTION_HIDDEN, "Same as -A", 0 }, 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "format", 'f', "FORMAT", 0, 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Use the output format FORMAT. FORMAT can be `bsd', `sysv' or `posix'. The default is `sysv'"), 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 0 }, 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 'B', NULL, 0, N_("Same as --format=bsd"), 0 }, 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "portability", 'P', NULL, 0, N_("Same as --format=posix"), 0 }, 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "radix", 't', "RADIX", 0, N_("Use RADIX for printing symbol values"), 0 }, 872356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper { "mark-special", OPT_MARK_SPECIAL, NULL, 0, N_("Mark special symbols"), 0 }, 882356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper { "mark-weak", OPT_MARK_SPECIAL, NULL, OPTION_HIDDEN, "", 0 }, 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "print-size", 'S', NULL, 0, N_("Print size of defined symbols"), 0 }, 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Output options:"), 0 }, 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "numeric-sort", 'n', NULL, 0, N_("Sort symbols numerically by address"), 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 0 }, 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "no-sort", 'p', NULL, 0, N_("Do not sort the symbols"), 0 }, 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "reverse-sort", 'r', NULL, 0, N_("Reverse the sense of the sort"), 0 }, 96b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 97b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper { "demangle", 'C', NULL, 0, 98b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper N_("Decode low-level symbol names into source code names"), 0 }, 99b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, NULL, 0 } 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program. */ 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("List symbols from FILEs (a.out by default)."); 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts. */ 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("[FILE...]"); 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler. */ 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 113c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper/* Parser children. */ 114c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepperstatic struct argp_child argp_children[] = 115c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper { 116c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper { &color_argp, 0, N_("Output formatting"), 2 }, 117c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper { NULL, 0, NULL, 0} 118c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper }; 119c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions. */ 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp = 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 123c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper options, parse_opt, args_doc, doc, argp_children, NULL, NULL 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print symbols in file named FNAME. */ 128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int process_file (const char *fname, bool more_than_one); 129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle content of archive. */ 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *suffix); 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle ELF file. */ 13570cd907e38757283f3696465771f723a342cc3d1Mark Wielaardstatic int handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *suffix); 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define INTERNAL_ERROR(fname) \ 140587c4b3e94c6ef877137d067d5d0f574f69b1391Mark Wielaard error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"), \ 141587c4b3e94c6ef877137d067d5d0f574f69b1391Mark Wielaard fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)) 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Internal representation of symbols. */ 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppertypedef struct GElf_SymX 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym; 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndx; 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *where; 150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} GElf_SymX; 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* User-selectable options. */ 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* The selected output format. */ 156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic enum 157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format_sysv = 0, 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format_bsd, 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format_posix 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} format; 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print defined, undefined, or both? */ 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool hide_undefined; 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool hide_defined; 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print local symbols also? */ 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool hide_local; 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Nonzero if full filename should precede every symbol. */ 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool print_file_name; 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If true print size of defined symbols in BSD format. */ 174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool print_size; 175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If true print archive index. */ 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool print_armap; 178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If true reverse sorting. */ 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool reverse_sort; 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 182b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 183b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper/* If true demangle symbols. */ 184b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepperstatic bool demangle; 185b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 186b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Type of the section we are printing. */ 188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic GElf_Word symsec_type = SHT_SYMTAB; 189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Sorting selection. */ 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic enum 192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sort_name = 0, 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sort_numeric, 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sort_nosort 196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} sort; 197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Radix for printed numbers. */ 199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic enum 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper radix_hex = 0, 202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper radix_decimal, 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper radix_octal 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} radix; 205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2062356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper/* If nonzero mark special symbols: 2072356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper - weak symbols are distinguished from global symbols by adding 2082356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper a `*' after the identifying letter for the symbol class and type. 2092356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper - TLS symbols are distinguished from normal symbols by adding 2102356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper a '@' after the identifying letter for the symbol class and type. */ 2112356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepperstatic bool mark_special; 212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[]) 216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int remaining; 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = 0; 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We use no threads here which can interfere with handling a stream. */ 221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); 222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); 223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER); 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set locale. */ 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) setlocale (LC_ALL, ""); 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the message catalog can be found. */ 229b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Initialize the message catalog. */ 232b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper (void) textdomain (PACKAGE_TARNAME); 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Parse and process arguments. */ 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); 236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Tell the library which version we are expecting. */ 238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) elf_version (EV_CURRENT); 239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (remaining == argc) 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The user didn't specify a name so we use a.out. */ 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = process_file ("a.out", false); 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Process all the remaining files. */ 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const bool more_than_one = remaining + 1 < argc; 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result |= process_file (argv[remaining], more_than_one); 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (++remaining < argc); 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information. */ 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 261b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper fprintf (stream, "nm (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("\ 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCopyright (C) %s Red Hat, Inc.\n\ 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions. There is NO\n\ 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 2663a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper"), "2012"); 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments. */ 272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt (int key, char *arg, 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct argp_state *state __attribute__ ((unused))) 275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'a': 279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX */ 280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 282b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 283b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper case 'C': 284b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper demangle = true; 285b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper break; 286b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 287b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'f': 289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (arg, "bsd") == 0) 290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format = format_bsd; 291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (strcmp (arg, "posix") == 0) 292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format = format_posix; 293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Be bug compatible. The BFD implementation also defaulted to 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper using the SysV format if nothing else matches. */ 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format = format_sysv; 297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'g': 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper hide_local = true; 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'n': 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sort = sort_numeric; 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'p': 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sort = sort_nosort; 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 't': 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (arg, "10") == 0 || strcmp (arg, "d") == 0) 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper radix = radix_decimal; 314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (strcmp (arg, "8") == 0 || strcmp (arg, "o") == 0) 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper radix = radix_octal; 316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper radix = radix_hex; 318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'u': 321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper hide_undefined = false; 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper hide_defined = true; 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'A': 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'o': 327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper print_file_name = true; 328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'B': 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format = format_bsd; 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'D': 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper symsec_type = SHT_DYNSYM; 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'P': 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format = format_posix; 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case OPT_DEFINED: 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper hide_undefined = true; 344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper hide_defined = false; 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3472356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper case OPT_MARK_SPECIAL: 3482356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper mark_special = true; 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'S': 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper print_size = true; 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 's': 356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper print_armap = true; 357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'r': 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reverse_sort = true; 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Open the file and determine the type. */ 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_file (const char *fname, bool more_than_one) 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Open the file. */ 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fd = open (fname, O_RDONLY); 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fd == -1) 377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("cannot open '%s'"), fname); 379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now get the ELF descriptor. */ 383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf != NULL) 385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_kind (elf) == ELF_K_ELF) 387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 38870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard int result = handle_elf (fd, elf, more_than_one ? "" : NULL, 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname, NULL); 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (elf) != 0) 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (close (fd) != 0) 395d112ef86686e4f47aad5b30ee38b4618a2bea611Ulrich Drepper error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname); 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (elf_kind (elf) == ELF_K_AR) 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = handle_ar (fd, elf, NULL, fname, NULL); 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (elf) != 0) 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (close (fd) != 0) 407d112ef86686e4f47aad5b30ee38b4618a2bea611Ulrich Drepper error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname); 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We cannot handle this type. Close the descriptor anyway. */ 413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (elf) != 0) 414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s: File format not recognized"), fname); 418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperhandle_ar (int fd, Elf *elf, const char *prefix, const char *fname, 425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *suffix) 426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t fname_len = strlen (fname) + 1; 428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t prefix_len = prefix != NULL ? strlen (prefix) : 0; 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_prefix[prefix_len + fname_len + 2]; 430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t suffix_len = suffix != NULL ? strlen (suffix) : 0; 431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_suffix[suffix_len + 2]; 432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *subelf; 433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Cmd cmd = ELF_C_READ_MMAP; 434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = 0; 435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = new_prefix; 437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = stpcpy (cp, prefix); 439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = stpcpy (cp, fname); 440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stpcpy (cp, "["); 441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = new_suffix; 443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (suffix != NULL) 444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = stpcpy (cp, suffix); 445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stpcpy (cp, "]"); 446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* First print the archive index if this is wanted. */ 448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (print_armap) 449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Arsym *arsym = elf_getarsym (elf, NULL); 451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (arsym != NULL) 453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Arhdr *arhdr = NULL; 455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t arhdr_off = 0; /* Note: 0 is no valid offset. */ 456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 457c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper fputs_unlocked (gettext("\nArchive index:\n"), stdout); 458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (arsym->as_off != 0) 460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (arhdr_off != arsym->as_off 462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (elf_rand (elf, arsym->as_off) != arsym->as_off 463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (subelf = elf_begin (fd, cmd, elf)) == NULL 464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (arhdr = elf_getarhdr (subelf)) == NULL)) 465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("invalid offset %zu for symbol %s"), 467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arsym->as_off, arsym->as_name); 4680b799ad9822f4866aaf1eb34564681e83bdaf9f1Mark Wielaard break; 469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf (gettext ("%s in %s\n"), arsym->as_name, arhdr->ar_name); 472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++arsym; 474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_rand (elf, SARMAG) != SARMAG) 477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, 479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("cannot reset archive offset to beginning")); 480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Process all the files contained in the archive. */ 486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The the header for this element. */ 489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Arhdr *arhdr = elf_getarhdr (subelf); 490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Skip over the index entries. */ 492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (arhdr->ar_name, "/") != 0 4938fb260f7137a231caf250dbe4ba64fcebd33b68dMark Wielaard && strcmp (arhdr->ar_name, "//") != 0 4948fb260f7137a231caf250dbe4ba64fcebd33b68dMark Wielaard && strcmp (arhdr->ar_name, "/SYM64/") != 0) 495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_kind (subelf) == ELF_K_ELF) 49770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_suffix); 499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (elf_kind (subelf) == ELF_K_AR) 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, 501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_suffix); 502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s%s%s: file format not recognized"), 505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_prefix, arhdr->ar_name, new_suffix); 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get next archive element. */ 511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cmd = elf_next (subelf); 512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (subelf) != 0) 513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Mapping of radix and binary class to length. */ 521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const int length_map[2][3] = 522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [ELFCLASS32 - 1] = 524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [radix_hex] = 8, 526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [radix_decimal] = 10, 527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [radix_octal] = 11 528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }, 529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [ELFCLASS64 - 1] = 530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [radix_hex] = 16, 532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [radix_decimal] = 20, 533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [radix_octal] = 22 534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperglobal_compare (const void *p1, const void *p2) 540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const Dwarf_Global *g1 = (const Dwarf_Global *) p1; 542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const Dwarf_Global *g2 = (const Dwarf_Global *) p2; 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return strcmp (g1->name, g2->name); 545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void *global_root; 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperget_global (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global, 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper void *arg __attribute__ ((unused))) 554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper tsearch (memcpy (xmalloc (sizeof (Dwarf_Global)), global, 556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sizeof (Dwarf_Global)), 557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &global_root, global_compare); 558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return DWARF_CB_OK; 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct local_name 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name; 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *file; 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word lineno; 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr lowpc; 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr highpc; 570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperlocal_compare (const void *p1, const void *p2) 575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct local_name *g1 = (struct local_name *) p1; 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct local_name *g2 = (struct local_name *) p2; 578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result; 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = strcmp (g1->name, g2->name); 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (result == 0) 582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (g1->lowpc <= g2->lowpc && g1->highpc >= g2->highpc) 584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* g2 is contained in g1. Update the data. */ 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper g2->lowpc = g1->lowpc; 587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper g2->highpc = g1->highpc; 588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 0; 589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (g2->lowpc <= g1->lowpc && g2->highpc >= g1->highpc) 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* g1 is contained in g2. Update the data. */ 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper g1->lowpc = g2->lowpc; 594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper g1->highpc = g2->highpc; 595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 0; 596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = g1->lowpc < g2->lowpc ? -1 : 1; 599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperget_var_range (Dwarf_Die *die, Dwarf_Word *lowpc, Dwarf_Word *highpc) 607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Attribute locattr_mem; 609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Attribute *locattr = dwarf_attr (die, DW_AT_location, &locattr_mem); 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (locattr == NULL) 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6136724c90d02659f7466b67b357563042e403d154eRoland McGrath Dwarf_Op *loc; 614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t nloc; 6156724c90d02659f7466b67b357563042e403d154eRoland McGrath if (dwarf_getlocation (locattr, &loc, &nloc) != 0) 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Interpret the location expressions. */ 619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX For now just the simple one: 620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (nloc == 1 && loc[0].atom == DW_OP_addr) 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *lowpc = *highpc = loc[0].number; 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void *local_root; 632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperget_local_names (Dwarf *dbg) 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Off offset = 0; 638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Off old_offset; 639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t hsize; 640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (dwarf_nextcu (dbg, old_offset = offset, &offset, &hsize, NULL, NULL, 642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NULL) == 0) 643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Die cudie_mem; 645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Die *cudie = dwarf_offdie (dbg, old_offset + hsize, &cudie_mem); 646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we cannot get the CU DIE there is no need to go on with 648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper this CU. */ 649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cudie == NULL) 650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This better be a CU DIE. */ 652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dwarf_tag (cudie) != DW_TAG_compile_unit) 653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the line information. */ 656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Files *files; 657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t nfiles; 658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dwarf_getsrcfiles (cudie, &files, &nfiles) != 0) 659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Die die_mem; 662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Die *die = &die_mem; 663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dwarf_child (cudie, die) == 0) 664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Iterate over all immediate children of the CU DIE. */ 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int tag = dwarf_tag (die); 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (tag != DW_TAG_subprogram && tag != DW_TAG_variable) 669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We are interested in five attributes: name, decl_file, 672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper decl_line, low_pc, and high_pc. */ 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Attribute attr_mem; 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Attribute *attr = dwarf_attr (die, DW_AT_name, &attr_mem); 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name = dwarf_formstring (attr); 676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (name == NULL) 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word fileidx; 680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper attr = dwarf_attr (die, DW_AT_decl_file, &attr_mem); 681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dwarf_formudata (attr, &fileidx) != 0 || fileidx >= nfiles) 682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Word lineno; 685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper attr = dwarf_attr (die, DW_AT_decl_line, &attr_mem); 686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dwarf_formudata (attr, &lineno) != 0 || lineno == 0) 687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr lowpc; 690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr highpc; 691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (tag == DW_TAG_subprogram) 692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dwarf_lowpc (die, &lowpc) != 0 694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || dwarf_highpc (die, &highpc) != 0) 695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (get_var_range (die, &lowpc, &highpc) != 0) 700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have all the information. Create a record. */ 704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct local_name *newp 705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = (struct local_name *) xmalloc (sizeof (*newp)); 706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->name = name; 707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->file = dwarf_filesrc (files, fileidx, NULL, NULL); 708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->lineno = lineno; 709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->lowpc = lowpc; 710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->highpc = highpc; 711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 7123fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard /* Check whether a similar local_name is already in the 7133fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard cache. That should not happen. But if it does, we 7143fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard don't want to leak memory. */ 7153fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard struct local_name **tres = tsearch (newp, &local_root, 7163fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard local_compare); 7173fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard if (tres == NULL) 7183fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard error (EXIT_FAILURE, errno, 7193fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard gettext ("cannot create search tree")); 7203fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard else if (*tres != newp) 7213fbd857267a6bffc57225857690aaa383ac58426Mark Wielaard free (newp); 722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (dwarf_siblingof (die, die) == 0); 724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 727468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath/* Do elf_strptr, but return a backup string and never NULL. */ 728468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrathstatic const char * 729468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrathsym_name (Elf *elf, GElf_Word strndx, GElf_Word st_name, char buf[], size_t n) 730468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath{ 731468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath const char *symstr = elf_strptr (elf, strndx, st_name); 732468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath if (symstr == NULL) 733468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath { 734468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath snprintf (buf, n, "[invalid st_name %#" PRIx32 "]", st_name); 735468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath symstr = buf; 736468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath } 737468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath return symstr; 738468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath} 739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 740b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Show symbols in SysV format. */ 741b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 742c8920de1429631ab53b8a388acdd3f8064305bd3Marek Polacekshow_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname, 743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_SymX *syms, size_t nsyms, int longest_name, 744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int longest_where) 745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t shnum; 747f189493154d0041deced00e6a99cc5426dc9d260Ulrich Drepper if (elf_getshdrnum (ebl->elf, &shnum) < 0) 748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fullname); 749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool scnnames_malloced = shnum * sizeof (const char *) > 128 * 1024; 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char **scnnames; 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnnames_malloced) 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scnnames = (const char **) xmalloc (sizeof (const char *) * shnum); 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scnnames = (const char **) alloca (sizeof (const char *) * shnum); 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the section header string table index. */ 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t shstrndx; 758f189493154d0041deced00e6a99cc5426dc9d260Ulrich Drepper if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (EXIT_FAILURE, 0, 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("cannot get section header string table index")); 761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cache the section names. */ 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt = 1; 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 76903d76f4aec5e750b81198c7a24571e119e754b40Mark Wielaard assert (elf_ndxscn (scn) == cnt); 77003d76f4aec5e750b81198c7a24571e119e754b40Mark Wielaard cnt++; 771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 772468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath char *name = elf_strptr (ebl->elf, shstrndx, 773468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath gelf_getshdr (scn, &shdr_mem)->sh_name); 774468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath if (unlikely (name == NULL)) 775468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath { 7767df3d2cd70932cd70515dbeb75e4db66fd27f192Mark Wielaard const size_t bufsz = sizeof "[invalid sh_name 0x12345678]"; 77757bd66cabf6e6b9ecf622cdbf350804897a8df58Roland McGrath name = alloca (bufsz); 77857bd66cabf6e6b9ecf622cdbf350804897a8df58Roland McGrath snprintf (name, bufsz, "[invalid sh_name %#" PRIx32 "]", 779468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath gelf_getshdr (scn, &shdr_mem)->sh_name); 780468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath } 781468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath scnnames[elf_ndxscn (scn)] = name; 782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 783b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 784b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int digits = length_map[gelf_getclass (ebl->elf) - 1][radix]; 785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We always print this prolog. */ 787c8920de1429631ab53b8a388acdd3f8064305bd3Marek Polacek printf (gettext ("\n\nSymbols from %s:\n\n"), fullname); 788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The header line. */ 790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf (gettext ("%*s%-*s %-*s Class Type %-*s %*s Section\n\n"), 791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper print_file_name ? (int) strlen (fullname) + 1: 0, "", 792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper longest_name, sgettext ("sysv|Name"), 793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* TRANS: the "sysv|" parts makes the string unique. */ 794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper digits, sgettext ("sysv|Value"), 795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* TRANS: the "sysv|" parts makes the string unique. */ 796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper digits, sgettext ("sysv|Size"), 797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* TRANS: the "sysv|" parts makes the string unique. */ 798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper longest_where, sgettext ("sysv|Line")); 799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 800b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 801b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper size_t demangle_buffer_len = 0; 802b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper char *demangle_buffer = NULL; 803b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 804b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Iterate over all symbols. */ 80666f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper for (cnt = 1; cnt < nsyms; ++cnt) 807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 80866f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper /* In this format SECTION entries are not printed. */ 80966f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper if (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_SECTION) 81066f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper continue; 81166f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper 812468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath char symstrbuf[50]; 813468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath const char *symstr = sym_name (ebl->elf, strndx, syms[cnt].sym.st_name, 814468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath symstrbuf, sizeof symstrbuf); 815468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath 816b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 8177c6e785e6eca774080a64801f950bd61785c469eJan Kratochvil /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ 8187c6e785e6eca774080a64801f950bd61785c469eJan Kratochvil if (demangle && symstr[0] == '_' && symstr[1] == 'Z') 819b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper { 820b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper int status = -1; 821b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, 822b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper &demangle_buffer_len, &status); 823b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 824b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper if (status == 0) 825b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper symstr = dmsymstr; 826b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper } 827b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 828b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char symbindbuf[50]; 830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char symtypebuf[50]; 831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char secnamebuf[1024]; 83266f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper char addressbuf[(64 + 2) / 3 + 1]; 83366f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper char sizebuf[(64 + 2) / 3 + 1]; 834b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have to precede the line with the file name. */ 836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (print_file_name) 837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fputs_unlocked (fullname, stdout); 839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper putchar_unlocked (':'); 840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 84266f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper /* Covert the address. */ 84366f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper if (syms[cnt].sym.st_shndx == SHN_UNDEF) 84466f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper addressbuf[0] = sizebuf[0] = '\0'; 84566f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper else 84666f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper { 847f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard snprintf (addressbuf, sizeof (addressbuf), 848f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard (radix == radix_hex ? "%0*" PRIx64 849f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard : (radix == radix_decimal ? "%0*" PRId64 850f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard : "%0*" PRIo64)), 85166f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper digits, syms[cnt].sym.st_value); 852f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard snprintf (sizebuf, sizeof (sizebuf), 853f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard (radix == radix_hex ? "%0*" PRIx64 854f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard : (radix == radix_decimal ? "%0*" PRId64 855f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard : "%0*" PRIo64)), 85666f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper digits, syms[cnt].sym.st_size); 85766f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper } 85866f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper 859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Print the actual string. */ 86066f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper printf ("%-*s|%s|%-6s|%-8s|%s|%*s|%s\n", 86166f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper longest_name, symstr, addressbuf, 862b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_symbol_binding_name (ebl, 863b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GELF_ST_BIND (syms[cnt].sym.st_info), 864b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper symbindbuf, sizeof (symbindbuf)), 865b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_symbol_type_name (ebl, GELF_ST_TYPE (syms[cnt].sym.st_info), 866b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper symtypebuf, sizeof (symtypebuf)), 86766f4c37d497bdde040a33f299b12163f044b1bf2Ulrich Drepper sizebuf, longest_where, syms[cnt].where, 868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_name (ebl, syms[cnt].sym.st_shndx, syms[cnt].xndx, 869b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper secnamebuf, sizeof (secnamebuf), scnnames, 870b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shnum)); 871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 873b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 874b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper free (demangle_buffer); 875b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 876b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnnames_malloced) 878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (scnnames); 879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 882b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic char 8832356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepperclass_type_char (Elf *elf, const GElf_Ehdr *ehdr, GElf_Sym *sym) 884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int local_p = GELF_ST_BIND (sym->st_info) == STB_LOCAL; 886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 887b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Add support for architecture specific types and classes. */ 888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx == SHN_ABS) 889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return local_p ? 'a' : 'A'; 890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx == SHN_UNDEF) 892b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Undefined symbols must be global. */ 893b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 'U'; 894b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 8952356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper char result = "NDTSFBD "[GELF_ST_TYPE (sym->st_info)]; 8962356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper 8972356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper if (result == 'D') 8982356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper { 8992356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper /* Special handling: unique data symbols. */ 9002356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper if (ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX 9012356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper && GELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE) 9022356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper result = 'u'; 9032356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper else 9042356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper { 9052356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper GElf_Shdr shdr_mem; 9062356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, sym->st_shndx), 9072356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper &shdr_mem); 9082356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper if (shdr != NULL) 9092356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper { 9102356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper if ((shdr->sh_flags & SHF_WRITE) == 0) 9112356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper result = 'R'; 9122356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper else if (shdr->sh_type == SHT_NOBITS) 9132356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper result = 'B'; 9142356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper } 9152356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper } 9162356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper } 917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return local_p ? tolower (result) : result; 919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 920b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 921b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 922b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 9232356ba04aeb670b90925ae88c3e579d75085a381Ulrich Dreppershow_symbols_bsd (Elf *elf, const GElf_Ehdr *ehdr, GElf_Word strndx, 924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *prefix, const char *fname, const char *fullname, 925b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_SymX *syms, size_t nsyms) 926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int digits = length_map[gelf_getclass (elf) - 1][radix]; 928b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 929b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL && ! print_file_name) 930b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("\n%s:\n", fname); 931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 932b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 933b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper size_t demangle_buffer_len = 0; 934b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper char *demangle_buffer = NULL; 935b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 936b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 937b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Iterate over all symbols. */ 938b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < nsyms; ++cnt) 939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 940468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath char symstrbuf[50]; 941468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath const char *symstr = sym_name (elf, strndx, syms[cnt].sym.st_name, 942468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath symstrbuf, sizeof symstrbuf); 943b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 944b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Printing entries with a zero-length name makes the output 945b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper not very well parseable. Since these entries don't carry 946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper much information we leave them out. */ 947b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symstr[0] == '\0') 948b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 950c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper /* We do not print the entries for files. */ 951c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper if (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_FILE) 952c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper continue; 953c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper 954b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 9557c6e785e6eca774080a64801f950bd61785c469eJan Kratochvil /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ 9567c6e785e6eca774080a64801f950bd61785c469eJan Kratochvil if (demangle && symstr[0] == '_' && symstr[1] == 'Z') 957b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper { 958b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper int status = -1; 959b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, 960b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper &demangle_buffer_len, &status); 961b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 962b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper if (status == 0) 963b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper symstr = dmsymstr; 964b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper } 965b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 966b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have to precede the line with the file name. */ 968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (print_file_name) 969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fputs_unlocked (fullname, stdout); 971b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper putchar_unlocked (':'); 972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 974c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper bool is_tls = GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_TLS; 975c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper bool is_weak = GELF_ST_BIND (syms[cnt].sym.st_info) == STB_WEAK; 976c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper const char *marker = (mark_special 977c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper ? (is_tls ? "@" : (is_weak ? "*" : " ")) : ""); 978c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper 979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (syms[cnt].sym.st_shndx == SHN_UNDEF) 980c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper { 981c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper const char *color = ""; 982c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper if (color_mode) 983c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper { 984c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper if (is_tls) 985c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper color = color_undef_tls; 986c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper else if (is_weak) 987c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper color = color_undef_weak; 988c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper else 989c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper color = color_undef; 990c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper } 991c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper 992c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper printf ("%*s %sU%s %s", digits, "", color, marker, symstr); 993c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper } 994b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 995c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper { 996c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper const char *color = ""; 997c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper if (color_mode) 998c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper { 999c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper if (is_tls) 1000c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper color = color_tls; 1001c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper else if (is_weak) 1002c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper color = color_weak; 1003c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper else 1004c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper color = color_symbol; 1005c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper } 1006f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard if (print_size && syms[cnt].sym.st_size != 0) 1007f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard { 1008f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#define HEXFMT "%6$s%2$0*1$" PRIx64 "%8$s %10$0*9$" PRIx64 " %7$s%3$c%4$s %5$s" 1009f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#define DECFMT "%6$s%2$*1$" PRId64 "%8$s %10$*9$" PRId64 " %7$s%3$c%4$s %5$s" 1010f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#define OCTFMT "%6$s%2$0*1$" PRIo64 "%8$s %10$0*9$" PRIo64 " %7$s%3$c%4$s %5$s" 1011f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard printf ((radix == radix_hex ? HEXFMT 1012f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard : (radix == radix_decimal ? DECFMT : OCTFMT)), 1013f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard digits, syms[cnt].sym.st_value, 1014f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard class_type_char (elf, ehdr, &syms[cnt].sym), marker, 1015f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard symstr, 1016f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard color_mode ? color_address : "", 1017f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard color, 1018f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard color_mode ? color_off : "", 1019f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard digits, (uint64_t) syms[cnt].sym.st_size); 1020f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#undef HEXFMT 1021f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#undef DECFMT 1022f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#undef OCTFMT 1023f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard } 1024f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard else 1025f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard { 1026f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#define HEXFMT "%6$s%2$0*1$" PRIx64 "%8$s %7$s%3$c%4$s %5$s" 1027f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#define DECFMT "%6$s%2$*1$" PRId64 "%8$s %7$s%3$c%4$s %5$s" 1028f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#define OCTFMT "%6$s%2$0*1$" PRIo64 "%8$s %7$s%3$c%4$s %5$s" 1029f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard printf ((radix == radix_hex ? HEXFMT 1030f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard : (radix == radix_decimal ? DECFMT : OCTFMT)), 1031f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard digits, syms[cnt].sym.st_value, 1032f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard class_type_char (elf, ehdr, &syms[cnt].sym), marker, 1033f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard symstr, 1034f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard color_mode ? color_address : "", 1035f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard color, 1036f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard color_mode ? color_off : ""); 1037f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#undef HEXFMT 1038f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#undef DECFMT 1039f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard#undef OCTFMT 1040f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard } 1041c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper } 1042c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper 1043c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper if (color_mode) 1044c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper fputs_unlocked (color_off, stdout); 1045c6b3d0c27833c8e0936cb6b8973e8578e3a9421fUlrich Drepper putchar_unlocked ('\n'); 1046b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1047b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 1048b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 1049b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper free (demangle_buffer); 1050b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 1051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1052b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1053b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1054b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 10552356ba04aeb670b90925ae88c3e579d75085a381Ulrich Dreppershow_symbols_posix (Elf *elf, const GElf_Ehdr *ehdr, GElf_Word strndx, 10562356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper const char *prefix, const char *fullname, GElf_SymX *syms, 10572356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper size_t nsyms) 1058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL && ! print_file_name) 1060b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("%s:\n", fullname); 1061b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1062b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int digits = length_map[gelf_getclass (elf) - 1][radix]; 1063b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1064b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 1065b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper size_t demangle_buffer_len = 0; 1066b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper char *demangle_buffer = NULL; 1067b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 1068b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 1069b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Iterate over all symbols. */ 1070b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < nsyms; ++cnt) 1071b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1072468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath char symstrbuf[50]; 1073468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath const char *symstr = sym_name (elf, strndx, syms[cnt].sym.st_name, 1074468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath symstrbuf, sizeof symstrbuf); 1075b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Printing entries with a zero-length name makes the output 1077b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper not very well parseable. Since these entries don't carry 1078b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper much information we leave them out. */ 1079b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symstr[0] == '\0') 1080b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1081b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1082b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 10837c6e785e6eca774080a64801f950bd61785c469eJan Kratochvil /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ 10847c6e785e6eca774080a64801f950bd61785c469eJan Kratochvil if (demangle && symstr[0] == '_' && symstr[1] == 'Z') 1085b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper { 1086b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper int status = -1; 1087b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, 1088b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper &demangle_buffer_len, &status); 1089b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 1090b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper if (status == 0) 1091b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper symstr = dmsymstr; 1092b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper } 1093b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 1094b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 1095b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have to precede the line with the file name. */ 1096b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (print_file_name) 1097b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1098b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fputs_unlocked (fullname, stdout); 1099b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper putchar_unlocked (':'); 1100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper putchar_unlocked (' '); 1101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1103f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard printf ((radix == radix_hex 1104f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard ? "%s %c%s %0*" PRIx64 " %0*" PRIx64 "\n" 1105f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard : (radix == radix_decimal 1106f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard ? "%s %c%s %*" PRId64 " %*" PRId64 "\n" 1107f48eb6b15fee66e54b488d71738979fc608f25eeMark Wielaard : "%s %c%s %0*" PRIo64 " %0*" PRIo64 "\n")), 1108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper symstr, 11092356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper class_type_char (elf, ehdr, &syms[cnt].sym), 11102356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper mark_special 11112356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper ? (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_TLS 11122356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper ? "@" 11132356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper : (GELF_ST_BIND (syms[cnt].sym.st_info) == STB_WEAK 11142356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper ? "*" : " ")) 1115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper : "", 1116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper digits, syms[cnt].sym.st_value, 1117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper digits, syms[cnt].sym.st_size); 1118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1119b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 1120b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 1121b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper free (demangle_buffer); 1122b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 1123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Maximum size of memory we allocate on the stack. */ 1127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define MAX_STACK_ALLOC 65536 1128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1129cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrathstatic int 1130cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrathsort_by_address (const void *p1, const void *p2) 1131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1132cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath GElf_SymX *s1 = (GElf_SymX *) p1; 1133cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath GElf_SymX *s2 = (GElf_SymX *) p2; 1134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1135cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath int result = (s1->sym.st_value < s2->sym.st_value 1136cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath ? -1 : (s1->sym.st_value == s2->sym.st_value ? 0 : 1)); 1137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1138cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath return reverse_sort ? -result : result; 1139cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath} 1140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1141cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrathstatic Elf_Data *sort_by_name_strtab; 1142cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 1143cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrathstatic int 1144cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrathsort_by_name (const void *p1, const void *p2) 1145cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath{ 1146cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath GElf_SymX *s1 = (GElf_SymX *) p1; 1147cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath GElf_SymX *s2 = (GElf_SymX *) p2; 1148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1149cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath const char *n1 = sort_by_name_strtab->d_buf + s1->sym.st_name; 1150cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath const char *n2 = sort_by_name_strtab->d_buf + s2->sym.st_name; 1151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1152cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath int result = strcmp (n1, n2); 1153cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 1154cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath return reverse_sort ? -result : result; 1155cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath} 1156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 115770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard/* Stub libdwfl callback, only the ELF handle already open is ever 115870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard used. Only used for finding the alternate debug file if the Dwarf 115970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard comes from the main file. We are not interested in separate 116070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard debuginfo. */ 116170cd907e38757283f3696465771f723a342cc3d1Mark Wielaardstatic int 116270cd907e38757283f3696465771f723a342cc3d1Mark Wielaardfind_no_debuginfo (Dwfl_Module *mod, 116370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard void **userdata, 116470cd907e38757283f3696465771f723a342cc3d1Mark Wielaard const char *modname, 116570cd907e38757283f3696465771f723a342cc3d1Mark Wielaard Dwarf_Addr base, 116670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard const char *file_name, 116770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard const char *debuglink_file, 116870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard GElf_Word debuglink_crc, 116970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard char **debuginfo_file_name) 117070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard{ 117170cd907e38757283f3696465771f723a342cc3d1Mark Wielaard Dwarf_Addr dwbias; 117270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL); 117370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard 117470cd907e38757283f3696465771f723a342cc3d1Mark Wielaard /* We are only interested if the Dwarf has been setup on the main 117570cd907e38757283f3696465771f723a342cc3d1Mark Wielaard elf file but is only missing the alternate debug link. If dwbias 117670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard hasn't even been setup, this is searching for separate debuginfo 117770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard for the main elf. We don't care in that case. */ 117870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard if (dwbias == (Dwarf_Addr) -1) 117970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard return -1; 118070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard 118170cd907e38757283f3696465771f723a342cc3d1Mark Wielaard return dwfl_standard_find_debuginfo (mod, userdata, modname, base, 118270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard file_name, debuglink_file, 118370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard debuglink_crc, debuginfo_file_name); 118470cd907e38757283f3696465771f723a342cc3d1Mark Wielaard} 118570cd907e38757283f3696465771f723a342cc3d1Mark Wielaard 118670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard/* Get the Dwarf for the module/file we want. */ 118770cd907e38757283f3696465771f723a342cc3d1Mark Wielaardstruct getdbg 118870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard{ 118970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard const char *name; 119070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard Dwarf **dbg; 119170cd907e38757283f3696465771f723a342cc3d1Mark Wielaard}; 119270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard 119370cd907e38757283f3696465771f723a342cc3d1Mark Wielaardstatic int 119470cd907e38757283f3696465771f723a342cc3d1Mark Wielaardgetdbg_dwflmod (Dwfl_Module *dwflmod, 119570cd907e38757283f3696465771f723a342cc3d1Mark Wielaard void **userdata __attribute__ ((unused)), 119670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard const char *name, 119770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard Dwarf_Addr base __attribute__ ((unused)), 119870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard void *arg) 119970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard{ 120070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard struct getdbg *get = (struct getdbg *) arg; 120170cd907e38757283f3696465771f723a342cc3d1Mark Wielaard if (get != NULL && get->name != NULL && strcmp (get->name, name) == 0) 120270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard { 120370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard Dwarf_Addr bias; 120470cd907e38757283f3696465771f723a342cc3d1Mark Wielaard *get->dbg = dwfl_module_getdwarf (dwflmod, &bias); 120570cd907e38757283f3696465771f723a342cc3d1Mark Wielaard return DWARF_CB_ABORT; 120670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard } 120770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard 120870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard return DWARF_CB_OK; 120970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard} 121070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard 1211cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrathstatic void 121270cd907e38757283f3696465771f723a342cc3d1Mark Wielaardshow_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr, 121370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard Elf_Scn *scn, Elf_Scn *xndxscn, 1214cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath GElf_Shdr *shdr, const char *prefix, const char *fname, 1215cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath const char *fullname) 1216cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath{ 1217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the section header string table index. */ 1218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t shstrndx; 1219f189493154d0041deced00e6a99cc5426dc9d260Ulrich Drepper if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) 1220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (EXIT_FAILURE, 0, 1221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("cannot get section header string table index")); 1222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The section is that large. */ 1224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t size = shdr->sh_size; 1225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* One entry is this large. */ 1226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t entsize = shdr->sh_entsize; 1227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Consistency checks. */ 1229309e712fea93473ac9b1aa361456fce8d3867baaMark Wielaard if (entsize == 0 1230a2b964c7dbbf54162b2c50931c172568fb4cfa70Mark Wielaard || entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)) 1231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, 1232309e712fea93473ac9b1aa361456fce8d3867baaMark Wielaard gettext ("%s: entry size in section %zd `%s' is not what we expect"), 1233309e712fea93473ac9b1aa361456fce8d3867baaMark Wielaard fullname, elf_ndxscn (scn), 1234309e712fea93473ac9b1aa361456fce8d3867baaMark Wielaard elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); 1235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (size % entsize != 0) 1236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, 1237309e712fea93473ac9b1aa361456fce8d3867baaMark Wielaard gettext ("%s: size of section %zd `%s' is not multiple of entry size"), 1238309e712fea93473ac9b1aa361456fce8d3867baaMark Wielaard fullname, elf_ndxscn (scn), 1239309e712fea93473ac9b1aa361456fce8d3867baaMark Wielaard elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); 1240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compute number of entries. Handle buggy entsize values. */ 1242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t nentries = size / (entsize ?: 1); 1243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define obstack_chunk_alloc xmalloc 1246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define obstack_chunk_free free 1247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct obstack whereob; 1248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper obstack_init (&whereob); 1249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get a DWARF debugging descriptor. It's no problem if this isn't 1251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper possible. We just won't print any line number information. */ 1252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf *dbg = NULL; 125370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard Dwfl *dwfl = NULL; 1254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (format == format_sysv) 1255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 125670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard if (ehdr->e_type != ET_REL) 125770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard dbg = dwarf_begin_elf (ebl->elf, DWARF_C_READ, NULL); 125870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard else 125970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard { 126070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard /* Abuse libdwfl to do the relocations for us. This is just 126170cd907e38757283f3696465771f723a342cc3d1Mark Wielaard for the ET_REL file containing Dwarf, so no need for 126270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard fancy lookups. */ 126370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard 126470cd907e38757283f3696465771f723a342cc3d1Mark Wielaard /* Duplicate an fd for dwfl_report_offline to swallow. */ 126570cd907e38757283f3696465771f723a342cc3d1Mark Wielaard int dwfl_fd = dup (fd); 126670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard if (likely (dwfl_fd >= 0)) 126770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard { 126870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard static const Dwfl_Callbacks callbacks = 126970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard { 127070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard .section_address = dwfl_offline_section_address, 127170cd907e38757283f3696465771f723a342cc3d1Mark Wielaard .find_debuginfo = find_no_debuginfo 127270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard }; 127370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard dwfl = dwfl_begin (&callbacks); 127470cd907e38757283f3696465771f723a342cc3d1Mark Wielaard if (likely (dwfl != NULL)) 127570cd907e38757283f3696465771f723a342cc3d1Mark Wielaard { 127670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard /* Let 0 be the logical address of the file (or 127770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard first in archive). */ 127870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard dwfl->offline_next_address = 0; 127970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) 128070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard == NULL) 128170cd907e38757283f3696465771f723a342cc3d1Mark Wielaard { 128270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard /* Consumed on success, not on failure. */ 128370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard close (dwfl_fd); 128470cd907e38757283f3696465771f723a342cc3d1Mark Wielaard } 128570cd907e38757283f3696465771f723a342cc3d1Mark Wielaard else 128670cd907e38757283f3696465771f723a342cc3d1Mark Wielaard { 128770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard dwfl_report_end (dwfl, NULL, NULL); 128870cd907e38757283f3696465771f723a342cc3d1Mark Wielaard 128970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard struct getdbg get = { .name = fname, .dbg = &dbg }; 129070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard dwfl_getmodules (dwfl, &getdbg_dwflmod, &get, 0); 129170cd907e38757283f3696465771f723a342cc3d1Mark Wielaard } 129270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard } 129370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard } 129470cd907e38757283f3696465771f723a342cc3d1Mark Wielaard } 1295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dbg != NULL) 1296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) dwarf_getpubnames (dbg, get_global, NULL, 0); 1298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper get_local_names (dbg); 1300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1303c08079a076420f67742be98d060500965eb22340Mark Wielaard /* Get the data of the section. */ 1304c08079a076420f67742be98d060500965eb22340Mark Wielaard Elf_Data *data = elf_getdata (scn, NULL); 1305c08079a076420f67742be98d060500965eb22340Mark Wielaard Elf_Data *xndxdata = elf_getdata (xndxscn, NULL); 1306c08079a076420f67742be98d060500965eb22340Mark Wielaard if (data == NULL || (xndxscn != NULL && xndxdata == NULL)) 1307c08079a076420f67742be98d060500965eb22340Mark Wielaard INTERNAL_ERROR (fullname); 1308c08079a076420f67742be98d060500965eb22340Mark Wielaard 1309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate the memory. 1310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper XXX We can use a dirty trick here. Since GElf_Sym == Elf64_Sym we 1312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper can use the data memory instead of copying again if what we read 1313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is a 64 bit file. */ 1314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_SymX *sym_mem; 1315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (nentries * sizeof (GElf_SymX) < MAX_STACK_ALLOC) 1316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym_mem = (GElf_SymX *) alloca (nentries * sizeof (GElf_SymX)); 1317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym_mem = (GElf_SymX *) xmalloc (nentries * sizeof (GElf_SymX)); 1319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Iterate over all symbols. */ 1321b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 1322b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper size_t demangle_buffer_len = 0; 1323b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper char *demangle_buffer = NULL; 1324b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 1325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int longest_name = 4; 1326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int longest_where = 4; 1327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t nentries_used = 0; 1328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < nentries; ++cnt) 1329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, cnt, 1331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &sym_mem[nentries_used].sym, 1332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &sym_mem[nentries_used].xndx); 1333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 1334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fullname); 1335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Filter out administrative symbols without a name and those 1337b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper deselected by the user with command line options. */ 1338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((hide_undefined && sym->st_shndx == SHN_UNDEF) 1339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (hide_defined && sym->st_shndx != SHN_UNDEF) 1340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (hide_local && GELF_ST_BIND (sym->st_info) == STB_LOCAL)) 1341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym_mem[nentries_used].where = ""; 1344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (format == format_sysv) 1345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *symstr = elf_strptr (ebl->elf, shdr->sh_link, 1347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym->st_name); 1348468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath if (symstr == NULL) 1349468fe4d81a3e92157f4c0446675487dc230b2ec6Roland McGrath continue; 1350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1351b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 13527c6e785e6eca774080a64801f950bd61785c469eJan Kratochvil /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ 13537c6e785e6eca774080a64801f950bd61785c469eJan Kratochvil if (demangle && symstr[0] == '_' && symstr[1] == 'Z') 1354b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper { 1355b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper int status = -1; 1356b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, 1357b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper &demangle_buffer_len, &status); 1358b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 1359b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper if (status == 0) 1360b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper symstr = dmsymstr; 1361b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper } 1362b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 1363b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper 1364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper longest_name = MAX ((size_t) longest_name, strlen (symstr)); 1365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != SHN_UNDEF 1367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_BIND (sym->st_info) != STB_LOCAL 1368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && global_root != NULL) 1369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Global fake = { .name = symstr }; 1371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Global **found = tfind (&fake, &global_root, 1372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper global_compare); 1373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (found != NULL) 1374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Die die_mem; 1376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Die *die = dwarf_offdie (dbg, (*found)->die_offset, 1377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &die_mem); 1378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Die cudie_mem; 1380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Die *cudie = NULL; 1381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr lowpc; 1383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Addr highpc; 1384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (die != NULL 1385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dwarf_lowpc (die, &lowpc) == 0 1386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && lowpc <= sym->st_value 1387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dwarf_highpc (die, &highpc) == 0 1388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && highpc > sym->st_value) 1389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cudie = dwarf_offdie (dbg, (*found)->cu_offset, 1390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &cudie_mem); 1391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cudie != NULL) 1392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Dwarf_Line *line = dwarf_getsrc_die (cudie, 1394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym->st_value); 1395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (line != NULL) 1396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We found the line. */ 1398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int lineno; 1399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) dwarf_lineno (line, &lineno); 1400a3344c7a785888ecd31475efaaf456db41897423Mark Wielaard const char *file = dwarf_linesrc (line, NULL, NULL); 1401a3344c7a785888ecd31475efaaf456db41897423Mark Wielaard file = (file != NULL) ? basename (file) : "???"; 1402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int n; 1403a3344c7a785888ecd31475efaaf456db41897423Mark Wielaard n = obstack_printf (&whereob, "%s:%d%c", file, 1404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper lineno, '\0'); 1405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym_mem[nentries_used].where 1406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = obstack_finish (&whereob); 1407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The return value of obstack_print included the 1409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NUL byte, so subtract one. */ 1410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (--n > (int) longest_where) 1411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper longest_where = (size_t) n; 1412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1417b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper /* Try to find the symbol among the local symbols. */ 1418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym_mem[nentries_used].where[0] == '\0') 1419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct local_name fake = 1421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .name = symstr, 1423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .lowpc = sym->st_value, 1424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .highpc = sym->st_value, 1425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct local_name **found = tfind (&fake, &local_root, 1427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper local_compare); 1428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (found != NULL) 1429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We found the line. */ 1431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int n = obstack_printf (&whereob, "%s:%" PRIu64 "%c", 1432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper basename ((*found)->file), 1433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (*found)->lineno, 1434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper '\0'); 1435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym_mem[nentries_used].where = obstack_finish (&whereob); 1436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The return value of obstack_print included the 1438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NUL byte, so subtract one. */ 1439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (--n > (int) longest_where) 1440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper longest_where = (size_t) n; 1441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We use this entry. */ 1446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++nentries_used; 1447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1448b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#ifdef USE_DEMANGLE 1449b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper free (demangle_buffer); 1450b4a16cf0c61746e9b2414570e82e0efcfdf1e721Ulrich Drepper#endif 1451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now we know the exact number. */ 1452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper nentries = nentries_used; 1453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Sort the entries according to the users wishes. */ 1455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sort == sort_name) 1456cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath { 1457cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath sort_by_name_strtab = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), 1458cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath NULL); 1459cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_name); 1460cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath } 1461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (sort == sort_numeric) 1462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_address); 1463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Finally print according to the users selection. */ 1465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (format) 1466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case format_sysv: 1468c8920de1429631ab53b8a388acdd3f8064305bd3Marek Polacek show_symbols_sysv (ebl, shdr->sh_link, fullname, sym_mem, nentries, 1469c8920de1429631ab53b8a388acdd3f8064305bd3Marek Polacek longest_name, longest_where); 1470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case format_bsd: 14732356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper show_symbols_bsd (ebl->elf, ehdr, shdr->sh_link, prefix, fname, fullname, 1474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym_mem, nentries); 1475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case format_posix: 1478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 1479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (format == format_posix); 14802356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper show_symbols_posix (ebl->elf, ehdr, shdr->sh_link, prefix, fullname, 14812356ba04aeb670b90925ae88c3e579d75085a381Ulrich Drepper sym_mem, nentries); 1482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Free all memory. */ 14869beaa94e56fb8b717f838e02905e100647138bf9Mark Wielaard if (nentries * sizeof (sym_mem[0]) >= MAX_STACK_ALLOC) 1487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (sym_mem); 1488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper obstack_free (&whereob, NULL); 1490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dbg != NULL) 1492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper tdestroy (global_root, free); 1494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper global_root = NULL; 1495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper tdestroy (local_root, free); 1497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper local_root = NULL; 1498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 149970cd907e38757283f3696465771f723a342cc3d1Mark Wielaard if (dwfl == NULL) 150070cd907e38757283f3696465771f723a342cc3d1Mark Wielaard (void) dwarf_end (dbg); 1501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 150270cd907e38757283f3696465771f723a342cc3d1Mark Wielaard if (dwfl != NULL) 150370cd907e38757283f3696465771f723a342cc3d1Mark Wielaard dwfl_end (dwfl); 1504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 150870cd907e38757283f3696465771f723a342cc3d1Mark Wielaardhandle_elf (int fd, Elf *elf, const char *prefix, const char *fname, 1509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *suffix) 1510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 1512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t suffix_len = suffix == NULL ? 0 : strlen (suffix); 1513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t fname_len = strlen (fname) + 1; 1514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char fullname[prefix_len + 1 + fname_len + suffix_len]; 1515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = fullname; 1516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 1517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int any = 0; 1518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = 0; 1519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr ehdr_mem; 1520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr *ehdr; 1521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl; 1522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the backend for this object file type. */ 1524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl = ebl_openbackend (elf); 1525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We need the ELF header in a few places. */ 1527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr = gelf_getehdr (elf, &ehdr_mem); 1528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr == NULL) 1529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fullname); 1530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we are asked to print the dynamic symbol table and this is 1532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper executable or dynamic executable, fail. */ 1533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symsec_type == SHT_DYNSYM 1534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Add machine specific object file types. */ 1537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s%s%s%s: Invalid operation"), 1538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper prefix ?: "", prefix ? "(" : "", fname, prefix ? ")" : ""); 1539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 1540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto out; 1541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the full name of the file. */ 1544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 1545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, prefix, prefix_len); 1546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, fname, fname_len); 1547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (suffix != NULL) 1548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (cp - 1, suffix, suffix_len + 1); 1549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Find the symbol table. 1551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper XXX Can there be more than one? Do we print all? Currently we do. */ 1553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (elf, scn)) != NULL) 1554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 1556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 1559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fullname); 1560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type == symsec_type) 1562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *xndxscn = NULL; 1564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have a symbol table. First make sure we remember this. */ 1566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper any = 1; 1567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Look for an extended section index table for this section. */ 1569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symsec_type == SHT_SYMTAB) 1570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t scnndx = elf_ndxscn (scn); 1572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((xndxscn = elf_nextscn (elf, xndxscn)) != NULL) 1574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr xndxshdr_mem; 1576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); 1577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxshdr == NULL) 1579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fullname); 1580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX 1582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && xndxshdr->sh_link == scnndx) 1583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 158770cd907e38757283f3696465771f723a342cc3d1Mark Wielaard show_symbols (fd, ebl, ehdr, scn, xndxscn, shdr, prefix, fname, 1588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fullname); 1589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! any) 1593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s%s%s: no symbols"), 1595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper prefix ?: "", prefix ? ":" : "", fname); 1596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 1597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out: 1600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Close the ELF backend library descriptor. */ 1601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_closebackend (ebl); 1602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 1604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 16053cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 16063cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 16073cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper#include "debugpred.h" 1608