125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print information from ELF file in human-readable form. 225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Copyright (C) 1999-2012 Red Hat, Inc. 325b3c049e70834cf33790a28643ab058b507b35cBen Cheng This file is part of Red Hat elfutils. 425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Written by Ulrich Drepper <drepper@redhat.com>, 1999. 525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is free software; you can redistribute it and/or modify 725b3c049e70834cf33790a28643ab058b507b35cBen Cheng it under the terms of the GNU General Public License as published by the 825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Free Software Foundation; version 2 of the License. 925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is distributed in the hope that it will be useful, but 1125b3c049e70834cf33790a28643ab058b507b35cBen Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 1225b3c049e70834cf33790a28643ab058b507b35cBen Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1325b3c049e70834cf33790a28643ab058b507b35cBen Cheng General Public License for more details. 1425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1525b3c049e70834cf33790a28643ab058b507b35cBen Cheng You should have received a copy of the GNU General Public License along 1625b3c049e70834cf33790a28643ab058b507b35cBen Cheng with Red Hat elfutils; if not, write to the Free Software Foundation, 1725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 1825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is an included package of the Open Invention Network. 2025b3c049e70834cf33790a28643ab058b507b35cBen Cheng An included package of the Open Invention Network is a package for which 2125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Open Invention Network licensees cross-license their patents. No patent 2225b3c049e70834cf33790a28643ab058b507b35cBen Cheng license is granted, either expressly or impliedly, by designation as an 2325b3c049e70834cf33790a28643ab058b507b35cBen Cheng included package. Should you wish to participate in the Open Invention 2425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Network licensing program, please visit www.openinventionnetwork.com 2525b3c049e70834cf33790a28643ab058b507b35cBen Cheng <http://www.openinventionnetwork.com>. */ 2625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef HAVE_CONFIG_H 2825b3c049e70834cf33790a28643ab058b507b35cBen Cheng# include <config.h> 2925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 3025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 3125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <argp.h> 3225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <assert.h> 3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <ctype.h> 3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <dwarf.h> 3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <errno.h> 3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <error.h> 3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <fcntl.h> 3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <gelf.h> 3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <inttypes.h> 4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <langinfo.h> 4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libdw.h> 4225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libdwfl.h> 4325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libintl.h> 4425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <locale.h> 4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdarg.h> 4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdbool.h> 4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdlib.h> 4825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <string.h> 4925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <time.h> 5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <unistd.h> 5125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/param.h> 5225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/stat.h> 5325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <system.h> 5525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "../libelf/libelfP.h" 5625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "../libelf/common.h" 5725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "../libebl/libeblP.h" 5825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "../libdw/libdwP.h" 5925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "../libdwfl/libdwflP.h" 6025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "../libdw/memory-access.h" 6125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 6225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 6325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Name and version of program. */ 6425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_version (FILE *stream, struct argp_state *state); 6525b3c049e70834cf33790a28643ab058b507b35cBen ChengARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 6625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 6725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Bug report address. */ 6825b3c049e70834cf33790a28643ab058b507b35cBen ChengARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 6925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 7025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Definitions of arguments for argp functions. */ 7125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct argp_option options[] = 7225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 7325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 }, 7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "all", 'a', NULL, 0, 7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 }, 7625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 }, 7725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 }, 7825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "histogram", 'I', NULL, 0, 7925b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Display histogram of bucket list lengths"), 0 }, 8025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 }, 8125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 8225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 }, 8325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 }, 8425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 8525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 }, 8625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 }, 8725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 }, 8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "arch-specific", 'A', NULL, 0, 8925b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Display architecture specific information, if any"), 0 }, 9025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "exception", 'e', NULL, 0, 9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Display sections for exception handling"), 0 }, 9225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 }, 9425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL, 9525b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Display DWARF section content. SECTION can be one of abbrev, " 9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng "aranges, frame, gdb_index, info, loc, line, ranges, pubnames, str, " 9725b3c049e70834cf33790a28643ab058b507b35cBen Cheng "macinfo, or exception"), 0 }, 9825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "hex-dump", 'x', "SECTION", 0, 9925b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 }, 10025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL, 10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Print string contents of sections"), 0 }, 10225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 10325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "archive-index", 'c', NULL, 0, 10425b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Display the symbol index of an archive"), 0 }, 10525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, N_("Output control:"), 0 }, 10725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "numeric-addresses", 'N', NULL, 0, 10825b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Do not find symbol names for addresses in DWARF data"), 0 }, 10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "wide", 'W', NULL, 0, 11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Ignored for compatibility (lines always wide)"), 0 }, 11125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, NULL, 0 } 11225b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Short description of program. */ 11525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char doc[] = N_("\ 11625b3c049e70834cf33790a28643ab058b507b35cBen ChengPrint information from ELF file in human-readable form."); 11725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Strings for arguments in help texts. */ 11925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char args_doc[] = N_("FILE..."); 12025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Prototype for option handler. */ 12225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 12325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Data structure to communicate with argp functions. */ 12525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct argp argp = 12625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 12725b3c049e70834cf33790a28643ab058b507b35cBen Cheng options, parse_opt, args_doc, doc, NULL, NULL, NULL 12825b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 12925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Flags set by the option controlling the output. */ 13225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if dynamic segment should be printed. */ 13425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_dynamic_table; 13525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if the file header should be printed. */ 13725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_file_header; 13825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if the program headers should be printed. */ 14025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_program_header; 14125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if relocations should be printed. */ 14325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_relocations; 14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if the section headers should be printed. */ 14625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_section_header; 14725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if the symbol table should be printed. */ 14925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_symbol_table; 15025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if the version information should be printed. */ 15225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_version_info; 15325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if section groups should be printed. */ 15525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_section_groups; 15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if bucket list length histogram should be printed. */ 15825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_histogram; 15925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if the architecture specific data should be printed. */ 16125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_arch; 16225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if note section content should be printed. */ 16425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_notes; 16525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if SHF_STRINGS section content should be printed. */ 16725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_string_sections; 16825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if archive index should be printed. */ 17025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_archive_index; 17125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if any of the control options except print_archive_index is set. */ 17325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool any_control_option; 17425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if we should print addresses from DWARF in symbolic form. */ 17625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_address_names = true; 17725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Select printing of debugging sections. */ 17925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic enum section_e 18025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 18125b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_abbrev = 1, /* .debug_abbrev */ 18225b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_aranges = 2, /* .debug_aranges */ 18325b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_frame = 4, /* .debug_frame or .eh_frame & al. */ 18425b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_info = 8, /* .debug_info, .debug_types */ 18525b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_types = section_info, 18625b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_line = 16, /* .debug_line */ 18725b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_loc = 32, /* .debug_loc */ 18825b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_pubnames = 64, /* .debug_pubnames */ 18925b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_str = 128, /* .debug_str */ 19025b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_macinfo = 256, /* .debug_macinfo */ 19125b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_ranges = 512, /* .debug_ranges */ 19225b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_exception = 1024, /* .eh_frame & al. */ 19325b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_gdb_index = 2048, /* .gdb_index */ 19425b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_all = (section_abbrev | section_aranges | section_frame 19525b3c049e70834cf33790a28643ab058b507b35cBen Cheng | section_info | section_line | section_loc 19625b3c049e70834cf33790a28643ab058b507b35cBen Cheng | section_pubnames | section_str | section_macinfo 19725b3c049e70834cf33790a28643ab058b507b35cBen Cheng | section_ranges | section_exception | section_gdb_index) 19825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} print_debug_sections, implicit_debug_sections; 19925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Select hex dumping of sections. */ 20125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct section_argument *dump_data_sections; 20225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct section_argument **dump_data_sections_tail = &dump_data_sections; 20325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Select string dumping of sections. */ 20525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct section_argument *string_sections; 20625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct section_argument **string_sections_tail = &string_sections; 20725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20825b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct section_argument 20925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 21025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct section_argument *next; 21125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *arg; 21225b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool implicit; 21325b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 21425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 21525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Numbers of sections and program headers in the file. */ 21625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t shnum; 21725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t phnum; 21825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 21925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Declarations of local functions. */ 22125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void process_file (int fd, const char *fname, bool only_one); 22225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void process_elf_file (Dwfl_Module *dwflmod, int fd); 22325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr); 22425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr); 22525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); 22625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_scngrp (Ebl *ebl); 22725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_dynamic (Ebl *ebl); 22825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); 22925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 23025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr); 23125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 23225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr); 23325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_symtab (Ebl *ebl, int type); 23425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 23525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_verinfo (Ebl *ebl); 23625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 23725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 23825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void handle_versym (Ebl *ebl, Elf_Scn *scn, 23925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr); 24025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr); 24125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void handle_hash (Ebl *ebl); 24225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr); 24325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_liblist (Ebl *ebl); 24425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr); 24525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void dump_data (Ebl *ebl); 24625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void dump_strings (Ebl *ebl); 24725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_strings (Ebl *ebl); 24825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void dump_archive_index (Elf *, const char *); 24925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25125b3c049e70834cf33790a28643ab058b507b35cBen Chengint 25225b3c049e70834cf33790a28643ab058b507b35cBen Chengmain (int argc, char *argv[]) 25325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 25425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set locale. */ 25525b3c049e70834cf33790a28643ab058b507b35cBen Cheng setlocale (LC_ALL, ""); 25625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Initialize the message catalog. */ 25825b3c049e70834cf33790a28643ab058b507b35cBen Cheng textdomain (PACKAGE_TARNAME); 25925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Parse and process arguments. */ 26125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int remaining; 26225b3c049e70834cf33790a28643ab058b507b35cBen Cheng argp_parse (&argp, argc, argv, 0, &remaining, NULL); 26325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Before we start tell the ELF library which version we are using. */ 26525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_version (EV_CURRENT); 26625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now process all the files given at the command line. */ 26825b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool only_one = remaining + 1 == argc; 26925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 27025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 27125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Open the file. */ 27225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int fd = open (argv[remaining], O_RDONLY); 27325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fd == -1) 27425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 27525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, errno, gettext ("cannot open input file")); 27625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 27725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 27825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27925b3c049e70834cf33790a28643ab058b507b35cBen Cheng process_file (fd, argv[remaining], only_one); 28025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28125b3c049e70834cf33790a28643ab058b507b35cBen Cheng close (fd); 28225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 28325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (++remaining < argc); 28425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return error_message_count != 0; 28625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 28725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle program arguments. */ 29025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic error_t 29125b3c049e70834cf33790a28643ab058b507b35cBen Chengparse_opt (int key, char *arg, 29225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct argp_state *state __attribute__ ((unused))) 29325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 29425b3c049e70834cf33790a28643ab058b507b35cBen Cheng void add_dump_section (const char *name, bool implicit) 29525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 29625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct section_argument *a = xmalloc (sizeof *a); 29725b3c049e70834cf33790a28643ab058b507b35cBen Cheng a->arg = name; 29825b3c049e70834cf33790a28643ab058b507b35cBen Cheng a->next = NULL; 29925b3c049e70834cf33790a28643ab058b507b35cBen Cheng a->implicit = implicit; 30025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct section_argument ***tailp 30125b3c049e70834cf33790a28643ab058b507b35cBen Cheng = key == 'x' ? &dump_data_sections_tail : &string_sections_tail; 30225b3c049e70834cf33790a28643ab058b507b35cBen Cheng **tailp = a; 30325b3c049e70834cf33790a28643ab058b507b35cBen Cheng *tailp = &a->next; 30425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 30525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 30625b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (key) 30725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 30825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'a': 30925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_header = true; 31025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_program_header = true; 31125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_relocations = true; 31225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_section_header = true; 31325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_symbol_table = true; 31425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_version_info = true; 31525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_dynamic_table = true; 31625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_section_groups = true; 31725b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_histogram = true; 31825b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_arch = true; 31925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_notes = true; 32025b3c049e70834cf33790a28643ab058b507b35cBen Cheng implicit_debug_sections |= section_exception; 32125b3c049e70834cf33790a28643ab058b507b35cBen Cheng add_dump_section (".strtab", true); 32225b3c049e70834cf33790a28643ab058b507b35cBen Cheng add_dump_section (".dynstr", true); 32325b3c049e70834cf33790a28643ab058b507b35cBen Cheng add_dump_section (".comment", true); 32425b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 32525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 32625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'A': 32725b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_arch = true; 32825b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 32925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 33025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'd': 33125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_dynamic_table = true; 33225b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 33325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 33425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'e': 33525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_exception; 33625b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 33725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 33825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'g': 33925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_section_groups = true; 34025b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 34125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 34225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'h': 34325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_header = true; 34425b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 34525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 34625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'I': 34725b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_histogram = true; 34825b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 34925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 35025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'l': 35125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_program_header = true; 35225b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 35325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 35425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'n': 35525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_notes = true; 35625b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 35725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 35825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'r': 35925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_relocations = true; 36025b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 36125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 36225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'S': 36325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_section_header = true; 36425b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 36525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 36625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 's': 36725b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_symbol_table = true; 36825b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 36925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 37025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'V': 37125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_version_info = true; 37225b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 37325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 37425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'c': 37525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_archive_index = true; 37625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 37725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'w': 37825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (arg == NULL) 37925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections = section_all; 38025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "abbrev") == 0) 38125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_abbrev; 38225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "aranges") == 0) 38325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_aranges; 38425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "ranges") == 0) 38525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 38625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_ranges; 38725b3c049e70834cf33790a28643ab058b507b35cBen Cheng implicit_debug_sections |= section_info; 38825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 38925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0) 39025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_frame; 39125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "info") == 0) 39225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_info; 39325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "loc") == 0) 39425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 39525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_loc; 39625b3c049e70834cf33790a28643ab058b507b35cBen Cheng implicit_debug_sections |= section_info; 39725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 39825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "line") == 0) 39925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_line; 40025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "pubnames") == 0) 40125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_pubnames; 40225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "str") == 0) 40325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_str; 40425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "macinfo") == 0) 40525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_macinfo; 40625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "exception") == 0) 40725b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_exception; 40825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (arg, "gdb_index") == 0) 40925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_sections |= section_gdb_index; 41025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 41125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 41225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"), 41325b3c049e70834cf33790a28643ab058b507b35cBen Cheng arg); 41425b3c049e70834cf33790a28643ab058b507b35cBen Cheng argp_help (&argp, stderr, ARGP_HELP_SEE, 41525b3c049e70834cf33790a28643ab058b507b35cBen Cheng program_invocation_short_name); 41625b3c049e70834cf33790a28643ab058b507b35cBen Cheng exit (1); 41725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 41825b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 41925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 42025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'p': 42125b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 42225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (arg == NULL) 42325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 42425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_string_sections = true; 42525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 42625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 42725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fall through. */ 42825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'x': 42925b3c049e70834cf33790a28643ab058b507b35cBen Cheng add_dump_section (arg, false); 43025b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_control_option = true; 43125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 43225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'N': 43325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_address_names = false; 43425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 43525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case ARGP_KEY_NO_ARGS: 43625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs (gettext ("Missing file name.\n"), stderr); 43725b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto do_argp_help; 43825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case ARGP_KEY_FINI: 43925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! any_control_option && ! print_archive_index) 44025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 44125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs (gettext ("No operation specified.\n"), stderr); 44225b3c049e70834cf33790a28643ab058b507b35cBen Cheng do_argp_help: 44325b3c049e70834cf33790a28643ab058b507b35cBen Cheng argp_help (&argp, stderr, ARGP_HELP_SEE, 44425b3c049e70834cf33790a28643ab058b507b35cBen Cheng program_invocation_short_name); 44525b3c049e70834cf33790a28643ab058b507b35cBen Cheng exit (EXIT_FAILURE); 44625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 44825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'W': /* Ignored. */ 44925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 45025b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 45125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ARGP_ERR_UNKNOWN; 45225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 45325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 45425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 45525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 45625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 45725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the version information. */ 45825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 45925b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 46025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 46125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 46225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, gettext ("\ 46325b3c049e70834cf33790a28643ab058b507b35cBen ChengCopyright (C) %s Red Hat, Inc.\n\ 46425b3c049e70834cf33790a28643ab058b507b35cBen ChengThis is free software; see the source for copying conditions. There is NO\n\ 46525b3c049e70834cf33790a28643ab058b507b35cBen Chengwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 46625b3c049e70834cf33790a28643ab058b507b35cBen Cheng"), "2012"); 46725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 46825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 46925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 47025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 47125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Check if the file is an archive, and if so dump its index. */ 47225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 47325b3c049e70834cf33790a28643ab058b507b35cBen Chengcheck_archive_index (int fd, const char *fname, bool only_one) 47425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 47525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create an `Elf' descriptor. */ 47625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 47725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf == NULL) 47825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot generate Elf descriptor: %s"), 47925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 48025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 48125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 48225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_kind (elf) == ELF_K_AR) 48325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 48425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!only_one) 48525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\n%s:\n\n", fname); 48625b3c049e70834cf33790a28643ab058b507b35cBen Cheng dump_archive_index (elf, fname); 48725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 48825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 48925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, 49025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("'%s' is not an archive, cannot print archive index"), 49125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname); 49225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 49325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now we can close the descriptor. */ 49425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_end (elf) != 0) 49525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("error while closing Elf descriptor: %s"), 49625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 49725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 49825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 49925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 50025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Trivial callback used for checking if we opened an archive. */ 50125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 50225b3c049e70834cf33790a28643ab058b507b35cBen Chengcount_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)), 50325b3c049e70834cf33790a28643ab058b507b35cBen Cheng void **userdata __attribute__ ((unused)), 50425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name __attribute__ ((unused)), 50525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr base __attribute__ ((unused)), 50625b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *arg) 50725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 50825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (*(bool *) arg) 50925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_ABORT; 51025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *(bool *) arg = true; 51125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_OK; 51225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 51325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 51425b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct process_dwflmod_args 51525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 51625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int fd; 51725b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool only_one; 51825b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 51925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 52025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 52125b3c049e70834cf33790a28643ab058b507b35cBen Chengprocess_dwflmod (Dwfl_Module *dwflmod, 52225b3c049e70834cf33790a28643ab058b507b35cBen Cheng void **userdata __attribute__ ((unused)), 52325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name __attribute__ ((unused)), 52425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr base __attribute__ ((unused)), 52525b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *arg) 52625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 52725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct process_dwflmod_args *a = arg; 52825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 52925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Print the file name. */ 53025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!a->only_one) 53125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 53225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *fname; 53325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL); 53425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 53525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\n%s:\n\n", fname); 53625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 53725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 53825b3c049e70834cf33790a28643ab058b507b35cBen Cheng process_elf_file (dwflmod, a->fd); 53925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 54025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_OK; 54125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 54225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 54325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Stub libdwfl callback, only the ELF handle already open is ever used. */ 54425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 54525b3c049e70834cf33790a28643ab058b507b35cBen Chengfind_no_debuginfo (Dwfl_Module *mod __attribute__ ((unused)), 54625b3c049e70834cf33790a28643ab058b507b35cBen Cheng void **userdata __attribute__ ((unused)), 54725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *modname __attribute__ ((unused)), 54825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr base __attribute__ ((unused)), 54925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *file_name __attribute__ ((unused)), 55025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *debuglink_file __attribute__ ((unused)), 55125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Word debuglink_crc __attribute__ ((unused)), 55225b3c049e70834cf33790a28643ab058b507b35cBen Cheng char **debuginfo_file_name __attribute__ ((unused))) 55325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 55425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return -1; 55525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 55625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 55725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Process one input file. */ 55825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 55925b3c049e70834cf33790a28643ab058b507b35cBen Chengprocess_file (int fd, const char *fname, bool only_one) 56025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 56125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_archive_index) 56225b3c049e70834cf33790a28643ab058b507b35cBen Cheng check_archive_index (fd, fname, only_one); 56325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 56425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!any_control_option) 56525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 56625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 56725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Duplicate an fd for dwfl_report_offline to swallow. */ 56825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int dwfl_fd = dup (fd); 56925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (dwfl_fd < 0)) 57025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, "dup"); 57125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 57225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use libdwfl in a trivial way to open the libdw handle for us. 57325b3c049e70834cf33790a28643ab058b507b35cBen Cheng This takes care of applying relocations to DWARF data in ET_REL files. */ 57425b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const Dwfl_Callbacks callbacks = 57525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 57625b3c049e70834cf33790a28643ab058b507b35cBen Cheng .section_address = dwfl_offline_section_address, 57725b3c049e70834cf33790a28643ab058b507b35cBen Cheng .find_debuginfo = find_no_debuginfo 57825b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 57925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwfl *dwfl = dwfl_begin (&callbacks); 58025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (dwfl != NULL)) 58125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Let 0 be the logical address of the file (or first in archive). */ 58225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwfl->offline_next_address = 0; 58325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL) 58425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 58525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct stat64 st; 58625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fstat64 (dwfl_fd, &st) != 0) 58725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, errno, gettext ("cannot stat input file")); 58825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (st.st_size == 0)) 58925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("input file is empty")); 59025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 59125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("failed reading '%s': %s"), 59225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname, dwfl_errmsg (-1)); 59325b3c049e70834cf33790a28643ab058b507b35cBen Cheng close (dwfl_fd); /* Consumed on success, not on failure. */ 59425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 59525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 59625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 59725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwfl_report_end (dwfl, NULL, NULL); 59825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 59925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (only_one) 60025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 60125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Clear ONLY_ONE if we have multiple modules, from an archive. */ 60225b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool seen = false; 60325b3c049e70834cf33790a28643ab058b507b35cBen Cheng only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0; 60425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 60525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 60625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Process the one or more modules gleaned from this file. */ 60725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct process_dwflmod_args a = { .fd = fd, .only_one = only_one }; 60825b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwfl_getmodules (dwfl, &process_dwflmod, &a, 0); 60925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 61025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwfl_end (dwfl); 61125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 61225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 61325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 61425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Process one ELF file. */ 61525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 61625b3c049e70834cf33790a28643ab058b507b35cBen Chengprocess_elf_file (Dwfl_Module *dwflmod, int fd) 61725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 61825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Addr dwflbias; 61925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias); 62025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 62125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr ehdr_mem; 62225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 62325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 62425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr == NULL) 62525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 62625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_error: 62725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1)); 62825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 62925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 63025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 63125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl = ebl_openbackend (elf); 63225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ebl == NULL)) 63325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 63425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_error: 63525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, errno, gettext ("cannot create EBL handle")); 63625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 63725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 63825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 63925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the number of sections. */ 64025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0)) 64125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 64225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot determine number of sections: %s"), 64325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 64425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 64525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the number of phdrs. */ 64625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0)) 64725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 64825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot determine number of program headers: %s"), 64925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 65025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 65125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* For an ET_REL file, libdwfl has adjusted the in-core shdrs 65225b3c049e70834cf33790a28643ab058b507b35cBen Cheng and may have applied relocation to some sections. 65325b3c049e70834cf33790a28643ab058b507b35cBen Cheng So we need to get a fresh Elf handle on the file to display those. */ 65425b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool print_unrelocated = (print_section_header 65525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || print_relocations 65625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || dump_data_sections != NULL 65725b3c049e70834cf33790a28643ab058b507b35cBen Cheng || print_notes); 65825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 65925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *pure_elf = NULL; 66025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *pure_ebl = ebl; 66125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_type == ET_REL && print_unrelocated) 66225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 66325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Read the file afresh. */ 66425b3c049e70834cf33790a28643ab058b507b35cBen Cheng off64_t aroff = elf_getaroff (elf); 66525b3c049e70834cf33790a28643ab058b507b35cBen Cheng pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 66625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (aroff > 0) 66725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 66825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Archive member. */ 66925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) elf_rand (pure_elf, aroff); 67025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf); 67125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_end (pure_elf); 67225b3c049e70834cf33790a28643ab058b507b35cBen Cheng pure_elf = armem; 67325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 67425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (pure_elf == NULL) 67525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto elf_error; 67625b3c049e70834cf33790a28643ab058b507b35cBen Cheng pure_ebl = ebl_openbackend (pure_elf); 67725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (pure_ebl == NULL) 67825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto ebl_error; 67925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 68025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 68125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_file_header) 68225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_ehdr (ebl, ehdr); 68325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_section_header) 68425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_shdr (pure_ebl, ehdr); 68525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_program_header) 68625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_phdr (ebl, ehdr); 68725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_section_groups) 68825b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_scngrp (ebl); 68925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_dynamic_table) 69025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_dynamic (ebl); 69125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_relocations) 69225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_relocs (pure_ebl, ehdr); 69325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_histogram) 69425b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_hash (ebl); 69525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_symbol_table) 69625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_symtab (ebl, SHT_DYNSYM); 69725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_version_info) 69825b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_verinfo (ebl); 69925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_symbol_table) 70025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_symtab (ebl, SHT_SYMTAB); 70125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_arch) 70225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_liblist (ebl); 70325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_arch) 70425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_attributes (ebl, ehdr); 70525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dump_data_sections != NULL) 70625b3c049e70834cf33790a28643ab058b507b35cBen Cheng dump_data (pure_ebl); 70725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (string_sections != NULL) 70825b3c049e70834cf33790a28643ab058b507b35cBen Cheng dump_strings (ebl); 70925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((print_debug_sections | implicit_debug_sections) != 0) 71025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug (dwflmod, ebl, ehdr); 71125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_notes) 71225b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_notes (pure_ebl, ehdr); 71325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_string_sections) 71425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_strings (ebl); 71525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 71625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_closebackend (ebl); 71725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 71825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (pure_ebl != ebl) 71925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 72025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_closebackend (pure_ebl); 72125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_end (pure_elf); 72225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 72325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 72425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 72525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 72625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print file type. */ 72725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 72825b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_file_type (unsigned short int e_type) 72925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 73025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (e_type <= ET_CORE)) 73125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 73225b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const knowntypes[] = 73325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 73425b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("NONE (None)"), 73525b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("REL (Relocatable file)"), 73625b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("EXEC (Executable file)"), 73725b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("DYN (Shared object file)"), 73825b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("CORE (Core file)") 73925b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 74025b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext (knowntypes[e_type])); 74125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 74225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (e_type >= ET_LOOS && e_type <= ET_HIOS) 74325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("OS Specific: (%x)\n"), e_type); 74425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */) 74525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("Processor Specific: (%x)\n"), e_type); 74625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 74725b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts ("???"); 74825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 74925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 75025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 75125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print ELF header. */ 75225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 75325b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_ehdr (Ebl *ebl, GElf_Ehdr *ehdr) 75425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 75525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout); 75625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt) 75725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %02hhx", ehdr->e_ident[cnt]); 75825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 75925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\n Class: %s\n"), 76025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32" 76125b3c049e70834cf33790a28643ab058b507b35cBen Cheng : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64" 76225b3c049e70834cf33790a28643ab058b507b35cBen Cheng : "\?\?\?"); 76325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 76425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Data: %s\n"), 76525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_DATA] == ELFDATA2LSB 76625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? "2's complement, little endian" 76725b3c049e70834cf33790a28643ab058b507b35cBen Cheng : ehdr->e_ident[EI_DATA] == ELFDATA2MSB 76825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? "2's complement, big endian" : "\?\?\?"); 76925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 77025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Ident Version: %hhd %s\n"), 77125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_VERSION], 77225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)") 77325b3c049e70834cf33790a28643ab058b507b35cBen Cheng : "(\?\?\?)"); 77425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 77525b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[512]; 77625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" OS/ABI: %s\n"), 77725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 77825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 77925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" ABI Version: %hhd\n"), 78025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_ABIVERSION]); 78125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 78225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext (" Type: "), stdout); 78325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_type (ehdr->e_type); 78425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 78525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Machine: %s\n"), ebl->name); 78625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 78725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Version: %d %s\n"), 78825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_version, 78925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)"); 79025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 79125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Entry point address: %#" PRIx64 "\n"), 79225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_entry); 79325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 79425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Start of program headers: %" PRId64 " %s\n"), 79525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_phoff, gettext ("(bytes into file)")); 79625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 79725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Start of section headers: %" PRId64 " %s\n"), 79825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_shoff, gettext ("(bytes into file)")); 79925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 80025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Flags: %s\n"), 80125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 80225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 80325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Size of this header: %" PRId16 " %s\n"), 80425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ehsize, gettext ("(bytes)")); 80525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 80625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Size of program header entries: %" PRId16 " %s\n"), 80725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_phentsize, gettext ("(bytes)")); 80825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 80925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Number of program headers entries: %" PRId16), 81025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_phnum); 81125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_phnum == PN_XNUM) 81225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 81325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 81425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 81525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL) 81625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" (%" PRIu32 " in [0].sh_info)"), 81725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint32_t) shdr->sh_info); 81825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 81925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext (" ([0] not available)"), stdout); 82025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 82125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked ('\n', stdout); 82225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 82325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Size of section header entries: %" PRId16 " %s\n"), 82425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_shentsize, gettext ("(bytes)")); 82525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 82625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Number of section headers entries: %" PRId16), 82725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_shnum); 82825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_shnum == 0) 82925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 83025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 83125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 83225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL) 83325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" (%" PRIu32 " in [0].sh_size)"), 83425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint32_t) shdr->sh_size); 83525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 83625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext (" ([0] not available)"), stdout); 83725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 83825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked ('\n', stdout); 83925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 84025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ehdr->e_shstrndx == SHN_XINDEX)) 84125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 84225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 84325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 84425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL) 84525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We managed to get the zeroth section. */ 84625b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"), 84725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint32_t) shdr->sh_link); 84825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 84925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 85025b3c049e70834cf33790a28643ab058b507b35cBen Cheng strncpy (buf, gettext (" ([0] not available)"), sizeof (buf)); 85125b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf[sizeof (buf) - 1] = '\0'; 85225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 85325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 85425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Section header string table index: XINDEX%s\n\n"), 85525b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf); 85625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 85725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 85825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Section header string table index: %" PRId16 "\n\n"), 85925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_shstrndx); 86025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 86125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 86225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 86325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 86425b3c049e70834cf33790a28643ab058b507b35cBen Chengget_visibility_type (int value) 86525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 86625b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (value) 86725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 86825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case STV_DEFAULT: 86925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "DEFAULT"; 87025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case STV_INTERNAL: 87125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "INTERNAL"; 87225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case STV_HIDDEN: 87325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "HIDDEN"; 87425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case STV_PROTECTED: 87525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "PROTECTED"; 87625b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 87725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 87825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 87925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 88025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 88125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 88225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the section headers. */ 88325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 88425b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_shdr (Ebl *ebl, GElf_Ehdr *ehdr) 88525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 88625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 88725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 88825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 88925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! print_file_header) 89025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 89125b3c049e70834cf33790a28643ab058b507b35cBen ChengThere are %d section headers, starting at offset %#" PRIx64 ":\n\ 89225b3c049e70834cf33790a28643ab058b507b35cBen Cheng\n"), 89325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_shnum, ehdr->e_shoff); 89425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 89525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 89625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 89725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 89825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 89925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 90025b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("Section Headers:")); 90125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 90225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 90325b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); 90425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 90525b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); 90625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 90725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < shnum; ++cnt) 90825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 90925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_getscn (ebl->elf, cnt); 91025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 91125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (scn == NULL)) 91225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"), 91325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 91425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 91525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header. */ 91625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 91725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 91825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr == NULL)) 91925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"), 92025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 92125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 92225b3c049e70834cf33790a28643ab058b507b35cBen Cheng char flagbuf[20]; 92325b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *cp = flagbuf; 92425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_WRITE) 92525b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'W'; 92625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_ALLOC) 92725b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'A'; 92825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_EXECINSTR) 92925b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'X'; 93025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_MERGE) 93125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'M'; 93225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_STRINGS) 93325b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'S'; 93425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_INFO_LINK) 93525b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'I'; 93625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_LINK_ORDER) 93725b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'L'; 93825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_OS_NONCONFORMING) 93925b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'N'; 94025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_GROUP) 94125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'G'; 94225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_TLS) 94325b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'T'; 94425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_ORDERED) 94525b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'O'; 94625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_flags & SHF_EXCLUDE) 94725b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = 'E'; 94825b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp = '\0'; 94925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 95025b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[128]; 95125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64 95225b3c049e70834cf33790a28643ab058b507b35cBen Cheng " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32 95325b3c049e70834cf33790a28643ab058b507b35cBen Cheng " %2" PRId64 "\n", 95425b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt, 95525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name) 95625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ?: "<corrupt>", 95725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)), 95825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr, 95925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset, 96025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size, 96125b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info, 96225b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addralign); 96325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 96425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 96525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked ('\n', stdout); 96625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 96725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 96825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 96925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the program header. */ 97025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 97125b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_phdr (Ebl *ebl, GElf_Ehdr *ehdr) 97225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 97325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_phnum == 0) 97425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No program header, this is OK in relocatable objects. */ 97525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 97625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 97725b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("Program Headers:")); 97825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 97925b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("\ 98025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); 98125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 98225b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("\ 98325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); 98425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 98525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Process all program headers. */ 98625b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool has_relro = false; 98725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Addr relro_from = 0; 98825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Addr relro_to = 0; 98925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = 0; cnt < phnum; ++cnt) 99025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 99125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[128]; 99225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr mem; 99325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem); 99425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 99525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If for some reason the header cannot be returned show this. */ 99625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (phdr == NULL)) 99725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 99825b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (" ???"); 99925b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 100025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 100125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 100225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64 100325b3c049e70834cf33790a28643ab058b507b35cBen Cheng " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n", 100425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)), 100525b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_offset, 100625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr, 100725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr, 100825b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_filesz, 100925b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_memsz, 101025b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags & PF_R ? 'R' : ' ', 101125b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags & PF_W ? 'W' : ' ', 101225b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags & PF_X ? 'E' : ' ', 101325b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_align); 101425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 101525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (phdr->p_type == PT_INTERP) 101625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 101725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We can show the user the name of the interpreter. */ 101825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t maxsize; 101925b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *filedata = elf_rawfile (ebl->elf, &maxsize); 102025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 102125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (filedata != NULL && phdr->p_offset < maxsize) 102225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\t[Requesting program interpreter: %s]\n"), 102325b3c049e70834cf33790a28643ab058b507b35cBen Cheng filedata + phdr->p_offset); 102425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 102525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (phdr->p_type == PT_GNU_RELRO) 102625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 102725b3c049e70834cf33790a28643ab058b507b35cBen Cheng has_relro = true; 102825b3c049e70834cf33790a28643ab058b507b35cBen Cheng relro_from = phdr->p_vaddr; 102925b3c049e70834cf33790a28643ab058b507b35cBen Cheng relro_to = relro_from + phdr->p_memsz; 103025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 103125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 103225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 103325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_shnum == 0) 103425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No sections in the file. Punt. */ 103525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 103625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 103725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 103825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 103925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 104025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 104125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 104225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 104325b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("\n Section to Segment mapping:\n Segment Sections...")); 104425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 104525b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = 0; cnt < phnum; ++cnt) 104625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 104725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Print the segment number. */ 104825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %2.2zu ", cnt); 104925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 105025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr phdr_mem; 105125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 105225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This must not happen. */ 105325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (phdr == NULL)) 105425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"), 105525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 105625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 105725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Iterate over the sections. */ 105825b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool in_relro = false; 105925b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool in_ro = false; 106025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t inner = 1; inner < shnum; ++inner) 106125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 106225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_getscn (ebl->elf, inner); 106325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This should not happen. */ 106425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (scn == NULL)) 106525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"), 106625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 106725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 106825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header. */ 106925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 107025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 107125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr == NULL)) 107225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 107325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header: %s"), 107425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 107525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 107625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_size > 0 107725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compare allocated sections by VMA, unallocated 107825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sections by file offset. */ 107925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shdr->sh_flags & SHF_ALLOC 108025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? (shdr->sh_addr >= phdr->p_vaddr 108125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shdr->sh_addr + shdr->sh_size 108225b3c049e70834cf33790a28643ab058b507b35cBen Cheng <= phdr->p_vaddr + phdr->p_memsz)) 108325b3c049e70834cf33790a28643ab058b507b35cBen Cheng : (shdr->sh_offset >= phdr->p_offset 108425b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shdr->sh_offset + shdr->sh_size 108525b3c049e70834cf33790a28643ab058b507b35cBen Cheng <= phdr->p_offset + phdr->p_filesz)))) 108625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 108725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (has_relro && !in_relro 108825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && shdr->sh_addr >= relro_from 108925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && shdr->sh_addr + shdr->sh_size <= relro_to) 109025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 109125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (" [RELRO:", stdout); 109225b3c049e70834cf33790a28643ab058b507b35cBen Cheng in_relro = true; 109325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 109425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (has_relro && in_relro && shdr->sh_addr >= relro_to) 109525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 109625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked ("]", stdout); 109725b3c049e70834cf33790a28643ab058b507b35cBen Cheng in_relro = false; 109825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 109925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (has_relro && in_relro 110025b3c049e70834cf33790a28643ab058b507b35cBen Cheng && shdr->sh_addr + shdr->sh_size > relro_to) 110125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked ("] <RELRO:", stdout); 110225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0) 110325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 110425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!in_ro) 110525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 110625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (" [RO:", stdout); 110725b3c049e70834cf33790a28643ab058b507b35cBen Cheng in_ro = true; 110825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 110925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 111025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 111125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 111225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the segment this section is part of. */ 111325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt2; 111425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr *phdr2 = NULL; 111525b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt2 = 0; cnt2 < phnum; ++cnt2) 111625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 111725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr phdr2_mem; 111825b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem); 111925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 112025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (phdr2 != NULL && phdr2->p_type == PT_LOAD 112125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && shdr->sh_addr >= phdr2->p_vaddr 112225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shdr->sh_addr + shdr->sh_size 112325b3c049e70834cf33790a28643ab058b507b35cBen Cheng <= phdr2->p_vaddr + phdr2->p_memsz)) 112425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 112525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 112625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 112725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cnt2 < phnum) 112825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 112925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((phdr2->p_flags & PF_W) == 0 && !in_ro) 113025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 113125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (" [RO:", stdout); 113225b3c049e70834cf33790a28643ab058b507b35cBen Cheng in_ro = true; 113325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 113425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if ((phdr2->p_flags & PF_W) != 0 && in_ro) 113525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 113625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked ("]", stdout); 113725b3c049e70834cf33790a28643ab058b507b35cBen Cheng in_ro = false; 113825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 113925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 114025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 114125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 114225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %s", 114325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); 114425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 114525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Signal that this sectin is only partially covered. */ 114625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (has_relro && in_relro 114725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && shdr->sh_addr + shdr->sh_size > relro_to) 114825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 114925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (">", stdout); 115025b3c049e70834cf33790a28643ab058b507b35cBen Cheng in_relro = false; 115125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 115225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 115325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 115425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (in_relro || in_ro) 115525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked ("]", stdout); 115625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 115725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Finish the line. */ 115825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked ('\n', stdout); 115925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 116025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 116125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 116225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 116325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 116425b3c049e70834cf33790a28643ab058b507b35cBen Chengsection_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr) 116525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 116625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???"; 116725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 116825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 116925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 117025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 117125b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 117225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 117325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section. */ 117425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 117525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 117625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 117725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr symshdr_mem; 117825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 117925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *symdata = elf_getdata (symscn, NULL); 118025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 118125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL 118225b3c049e70834cf33790a28643ab058b507b35cBen Cheng || symdata == NULL) 118325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 118425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 118525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 118625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 118725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 118825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 118925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 119025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 119125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *grpref = (Elf32_Word *) data->d_buf; 119225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 119325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym sym_mem; 119425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ((grpref[0] & GRP_COMDAT) 119525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ngettext ("\ 119625b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n", 119725b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 119825b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n", 119925b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_size / sizeof (Elf32_Word) - 1) 120025b3c049e70834cf33790a28643ab058b507b35cBen Cheng : ngettext ("\ 120125b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\ 120225b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n", 120325b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_size / sizeof (Elf32_Word) - 1), 120425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), 120525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 120625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, symshdr->sh_link, 120725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name) 120825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ?: gettext ("<INVALID SYMBOL>"), 120925b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_size / sizeof (Elf32_Word) - 1); 121025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 121125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 121225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 121325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr grpshdr_mem; 121425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]), 121525b3c049e70834cf33790a28643ab058b507b35cBen Cheng &grpshdr_mem); 121625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 121725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *str; 121825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%2u] %s\n", 121925b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpref[cnt], 122025b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpshdr != NULL 122125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name)) 122225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? str : gettext ("<INVALID SECTION>")); 122325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 122425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 122525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 122625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 122725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 122825b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_scngrp (Ebl *ebl) 122925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 123025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find all relocation sections and handle them. */ 123125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 123225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 123325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 123425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 123525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle the section if it is a symbol table. */ 123625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 123725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 123825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 123925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL && shdr->sh_type == SHT_GROUP) 124025b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_scngrp (ebl, scn, shdr); 124125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 124225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 124325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 124425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 124525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct flags 124625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 124725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int mask; 124825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *str; 124925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} dt_flags[] = 125025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 125125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_ORIGIN, "ORIGIN" }, 125225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_SYMBOLIC, "SYMBOLIC" }, 125325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_TEXTREL, "TEXTREL" }, 125425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_BIND_NOW, "BIND_NOW" }, 125525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_STATIC_TLS, "STATIC_TLS" } 125625b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 125725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]); 125825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 125925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct flags dt_flags_1[] = 126025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 126125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_NOW, "NOW" }, 126225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_GLOBAL, "GLOBAL" }, 126325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_GROUP, "GROUP" }, 126425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_NODELETE, "NODELETE" }, 126525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_LOADFLTR, "LOADFLTR" }, 126625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_INITFIRST, "INITFIRST" }, 126725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_NOOPEN, "NOOPEN" }, 126825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_ORIGIN, "ORIGIN" }, 126925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_DIRECT, "DIRECT" }, 127025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_TRANS, "TRANS" }, 127125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_INTERPOSE, "INTERPOSE" }, 127225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_NODEFLIB, "NODEFLIB" }, 127325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_NODUMP, "NODUMP" }, 127425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_CONFALT, "CONFALT" }, 127525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_ENDFILTEE, "ENDFILTEE" }, 127625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_DISPRELDNE, "DISPRELDNE" }, 127725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_1_DISPRELPND, "DISPRELPND" }, 127825b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 127925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]); 128025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 128125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct flags dt_feature_1[] = 128225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 128325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DTF_1_PARINIT, "PARINIT" }, 128425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DTF_1_CONFEXP, "CONFEXP" } 128525b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 128625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const int ndt_feature_1 = (sizeof (dt_feature_1) 128725b3c049e70834cf33790a28643ab058b507b35cBen Cheng / sizeof (dt_feature_1[0])); 128825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 128925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct flags dt_posflag_1[] = 129025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 129125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_P1_LAZYLOAD, "LAZYLOAD" }, 129225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { DF_P1_GROUPPERM, "GROUPPERM" } 129325b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 129425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const int ndt_posflag_1 = (sizeof (dt_posflag_1) 129525b3c049e70834cf33790a28643ab058b507b35cBen Cheng / sizeof (dt_posflag_1[0])); 129625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 129725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 129825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 129925b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_flags (int class, GElf_Xword d_val, const struct flags *flags, 130025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int nflags) 130125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 130225b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool first = true; 130325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int cnt; 130425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 130525b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < nflags; ++cnt) 130625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (d_val & flags[cnt].mask) 130725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 130825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!first) 130925b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked (' '); 131025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (flags[cnt].str, stdout); 131125b3c049e70834cf33790a28643ab058b507b35cBen Cheng d_val &= ~flags[cnt].mask; 131225b3c049e70834cf33790a28643ab058b507b35cBen Cheng first = false; 131325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 131425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 131525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (d_val != 0) 131625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 131725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!first) 131825b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked (' '); 131925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val); 132025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 132125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 132225b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked ('\n'); 132325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 132425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 132525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 132625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 132725b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_dt_flags (int class, GElf_Xword d_val) 132825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 132925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_flags (class, d_val, dt_flags, ndt_flags); 133025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 133125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 133225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 133325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 133425b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_dt_flags_1 (int class, GElf_Xword d_val) 133525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 133625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_flags (class, d_val, dt_flags_1, ndt_flags_1); 133725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 133825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 133925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 134025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 134125b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_dt_feature_1 (int class, GElf_Xword d_val) 134225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 134325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_flags (class, d_val, dt_feature_1, ndt_feature_1); 134425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 134525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 134625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 134725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 134825b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_dt_posflag_1 (int class, GElf_Xword d_val) 134925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 135025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_flags (class, d_val, dt_posflag_1, ndt_posflag_1); 135125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 135225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 135325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 135425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 135525b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 135625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 135725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int class = gelf_getclass (ebl->elf); 135825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr glink; 135925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data; 136025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 136125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 136225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 136325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section. */ 136425b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = elf_getdata (scn, NULL); 136525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 136625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 136725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 136825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 136925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 137025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 137125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 137225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 137325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 137425b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 137525b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 137625b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 137725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size / shdr->sh_entsize), 137825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned long int) (shdr->sh_size / shdr->sh_entsize), 137925b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 138025b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 138125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) shdr->sh_link, 138225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, 138325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 138425b3c049e70834cf33790a28643ab058b507b35cBen Cheng &glink)->sh_name)); 138525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext (" Type Value\n"), stdout); 138625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 138725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 138825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 138925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Dyn dynmem; 139025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem); 139125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dyn == NULL) 139225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 139325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 139425b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[64]; 139525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %-17s ", 139625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf))); 139725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 139825b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (dyn->d_tag) 139925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 140025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_NULL: 140125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_DEBUG: 140225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_BIND_NOW: 140325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_TEXTREL: 140425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No further output. */ 140525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked ('\n', stdout); 140625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 140725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 140825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_NEEDED: 140925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("Shared library: [%s]\n"), 141025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 141125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 141225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 141325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_SONAME: 141425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("Library soname: [%s]\n"), 141525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 141625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 141725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 141825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_RPATH: 141925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("Library rpath: [%s]\n"), 142025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 142125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 142225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 142325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_RUNPATH: 142425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("Library runpath: [%s]\n"), 142525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 142625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 142725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 142825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_PLTRELSZ: 142925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_RELASZ: 143025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_STRSZ: 143125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_RELSZ: 143225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_RELAENT: 143325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_SYMENT: 143425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_RELENT: 143525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_PLTPADSZ: 143625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_MOVEENT: 143725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_MOVESZ: 143825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_INIT_ARRAYSZ: 143925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_FINI_ARRAYSZ: 144025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_SYMINSZ: 144125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_SYMINENT: 144225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_GNU_CONFLICTSZ: 144325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_GNU_LIBLISTSZ: 144425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val); 144525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 144625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 144725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_VERDEFNUM: 144825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_VERNEEDNUM: 144925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_RELACOUNT: 145025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_RELCOUNT: 145125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%" PRId64 "\n", dyn->d_un.d_val); 145225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 145325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 145425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_PLTREL:; 145525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val, 145625b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL, 0); 145725b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (tagname ?: "???"); 145825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 145925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 146025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_FLAGS: 146125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_dt_flags (class, dyn->d_un.d_val); 146225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 146325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 146425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_FLAGS_1: 146525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_dt_flags_1 (class, dyn->d_un.d_val); 146625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 146725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 146825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_FEATURE_1: 146925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_dt_feature_1 (class, dyn->d_un.d_val); 147025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 147125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 147225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DT_POSFLAG_1: 147325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_dt_posflag_1 (class, dyn->d_un.d_val); 147425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 147525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 147625b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 147725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%#0*" PRIx64 "\n", 147825b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val); 147925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 148025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 148125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 148225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 148325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 148425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 148525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the dynamic segment. */ 148625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 148725b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_dynamic (Ebl *ebl) 148825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 148925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < phnum; ++i) 149025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 149125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr phdr_mem; 149225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 149325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 149425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 149525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 149625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset); 149725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 149825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 149925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 150025b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_dynamic (ebl, scn, shdr); 150125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 150225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 150325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 150425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 150525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 150625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 150725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print relocations. */ 150825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 150925b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_relocs (Ebl *ebl, GElf_Ehdr *ehdr) 151025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 151125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find all relocation sections and handle them. */ 151225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 151325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 151425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 151525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 151625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle the section if it is a symbol table. */ 151725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 151825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 151925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 152025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (shdr != NULL)) 152125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 152225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type == SHT_REL) 152325b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_relocs_rel (ebl, ehdr, scn, shdr); 152425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (shdr->sh_type == SHT_RELA) 152525b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_relocs_rela (ebl, ehdr, scn, shdr); 152625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 152725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 152825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 152925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 153025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 153125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle a relocation section. */ 153225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 153325b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) 153425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 153525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int class = gelf_getclass (ebl->elf); 153625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int nentries = shdr->sh_size / shdr->sh_entsize; 153725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 153825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section. */ 153925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 154025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 154125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 154225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 154325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the symbol table information. */ 154425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 154525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr symshdr_mem; 154625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 154725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *symdata = elf_getdata (symscn, NULL); 154825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 154925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header of the section the relocations are for. */ 155025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr destshdr_mem; 155125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 155225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &destshdr_mem); 155325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 155425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) 155525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 155625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"), 155725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset); 155825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 155925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 156025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 156125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Search for the optional extended section index table. */ 156225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *xndxdata = NULL; 156325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int xndxscnidx = elf_scnshndx (scn); 156425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (xndxscnidx > 0)) 156525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); 156625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 156725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 156825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 156925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 157025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 157125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 157225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 157325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_info != 0) 157425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 157525b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 157625b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 157725b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 157825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nentries), 157925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), 158025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 158125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) shdr->sh_info, 158225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), 158325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 158425b3c049e70834cf33790a28643ab058b507b35cBen Cheng nentries); 158525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 158625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The .rel.dyn section does not refer to a specific section but 158725b3c049e70834cf33790a28643ab058b507b35cBen Cheng instead of section index zero. Do not try to print a section 158825b3c049e70834cf33790a28643ab058b507b35cBen Cheng name. */ 158925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 159025b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 159125b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 159225b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 159325b3c049e70834cf33790a28643ab058b507b35cBen Cheng nentries), 159425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) elf_ndxscn (scn), 159525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 159625b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 159725b3c049e70834cf33790a28643ab058b507b35cBen Cheng nentries); 159825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (class == ELFCLASS32 159925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? gettext ("\ 160025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Offset Type Value Name\n") 160125b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("\ 160225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Offset Type Value Name\n"), 160325b3c049e70834cf33790a28643ab058b507b35cBen Cheng stdout); 160425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 160525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int is_statically_linked = 0; 160625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int cnt = 0; cnt < nentries; ++cnt) 160725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 160825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Rel relmem; 160925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Rel *rel = gelf_getrel (data, cnt, &relmem); 161025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (rel != NULL)) 161125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 161225b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[128]; 161325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym symmem; 161425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word xndx; 161525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 161625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GELF_R_SYM (rel->r_info), 161725b3c049e70834cf33790a28643ab058b507b35cBen Cheng &symmem, &xndx); 161825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (sym == NULL)) 161925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 162025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* As a special case we have to handle relocations in static 162125b3c049e70834cf33790a28643ab058b507b35cBen Cheng executables. This only happens for IRELATIVE relocations 162225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (so far). There is no symbol table. */ 162325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (is_statically_linked == 0) 162425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 162525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the program header and look for a PT_INTERP entry. */ 162625b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_statically_linked = -1; 162725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_type == ET_EXEC) 162825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 162925b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_statically_linked = 1; 163025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 163125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t inner = 0; inner < phnum; ++inner) 163225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 163325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr phdr_mem; 163425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner, 163525b3c049e70834cf33790a28643ab058b507b35cBen Cheng &phdr_mem); 163625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (phdr != NULL && phdr->p_type == PT_INTERP) 163725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 163825b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_statically_linked = -1; 163925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 164025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 164125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 164225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 164325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 164425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 164525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (is_statically_linked > 0 && shdr->sh_link == 0) 164625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\ 164725b3c049e70834cf33790a28643ab058b507b35cBen Cheng %#0*" PRIx64 " %-20s %*s %s\n", 164825b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 164925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 165025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 165125b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 165225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 165325b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 165425b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 165525b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, "", 165625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 165725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 165825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", 165925b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 166025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 166125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 166225b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 166325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 166425b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 166525b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 166625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("INVALID SYMBOL"), 166725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (long int) GELF_R_SYM (rel->r_info)); 166825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 166925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) 167025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", 167125b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 167225b3c049e70834cf33790a28643ab058b507b35cBen Cheng likely (ebl_reloc_type_check (ebl, 167325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GELF_R_TYPE (rel->r_info))) 167425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 167525b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 167625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 167725b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 167825b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 167925b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, sym->st_value, 168025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); 168125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 168225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 168325b3c049e70834cf33790a28643ab058b507b35cBen Cheng destshdr = gelf_getshdr (elf_getscn (ebl->elf, 168425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx == SHN_XINDEX 168525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? xndx : sym->st_shndx), 168625b3c049e70834cf33790a28643ab058b507b35cBen Cheng &destshdr_mem); 168725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 168825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (destshdr == NULL)) 168925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", 169025b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 169125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 169225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 169325b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 169425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 169525b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 169625b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 169725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("INVALID SECTION"), 169825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (long int) (sym->st_shndx == SHN_XINDEX 169925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? xndx : sym->st_shndx)); 170025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 170125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", 170225b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 170325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 170425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 170525b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 170625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 170725b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 170825b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 170925b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, sym->st_value, 171025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 171125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 171225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 171325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 171425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 171525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 171625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 171725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle a relocation section. */ 171825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 171925b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) 172025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 172125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int class = gelf_getclass (ebl->elf); 172225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int nentries = shdr->sh_size / shdr->sh_entsize; 172325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 172425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section. */ 172525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 172625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 172725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 172825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 172925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the symbol table information. */ 173025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 173125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr symshdr_mem; 173225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 173325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *symdata = elf_getdata (symscn, NULL); 173425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 173525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header of the section the relocations are for. */ 173625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr destshdr_mem; 173725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 173825b3c049e70834cf33790a28643ab058b507b35cBen Cheng &destshdr_mem); 173925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 174025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) 174125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 174225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"), 174325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset); 174425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 174525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 174625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 174725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Search for the optional extended section index table. */ 174825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *xndxdata = NULL; 174925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int xndxscnidx = elf_scnshndx (scn); 175025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (xndxscnidx > 0)) 175125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); 175225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 175325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 175425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 175525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 175625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 175725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 175825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 175925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 176025b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 176125b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 176225b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 176325b3c049e70834cf33790a28643ab058b507b35cBen Cheng nentries), 176425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), 176525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 176625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) shdr->sh_info, 176725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), 176825b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 176925b3c049e70834cf33790a28643ab058b507b35cBen Cheng nentries); 177025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (class == ELFCLASS32 177125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? gettext ("\ 177225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Offset Type Value Addend Name\n") 177325b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("\ 177425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Offset Type Value Addend Name\n"), 177525b3c049e70834cf33790a28643ab058b507b35cBen Cheng stdout); 177625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 177725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int is_statically_linked = 0; 177825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int cnt = 0; cnt < nentries; ++cnt) 177925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 178025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Rela relmem; 178125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Rela *rel = gelf_getrela (data, cnt, &relmem); 178225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (rel != NULL)) 178325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 178425b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[64]; 178525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym symmem; 178625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word xndx; 178725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 178825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GELF_R_SYM (rel->r_info), 178925b3c049e70834cf33790a28643ab058b507b35cBen Cheng &symmem, &xndx); 179025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 179125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (sym == NULL)) 179225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 179325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* As a special case we have to handle relocations in static 179425b3c049e70834cf33790a28643ab058b507b35cBen Cheng executables. This only happens for IRELATIVE relocations 179525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (so far). There is no symbol table. */ 179625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (is_statically_linked == 0) 179725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 179825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the program header and look for a PT_INTERP entry. */ 179925b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_statically_linked = -1; 180025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_type == ET_EXEC) 180125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 180225b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_statically_linked = 1; 180325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 180425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t inner = 0; inner < phnum; ++inner) 180525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 180625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr phdr_mem; 180725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner, 180825b3c049e70834cf33790a28643ab058b507b35cBen Cheng &phdr_mem); 180925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (phdr != NULL && phdr->p_type == PT_INTERP) 181025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 181125b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_statically_linked = -1; 181225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 181325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 181425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 181525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 181625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 181725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 181825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (is_statically_linked > 0 && shdr->sh_link == 0) 181925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\ 182025b3c049e70834cf33790a28643ab058b507b35cBen Cheng %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n", 182125b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 182225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 182325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 182425b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 182525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 182625b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 182725b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 182825b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, "", 182925b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel->r_addend, 183025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 183125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 183225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", 183325b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 183425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 183525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 183625b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 183725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 183825b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 183925b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 184025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("INVALID SYMBOL"), 184125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (long int) GELF_R_SYM (rel->r_info)); 184225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 184325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) 184425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\ 184525b3c049e70834cf33790a28643ab058b507b35cBen Cheng %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", 184625b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 184725b3c049e70834cf33790a28643ab058b507b35cBen Cheng likely (ebl_reloc_type_check (ebl, 184825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GELF_R_TYPE (rel->r_info))) 184925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 185025b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 185125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 185225b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 185325b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 185425b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, sym->st_value, 185525b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel->r_addend, 185625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); 185725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 185825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 185925b3c049e70834cf33790a28643ab058b507b35cBen Cheng destshdr = gelf_getshdr (elf_getscn (ebl->elf, 186025b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx == SHN_XINDEX 186125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? xndx : sym->st_shndx), 186225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &destshdr_mem); 186325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 186425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr == NULL)) 186525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", 186625b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 186725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 186825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 186925b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 187025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 187125b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 187225b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 187325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("INVALID SECTION"), 187425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (long int) (sym->st_shndx == SHN_XINDEX 187525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? xndx : sym->st_shndx)); 187625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 187725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\ 187825b3c049e70834cf33790a28643ab058b507b35cBen Cheng %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", 187925b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, rel->r_offset, 188025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 188125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Avoid the leading R_ which isn't carrying any 188225b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 188325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 188425b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) + 2 188525b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("<INVALID RELOC>"), 188625b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, sym->st_value, 188725b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel->r_addend, 188825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 188925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 189025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 189125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 189225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 189325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 189425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 189525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the program header. */ 189625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 189725b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_symtab (Ebl *ebl, int type) 189825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 189925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the symbol table(s). For this we have to search through the 190025b3c049e70834cf33790a28643ab058b507b35cBen Cheng section table. */ 190125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 190225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 190325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 190425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 190525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle the section if it is a symbol table. */ 190625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 190725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 190825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 190925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL && shdr->sh_type == (GElf_Word) type) 191025b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_symtab (ebl, scn, shdr); 191125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 191225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 191325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 191425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 191525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 191625b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 191725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 191825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *versym_data = NULL; 191925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *verneed_data = NULL; 192025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *verdef_data = NULL; 192125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *xndx_data = NULL; 192225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int class = gelf_getclass (ebl->elf); 192325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word verneed_stridx = 0; 192425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word verdef_stridx = 0; 192525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 192625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section. */ 192725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 192825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 192925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 193025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 193125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find out whether we have other sections we might need. */ 193225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *runscn = NULL; 193325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL) 193425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 193525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr runshdr_mem; 193625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem); 193725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 193825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (runshdr != NULL)) 193925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 194025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runshdr->sh_type == SHT_GNU_versym 194125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && runshdr->sh_link == elf_ndxscn (scn)) 194225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Bingo, found the version information. Now get the data. */ 194325b3c049e70834cf33790a28643ab058b507b35cBen Cheng versym_data = elf_getdata (runscn, NULL); 194425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (runshdr->sh_type == SHT_GNU_verneed) 194525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 194625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is the information about the needed versions. */ 194725b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneed_data = elf_getdata (runscn, NULL); 194825b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneed_stridx = runshdr->sh_link; 194925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 195025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (runshdr->sh_type == SHT_GNU_verdef) 195125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 195225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is the information about the defined versions. */ 195325b3c049e70834cf33790a28643ab058b507b35cBen Cheng verdef_data = elf_getdata (runscn, NULL); 195425b3c049e70834cf33790a28643ab058b507b35cBen Cheng verdef_stridx = runshdr->sh_link; 195525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 195625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (runshdr->sh_type == SHT_SYMTAB_SHNDX 195725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && runshdr->sh_link == elf_ndxscn (scn)) 195825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Extended section index. */ 195925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx_data = elf_getdata (runscn, NULL); 196025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 196125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 196225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 196325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 196425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 196525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 196625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 196725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 196825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 196925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now we can compute the number of entries in the section. */ 197025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int nsyms = data->d_size / (class == ELFCLASS32 197125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? sizeof (Elf32_Sym) 197225b3c049e70834cf33790a28643ab058b507b35cBen Cheng : sizeof (Elf64_Sym)); 197325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 197425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n", 197525b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\nSymbol table [%2u] '%s' contains %u entries:\n", 197625b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsyms), 197725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) elf_ndxscn (scn), 197825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms); 197925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr glink; 198025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n", 198125b3c049e70834cf33790a28643ab058b507b35cBen Cheng " %lu local symbols String table: [%2u] '%s'\n", 198225b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info), 198325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned long int) shdr->sh_info, 198425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) shdr->sh_link, 198525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, 198625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 198725b3c049e70834cf33790a28643ab058b507b35cBen Cheng &glink)->sh_name)); 198825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 198925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (class == ELFCLASS32 199025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? gettext ("\ 199125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Num: Value Size Type Bind Vis Ndx Name\n") 199225b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("\ 199325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Num: Value Size Type Bind Vis Ndx Name\n"), 199425b3c049e70834cf33790a28643ab058b507b35cBen Cheng stdout); 199525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 199625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (unsigned int cnt = 0; cnt < nsyms; ++cnt) 199725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 199825b3c049e70834cf33790a28643ab058b507b35cBen Cheng char typebuf[64]; 199925b3c049e70834cf33790a28643ab058b507b35cBen Cheng char bindbuf[64]; 200025b3c049e70834cf33790a28643ab058b507b35cBen Cheng char scnbuf[64]; 200125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word xndx; 200225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym sym_mem; 200325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx); 200425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 200525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (sym == NULL)) 200625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 200725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 200825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the real section index. */ 200925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (sym->st_shndx != SHN_XINDEX)) 201025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx = sym->st_shndx; 201125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 201225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 201325b3c049e70834cf33790a28643ab058b507b35cBen Cheng%5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"), 201425b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt, 201525b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 8 : 16, 201625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value, 201725b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_size, 201825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 201925b3c049e70834cf33790a28643ab058b507b35cBen Cheng typebuf, sizeof (typebuf)), 202025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), 202125b3c049e70834cf33790a28643ab058b507b35cBen Cheng bindbuf, sizeof (bindbuf)), 202225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)), 202325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf, 202425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (scnbuf), NULL, shnum), 202525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, sym->st_name)); 202625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 202725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (versym_data != NULL) 202825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 202925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the version information. */ 203025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Versym versym_mem; 203125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem); 203225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 203325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1)) 203425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 203525b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool is_nobits = false; 203625b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool check_def = xndx != SHN_UNDEF; 203725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 203825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX) 203925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 204025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr symshdr_mem; 204125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *symshdr = 204225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem); 204325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 204425b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_nobits = (symshdr != NULL 204525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && symshdr->sh_type == SHT_NOBITS); 204625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 204725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 204825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (is_nobits || ! check_def) 204925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 205025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We must test both. */ 205125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux vernaux_mem; 205225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux *vernaux = NULL; 205325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t vn_offset = 0; 205425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 205525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed verneed_mem; 205625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0, 205725b3c049e70834cf33790a28643ab058b507b35cBen Cheng &verneed_mem); 205825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (verneed != NULL) 205925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 206025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t vna_offset = vn_offset; 206125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 206225b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux = gelf_getvernaux (verneed_data, 206325b3c049e70834cf33790a28643ab058b507b35cBen Cheng vna_offset += verneed->vn_aux, 206425b3c049e70834cf33790a28643ab058b507b35cBen Cheng &vernaux_mem); 206525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (vernaux != NULL 206625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && vernaux->vna_other != *versym 206725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && vernaux->vna_next != 0) 206825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 206925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Update the offset. */ 207025b3c049e70834cf33790a28643ab058b507b35cBen Cheng vna_offset += vernaux->vna_next; 207125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 207225b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux = (vernaux->vna_next == 0 207325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? NULL 207425b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gelf_getvernaux (verneed_data, 207525b3c049e70834cf33790a28643ab058b507b35cBen Cheng vna_offset, 207625b3c049e70834cf33790a28643ab058b507b35cBen Cheng &vernaux_mem)); 207725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 207825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 207925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether we found the version. */ 208025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (vernaux != NULL && vernaux->vna_other == *versym) 208125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Found it. */ 208225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 208325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 208425b3c049e70834cf33790a28643ab058b507b35cBen Cheng vn_offset += verneed->vn_next; 208525b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneed = (verneed->vn_next == 0 208625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? NULL 208725b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gelf_getverneed (verneed_data, vn_offset, 208825b3c049e70834cf33790a28643ab058b507b35cBen Cheng &verneed_mem)); 208925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 209025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 209125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (vernaux != NULL && vernaux->vna_other == *versym) 209225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 209325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("@%s (%u)", 209425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, verneed_stridx, 209525b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux->vna_name), 209625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) vernaux->vna_other); 209725b3c049e70834cf33790a28643ab058b507b35cBen Cheng check_def = 0; 209825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 209925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (! is_nobits)) 210025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("bad dynamic symbol")); 210125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 210225b3c049e70834cf33790a28643ab058b507b35cBen Cheng check_def = 1; 210325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 210425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 210525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (check_def && *versym != 0x8001) 210625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 210725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We must test both. */ 210825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t vd_offset = 0; 210925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 211025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdef verdef_mem; 211125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0, 211225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &verdef_mem); 211325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (verdef != NULL) 211425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 211525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (verdef->vd_ndx == (*versym & 0x7fff)) 211625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Found the definition. */ 211725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 211825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 211925b3c049e70834cf33790a28643ab058b507b35cBen Cheng vd_offset += verdef->vd_next; 212025b3c049e70834cf33790a28643ab058b507b35cBen Cheng verdef = (verdef->vd_next == 0 212125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? NULL 212225b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gelf_getverdef (verdef_data, vd_offset, 212325b3c049e70834cf33790a28643ab058b507b35cBen Cheng &verdef_mem)); 212425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 212525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 212625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (verdef != NULL) 212725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 212825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdaux verdaux_mem; 212925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdaux *verdaux 213025b3c049e70834cf33790a28643ab058b507b35cBen Cheng = gelf_getverdaux (verdef_data, 213125b3c049e70834cf33790a28643ab058b507b35cBen Cheng vd_offset + verdef->vd_aux, 213225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &verdaux_mem); 213325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 213425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (verdaux != NULL) 213525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ((*versym & 0x8000) ? "@%s" : "@@%s", 213625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, verdef_stridx, 213725b3c049e70834cf33790a28643ab058b507b35cBen Cheng verdaux->vda_name)); 213825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 213925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 214025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 214125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 214225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 214325b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked ('\n'); 214425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 214525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 214625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 214725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 214825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print version information. */ 214925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 215025b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_verinfo (Ebl *ebl) 215125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 215225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the version information sections. For this we have to 215325b3c049e70834cf33790a28643ab058b507b35cBen Cheng search through the section table. */ 215425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 215525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 215625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 215725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 215825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle the section if it is part of the versioning handling. */ 215925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 216025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 216125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 216225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (shdr != NULL)) 216325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 216425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type == SHT_GNU_verneed) 216525b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_verneed (ebl, scn, shdr); 216625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (shdr->sh_type == SHT_GNU_verdef) 216725b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_verdef (ebl, scn, shdr); 216825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (shdr->sh_type == SHT_GNU_versym) 216925b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_versym (ebl, scn, shdr); 217025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 217125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 217225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 217325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 217425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 217525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 217625b3c049e70834cf33790a28643ab058b507b35cBen Chengget_ver_flags (unsigned int flags) 217725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 217825b3c049e70834cf33790a28643ab058b507b35cBen Cheng static char buf[32]; 217925b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *endp; 218025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 218125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (flags == 0) 218225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return gettext ("none"); 218325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 218425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (flags & VER_FLG_BASE) 218525b3c049e70834cf33790a28643ab058b507b35cBen Cheng endp = stpcpy (buf, "BASE "); 218625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 218725b3c049e70834cf33790a28643ab058b507b35cBen Cheng endp = buf; 218825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 218925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (flags & VER_FLG_WEAK) 219025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 219125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (endp != buf) 219225b3c049e70834cf33790a28643ab058b507b35cBen Cheng endp = stpcpy (endp, "| "); 219325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 219425b3c049e70834cf33790a28643ab058b507b35cBen Cheng endp = stpcpy (endp, "WEAK "); 219525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 219625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 219725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))) 219825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 219925b3c049e70834cf33790a28643ab058b507b35cBen Cheng strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp); 220025b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf[sizeof (buf) - 1] = '\0'; 220125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 220225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 220325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return buf; 220425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 220525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 220625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 220725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 220825b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 220925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 221025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int class = gelf_getclass (ebl->elf); 221125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 221225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section. */ 221325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 221425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 221525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 221625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 221725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 221825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 221925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 222025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 222125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 222225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 222325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr glink; 222425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 222525b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 222625b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 222725b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 222825b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info), 222925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) elf_ndxscn (scn), 223025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info, 223125b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 223225b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 223325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) shdr->sh_link, 223425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, 223525b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 223625b3c049e70834cf33790a28643ab058b507b35cBen Cheng &glink)->sh_name)); 223725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 223825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int offset = 0; 223925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int cnt = shdr->sh_info; --cnt >= 0; ) 224025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 224125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data at the next offset. */ 224225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed needmem; 224325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 224425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (need == NULL)) 224525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 224625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 224725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"), 224825b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset, (unsigned short int) need->vn_version, 224925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, need->vn_file), 225025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned short int) need->vn_cnt); 225125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 225225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int auxoffset = offset + need->vn_aux; 225325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 225425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 225525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux auxmem; 225625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 225725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (aux == NULL)) 225825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 225925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 226025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"), 226125b3c049e70834cf33790a28643ab058b507b35cBen Cheng auxoffset, 226225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name), 226325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_ver_flags (aux->vna_flags), 226425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned short int) aux->vna_other); 226525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 226625b3c049e70834cf33790a28643ab058b507b35cBen Cheng auxoffset += aux->vna_next; 226725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 226825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 226925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the next offset. */ 227025b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += need->vn_next; 227125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 227225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 227325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 227425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 227525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 227625b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 227725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 227825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section. */ 227925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 228025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 228125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 228225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 228325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 228425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 228525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 228625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 228725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 228825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 228925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int class = gelf_getclass (ebl->elf); 229025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr glink; 229125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 229225b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 229325b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 229425b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 229525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info), 229625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) elf_ndxscn (scn), 229725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 229825b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info, 229925b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 230025b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 230125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) shdr->sh_link, 230225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, 230325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 230425b3c049e70834cf33790a28643ab058b507b35cBen Cheng &glink)->sh_name)); 230525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 230625b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int offset = 0; 230725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int cnt = shdr->sh_info; --cnt >= 0; ) 230825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 230925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data at the next offset. */ 231025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdef defmem; 231125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 231225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (def == NULL)) 231325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 231425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 231525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int auxoffset = offset + def->vd_aux; 231625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdaux auxmem; 231725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 231825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (aux == NULL)) 231925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 232025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 232125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 232225b3c049e70834cf33790a28643ab058b507b35cBen Cheng %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"), 232325b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset, def->vd_version, 232425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_ver_flags (def->vd_flags), 232525b3c049e70834cf33790a28643ab058b507b35cBen Cheng def->vd_ndx, 232625b3c049e70834cf33790a28643ab058b507b35cBen Cheng def->vd_cnt, 232725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); 232825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 232925b3c049e70834cf33790a28643ab058b507b35cBen Cheng auxoffset += aux->vda_next; 233025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 233125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 233225b3c049e70834cf33790a28643ab058b507b35cBen Cheng aux = gelf_getverdaux (data, auxoffset, &auxmem); 233325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (aux == NULL)) 233425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 233525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 233625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %#06x: Parent %d: %s\n"), 233725b3c049e70834cf33790a28643ab058b507b35cBen Cheng auxoffset, cnt2, 233825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); 233925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 234025b3c049e70834cf33790a28643ab058b507b35cBen Cheng auxoffset += aux->vda_next; 234125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 234225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 234325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the next offset. */ 234425b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += def->vd_next; 234525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 234625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 234725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 234825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 234925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 235025b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 235125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 235225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int class = gelf_getclass (ebl->elf); 235325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char **vername; 235425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char **filename; 235525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 235625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section. */ 235725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 235825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 235925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 236025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 236125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 236225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 236325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 236425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 236525b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 236625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 236725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to find the version definition section and extract the 236825b3c049e70834cf33790a28643ab058b507b35cBen Cheng version names. */ 236925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *defscn = NULL; 237025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *needscn = NULL; 237125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 237225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *verscn = NULL; 237325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL) 237425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 237525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr vershdr_mem; 237625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem); 237725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 237825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (vershdr != NULL)) 237925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 238025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (vershdr->sh_type == SHT_GNU_verdef) 238125b3c049e70834cf33790a28643ab058b507b35cBen Cheng defscn = verscn; 238225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (vershdr->sh_type == SHT_GNU_verneed) 238325b3c049e70834cf33790a28643ab058b507b35cBen Cheng needscn = verscn; 238425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 238525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 238625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 238725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nvername; 238825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (defscn != NULL || needscn != NULL) 238925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 239025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have a version information (better should have). Now get 239125b3c049e70834cf33790a28643ab058b507b35cBen Cheng the version names. First find the maximum version number. */ 239225b3c049e70834cf33790a28643ab058b507b35cBen Cheng nvername = 0; 239325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (defscn != NULL) 239425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 239525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Run through the version definitions and find the highest 239625b3c049e70834cf33790a28643ab058b507b35cBen Cheng index. */ 239725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int offset = 0; 239825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *defdata; 239925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr defshdrmem; 240025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *defshdr; 240125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 240225b3c049e70834cf33790a28643ab058b507b35cBen Cheng defdata = elf_getdata (defscn, NULL); 240325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (defdata == NULL)) 240425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 240525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 240625b3c049e70834cf33790a28643ab058b507b35cBen Cheng defshdr = gelf_getshdr (defscn, &defshdrmem); 240725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (defshdr == NULL)) 240825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 240925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 241025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) 241125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 241225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdef defmem; 241325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdef *def; 241425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 241525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data at the next offset. */ 241625b3c049e70834cf33790a28643ab058b507b35cBen Cheng def = gelf_getverdef (defdata, offset, &defmem); 241725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (def == NULL)) 241825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 241925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 242025b3c049e70834cf33790a28643ab058b507b35cBen Cheng nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff)); 242125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 242225b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += def->vd_next; 242325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 242425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 242525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (needscn != NULL) 242625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 242725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int offset = 0; 242825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *needdata; 242925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr needshdrmem; 243025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *needshdr; 243125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 243225b3c049e70834cf33790a28643ab058b507b35cBen Cheng needdata = elf_getdata (needscn, NULL); 243325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (needdata == NULL)) 243425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 243525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 243625b3c049e70834cf33790a28643ab058b507b35cBen Cheng needshdr = gelf_getshdr (needscn, &needshdrmem); 243725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (needshdr == NULL)) 243825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 243925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 244025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) 244125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 244225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed needmem; 244325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed *need; 244425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int auxoffset; 244525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int cnt2; 244625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 244725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data at the next offset. */ 244825b3c049e70834cf33790a28643ab058b507b35cBen Cheng need = gelf_getverneed (needdata, offset, &needmem); 244925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (need == NULL)) 245025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 245125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 245225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Run through the auxiliary entries. */ 245325b3c049e70834cf33790a28643ab058b507b35cBen Cheng auxoffset = offset + need->vn_aux; 245425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt2 = need->vn_cnt; --cnt2 >= 0; ) 245525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 245625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux auxmem; 245725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux *aux; 245825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 245925b3c049e70834cf33790a28643ab058b507b35cBen Cheng aux = gelf_getvernaux (needdata, auxoffset, &auxmem); 246025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (aux == NULL)) 246125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 246225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 246325b3c049e70834cf33790a28643ab058b507b35cBen Cheng nvername = MAX (nvername, 246425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (size_t) (aux->vna_other & 0x7fff)); 246525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 246625b3c049e70834cf33790a28643ab058b507b35cBen Cheng auxoffset += aux->vna_next; 246725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 246825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 246925b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += need->vn_next; 247025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 247125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 247225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 247325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is the number of versions we know about. */ 247425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nvername; 247525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 247625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Allocate the array. */ 247725b3c049e70834cf33790a28643ab058b507b35cBen Cheng vername = (const char **) alloca (nvername * sizeof (const char *)); 247825b3c049e70834cf33790a28643ab058b507b35cBen Cheng filename = (const char **) alloca (nvername * sizeof (const char *)); 247925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 248025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Run through the data structures again and collect the strings. */ 248125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (defscn != NULL) 248225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 248325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Run through the version definitions and find the highest 248425b3c049e70834cf33790a28643ab058b507b35cBen Cheng index. */ 248525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int offset = 0; 248625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *defdata; 248725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr defshdrmem; 248825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *defshdr; 248925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 249025b3c049e70834cf33790a28643ab058b507b35cBen Cheng defdata = elf_getdata (defscn, NULL); 249125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (defdata == NULL)) 249225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 249325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 249425b3c049e70834cf33790a28643ab058b507b35cBen Cheng defshdr = gelf_getshdr (defscn, &defshdrmem); 249525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (defshdr == NULL)) 249625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 249725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 249825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) 249925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 250025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 250125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data at the next offset. */ 250225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdef defmem; 250325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem); 250425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdaux auxmem; 250525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verdaux *aux = gelf_getverdaux (defdata, 250625b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset + def->vd_aux, 250725b3c049e70834cf33790a28643ab058b507b35cBen Cheng &auxmem); 250825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (def == NULL || aux == NULL)) 250925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 251025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 251125b3c049e70834cf33790a28643ab058b507b35cBen Cheng vername[def->vd_ndx & 0x7fff] 251225b3c049e70834cf33790a28643ab058b507b35cBen Cheng = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name); 251325b3c049e70834cf33790a28643ab058b507b35cBen Cheng filename[def->vd_ndx & 0x7fff] = NULL; 251425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 251525b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += def->vd_next; 251625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 251725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 251825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (needscn != NULL) 251925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 252025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int offset = 0; 252125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 252225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *needdata = elf_getdata (needscn, NULL); 252325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr needshdrmem; 252425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem); 252525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (needdata == NULL || needshdr == NULL)) 252625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 252725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 252825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) 252925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 253025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data at the next offset. */ 253125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed needmem; 253225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed *need = gelf_getverneed (needdata, offset, 253325b3c049e70834cf33790a28643ab058b507b35cBen Cheng &needmem); 253425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (need == NULL)) 253525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 253625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 253725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Run through the auxiliary entries. */ 253825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int auxoffset = offset + need->vn_aux; 253925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 254025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 254125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux auxmem; 254225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset, 254325b3c049e70834cf33790a28643ab058b507b35cBen Cheng &auxmem); 254425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (aux == NULL)) 254525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 254625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 254725b3c049e70834cf33790a28643ab058b507b35cBen Cheng vername[aux->vna_other & 0x7fff] 254825b3c049e70834cf33790a28643ab058b507b35cBen Cheng = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name); 254925b3c049e70834cf33790a28643ab058b507b35cBen Cheng filename[aux->vna_other & 0x7fff] 255025b3c049e70834cf33790a28643ab058b507b35cBen Cheng = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file); 255125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 255225b3c049e70834cf33790a28643ab058b507b35cBen Cheng auxoffset += aux->vna_next; 255325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 255425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 255525b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += need->vn_next; 255625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 255725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 255825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 255925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 256025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 256125b3c049e70834cf33790a28643ab058b507b35cBen Cheng vername = NULL; 256225b3c049e70834cf33790a28643ab058b507b35cBen Cheng nvername = 1; 256325b3c049e70834cf33790a28643ab058b507b35cBen Cheng filename = NULL; 256425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 256525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 256625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Print the header. */ 256725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr glink; 256825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 256925b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", 257025b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 257125b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", 257225b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size / shdr->sh_entsize), 257325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) elf_ndxscn (scn), 257425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 257525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (shdr->sh_size / shdr->sh_entsize), 257625b3c049e70834cf33790a28643ab058b507b35cBen Cheng class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 257725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 257825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) shdr->sh_link, 257925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, 258025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 258125b3c049e70834cf33790a28643ab058b507b35cBen Cheng &glink)->sh_name)); 258225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 258325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now we can finally look at the actual contents of this section. */ 258425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 258525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 258625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cnt % 2 == 0) 258725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\n %4d:", cnt); 258825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 258925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Versym symmem; 259025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Versym *sym = gelf_getversym (data, cnt, &symmem); 259125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym == NULL) 259225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 259325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 259425b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (*sym) 259525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 259625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ssize_t n; 259725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 0: 259825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext (" 0 *local* "), 259925b3c049e70834cf33790a28643ab058b507b35cBen Cheng stdout); 260025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 260125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 260225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 1: 260325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext (" 1 *global* "), 260425b3c049e70834cf33790a28643ab058b507b35cBen Cheng stdout); 260525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 260625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 260725b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 260825b3c049e70834cf33790a28643ab058b507b35cBen Cheng n = printf ("%4d%c%s", 260925b3c049e70834cf33790a28643ab058b507b35cBen Cheng *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ', 261025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) (*sym & 0x7fff) < nvername 261125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? vername[*sym & 0x7fff] : "???"); 261225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((unsigned int) (*sym & 0x7fff) < nvername 261325b3c049e70834cf33790a28643ab058b507b35cBen Cheng && filename[*sym & 0x7fff] != NULL) 261425b3c049e70834cf33790a28643ab058b507b35cBen Cheng n += printf ("(%s)", filename[*sym & 0x7fff]); 261525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s", MAX (0, 33 - (int) n), " "); 261625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 261725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 261825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 261925b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked ('\n'); 262025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 262125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 262225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 262325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 262425b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx, 262525b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t maxlength, Elf32_Word nbucket, 262625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr) 262725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 262825b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t)); 262925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 263025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 263125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++counts[lengths[cnt]]; 263225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 263325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr glink; 263425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 263525b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 263625b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 263725b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 263825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nbucket), 263925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) elf_ndxscn (scn), 264025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 264125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) nbucket, 264225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18, 264325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addr, 264425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 264525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) shdr->sh_link, 264625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, 264725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 264825b3c049e70834cf33790a28643ab058b507b35cBen Cheng &glink)->sh_name)); 264925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 265025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (extrastr != NULL) 265125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs (extrastr, stdout); 265225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 265325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (nbucket > 0)) 265425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 265525b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t success = 0; 265625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 265725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* xgettext:no-c-format */ 265825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext ("\ 265925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Length Number % of total Coverage\n"), stdout); 266025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"), 266125b3c049e70834cf33790a28643ab058b507b35cBen Cheng counts[0], (counts[0] * 100.0) / nbucket); 266225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 266325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t nzero_counts = 0; 266425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) 266525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 266625b3c049e70834cf33790a28643ab058b507b35cBen Cheng nzero_counts += counts[cnt] * cnt; 266725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 266825b3c049e70834cf33790a28643ab058b507b35cBen Cheng%7d %6" PRIu32 " %5.1f%% %5.1f%%\n"), 266925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket, 267025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (nzero_counts * 100.0) / nsyms); 267125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 267225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 267325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word acc = 0; 267425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) 267525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 267625b3c049e70834cf33790a28643ab058b507b35cBen Cheng acc += cnt; 267725b3c049e70834cf33790a28643ab058b507b35cBen Cheng success += counts[cnt] * acc; 267825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 267925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 268025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 268125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Average number of tests: successful lookup: %f\n\ 268225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsuccessful lookup: %f\n"), 268325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (double) success / (double) nzero_counts, 268425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (double) nzero_counts / (double) nbucket); 268525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 268625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 268725b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (counts); 268825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 268925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 269025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 269125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* This function handles the traditional System V-style hash table format. */ 269225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 269325b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 269425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 269525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 269625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 269725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 269825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get data for section %d: %s"), 269925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) elf_ndxscn (scn), elf_errmsg (-1)); 270025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 270125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 270225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 270325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 270425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 270525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2]; 270625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket]; 270725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 270825b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 270925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 271025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t maxlength = 0; 271125b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t nsyms = 0; 271225b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 271325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 271425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word inner = bucket[cnt]; 271525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (inner > 0 && inner < nchain) 271625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 271725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nsyms; 271825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (maxlength < ++lengths[cnt]) 271925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++maxlength; 272025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 272125b3c049e70834cf33790a28643ab058b507b35cBen Cheng inner = chain[inner]; 272225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 272325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 272425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 272525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 272625b3c049e70834cf33790a28643ab058b507b35cBen Cheng lengths, NULL); 272725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 272825b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (lengths); 272925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 273025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 273125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 273225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* This function handles the incorrect, System V-style hash table 273325b3c049e70834cf33790a28643ab058b507b35cBen Cheng format some 64-bit architectures use. */ 273425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 273525b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 273625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 273725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 273825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 273925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 274025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get data for section %d: %s"), 274125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) elf_ndxscn (scn), elf_errmsg (-1)); 274225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 274325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 274425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 274525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; 274625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; 274725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2]; 274825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket]; 274925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 275025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 275125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 275225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t maxlength = 0; 275325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t nsyms = 0; 275425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) 275525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 275625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf64_Xword inner = bucket[cnt]; 275725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (inner > 0 && inner < nchain) 275825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 275925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nsyms; 276025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (maxlength < ++lengths[cnt]) 276125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++maxlength; 276225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 276325b3c049e70834cf33790a28643ab058b507b35cBen Cheng inner = chain[inner]; 276425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 276525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 276625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 276725b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 276825b3c049e70834cf33790a28643ab058b507b35cBen Cheng lengths, NULL); 276925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 277025b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (lengths); 277125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 277225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 277325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 277425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* This function handles the GNU-style hash table format. */ 277525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 277625b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 277725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 277825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 277925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 278025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 278125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get data for section %d: %s"), 278225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) elf_ndxscn (scn), elf_errmsg (-1)); 278325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 278425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 278525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 278625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 278725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; 278825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 278925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Next comes the size of the bitmap. It's measured in words for 279025b3c049e70834cf33790a28643ab058b507b35cBen Cheng the architecture. It's 32 bits for 32 bit archs, and 64 bits for 279125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 64 bit archs. */ 279225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; 279325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (gelf_getclass (ebl->elf) == ELFCLASS64) 279425b3c049e70834cf33790a28643ab058b507b35cBen Cheng bitmask_words *= 2; 279525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 279625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; 279725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 279825b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 279925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 280025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4]; 280125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words]; 280225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words 280325b3c049e70834cf33790a28643ab058b507b35cBen Cheng + nbucket]; 280425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 280525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute distribution of chain lengths. */ 280625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t maxlength = 0; 280725b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t nsyms = 0; 280825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 280925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (bucket[cnt] != 0) 281025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 281125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word inner = bucket[cnt] - symbias; 281225b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 281325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 281425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nsyms; 281525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (maxlength < ++lengths[cnt]) 281625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++maxlength; 281725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 281825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((chain[inner++] & 1) == 0); 281925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 282025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 282125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Count bits in bitmask. */ 282225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t nbits = 0; 282325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt) 282425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 282525b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast32_t word = bitmask[cnt]; 282625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 282725b3c049e70834cf33790a28643ab058b507b35cBen Cheng word = (word & 0x55555555) + ((word >> 1) & 0x55555555); 282825b3c049e70834cf33790a28643ab058b507b35cBen Cheng word = (word & 0x33333333) + ((word >> 2) & 0x33333333); 282925b3c049e70834cf33790a28643ab058b507b35cBen Cheng word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f); 283025b3c049e70834cf33790a28643ab058b507b35cBen Cheng word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff); 283125b3c049e70834cf33790a28643ab058b507b35cBen Cheng nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff); 283225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 283325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 283425b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *str; 283525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (asprintf (&str, gettext ("\ 283625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Symbol Bias: %u\n\ 283725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"), 283825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) symbias, 283925b3c049e70834cf33790a28643ab058b507b35cBen Cheng bitmask_words * sizeof (Elf32_Word), 284025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((nbits * 100 + 50) 284125b3c049e70834cf33790a28643ab058b507b35cBen Cheng / (uint_fast32_t) (bitmask_words 284225b3c049e70834cf33790a28643ab058b507b35cBen Cheng * sizeof (Elf32_Word) * 8)), 284325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) shift) == -1)) 284425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("memory exhausted")); 284525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 284625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 284725b3c049e70834cf33790a28643ab058b507b35cBen Cheng lengths, str); 284825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 284925b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (str); 285025b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (lengths); 285125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 285225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 285325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 285425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Find the symbol table(s). For this we have to search through the 285525b3c049e70834cf33790a28643ab058b507b35cBen Cheng section table. */ 285625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 285725b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_hash (Ebl *ebl) 285825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 285925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 286025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 286125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 286225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 286325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 286425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 286525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 286625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 286725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 286825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle the section if it is a symbol table. */ 286925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 287025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 287125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 287225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (shdr != NULL)) 287325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 287425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type == SHT_HASH) 287525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 287625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) 287725b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_sysv_hash64 (ebl, scn, shdr, shstrndx); 287825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 287925b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_sysv_hash (ebl, scn, shdr, shstrndx); 288025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 288125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (shdr->sh_type == SHT_GNU_HASH) 288225b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_gnu_hash (ebl, scn, shdr, shstrndx); 288325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 288425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 288525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 288625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 288725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 288825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 288925b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_liblist (Ebl *ebl) 289025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 289125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the library list sections. For this we have to search 289225b3c049e70834cf33790a28643ab058b507b35cBen Cheng through the section table. */ 289325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 289425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 289525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 289625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 289725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 289825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 289925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 290025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 290125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 290225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 290325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 290425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 290525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 290625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST) 290725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 290825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int nentries = shdr->sh_size / shdr->sh_entsize; 290925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 291025b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 291125b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 291225b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 291325b3c049e70834cf33790a28643ab058b507b35cBen Cheng nentries), 291425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), 291525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 291625b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset, 291725b3c049e70834cf33790a28643ab058b507b35cBen Cheng nentries); 291825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 291925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 292025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 292125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 292225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 292325b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("\ 292425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Library Time Stamp Checksum Version Flags")); 292525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 292625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int cnt = 0; cnt < nentries; ++cnt) 292725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 292825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Lib lib_mem; 292925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem); 293025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (lib == NULL)) 293125b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 293225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 293325b3c049e70834cf33790a28643ab058b507b35cBen Cheng time_t t = (time_t) lib->l_time_stamp; 293425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct tm *tm = gmtime (&t); 293525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (tm == NULL)) 293625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 293725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 293825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n", 293925b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name), 294025b3c049e70834cf33790a28643ab058b507b35cBen Cheng tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 294125b3c049e70834cf33790a28643ab058b507b35cBen Cheng tm->tm_hour, tm->tm_min, tm->tm_sec, 294225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) lib->l_checksum, 294325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) lib->l_version, 294425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (unsigned int) lib->l_flags); 294525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 294625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 294725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 294825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 294925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 295025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 295125b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_attributes (Ebl *ebl, const GElf_Ehdr *ehdr) 295225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 295325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the object attributes sections. For this we have to search 295425b3c049e70834cf33790a28643ab058b507b35cBen Cheng through the section table. */ 295525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 295625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 295725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 295825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 295925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 296025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 296125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 296225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 296325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 296425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 296525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 296625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 296725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 296825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES 296925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shdr->sh_type != SHT_ARM_ATTRIBUTES 297025b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ehdr->e_machine != EM_ARM))) 297125b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 297225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 297325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 297425b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nObject attributes section [%2zu] '%s' of %" PRIu64 297525b3c049e70834cf33790a28643ab058b507b35cBen Cheng " bytes at offset %#0" PRIx64 ":\n"), 297625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), 297725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 297825b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size, shdr->sh_offset); 297925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 298025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 298125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 298225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 298325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 298425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *p = data->d_buf; 298525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 298625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (*p++ != 'A')) 298725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 298825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 298925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext (" Owner Size\n"), stdout); 299025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 299125b3c049e70834cf33790a28643ab058b507b35cBen Cheng inline size_t left (void) 299225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 299325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return (const unsigned char *) data->d_buf + data->d_size - p; 299425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 299525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 299625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (left () >= 4) 299725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 299825b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t len; 299925b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (&len, p, sizeof len); 300025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 300125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 300225b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONVERT (len); 300325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 300425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (len > left ())) 300525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 300625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 300725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *name = p + sizeof len; 300825b3c049e70834cf33790a28643ab058b507b35cBen Cheng p += len; 300925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 301025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned const char *q = memchr (name, '\0', len); 301125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (q == NULL)) 301225b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 301325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++q; 301425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 301525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %-13s %4" PRIu32 "\n"), name, len); 301625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 301725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type != SHT_GNU_ATTRIBUTES 301825b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (q - name == sizeof "gnu" 301925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && !memcmp (name, "gnu", sizeof "gnu"))) 302025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (q < p) 302125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 302225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const sub = q; 302325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 302425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int subsection_tag; 302525b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (subsection_tag, q); 302625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (q >= p)) 302725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 302825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 302925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t subsection_len; 303025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len)) 303125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 303225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 303325b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (&subsection_len, q, sizeof subsection_len); 303425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 303525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 303625b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONVERT (subsection_len); 303725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 303825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (p - sub < (ptrdiff_t) subsection_len)) 303925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 304025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 304125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *r = q + sizeof subsection_len; 304225b3c049e70834cf33790a28643ab058b507b35cBen Cheng q = sub + subsection_len; 304325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 304425b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (subsection_tag) 304525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 304625b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 304725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %-4u %12" PRIu32 "\n"), 304825b3c049e70834cf33790a28643ab058b507b35cBen Cheng subsection_tag, subsection_len); 304925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 305025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 305125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 1: /* Tag_File */ 305225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" File: %11" PRIu32 "\n"), 305325b3c049e70834cf33790a28643ab058b507b35cBen Cheng subsection_len); 305425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 305525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (r < q) 305625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 305725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int tag; 305825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (tag, r); 305925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (r >= q)) 306025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 306125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 306225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t value = 0; 306325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *string = NULL; 306425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (tag == 32 || (tag & 1) == 0) 306525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 306625b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (value, r); 306725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (r > q) 306825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 306925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 307025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (tag == 32 || (tag & 1) != 0) 307125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 307225b3c049e70834cf33790a28643ab058b507b35cBen Cheng r = memchr (r, '\0', q - r); 307325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (r == NULL) 307425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 307525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++r; 307625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 307725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 307825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *tag_name = NULL; 307925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *value_name = NULL; 308025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_check_object_attribute (ebl, (const char *) name, 308125b3c049e70834cf33790a28643ab058b507b35cBen Cheng tag, value, 308225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &tag_name, &value_name); 308325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 308425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (tag_name != NULL) 308525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 308625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (tag == 32) 308725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %s: %" PRId64 ", %s\n"), 308825b3c049e70834cf33790a28643ab058b507b35cBen Cheng tag_name, value, string); 308925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (string == NULL && value_name == NULL) 309025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %s: %" PRId64 "\n"), 309125b3c049e70834cf33790a28643ab058b507b35cBen Cheng tag_name, value); 309225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 309325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %s: %s\n"), 309425b3c049e70834cf33790a28643ab058b507b35cBen Cheng tag_name, string ?: value_name); 309525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 309625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 309725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 309825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (tag != 32); 309925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (string == NULL) 310025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %u: %" PRId64 "\n"), 310125b3c049e70834cf33790a28643ab058b507b35cBen Cheng tag, value); 310225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 310325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %u: %s\n"), 310425b3c049e70834cf33790a28643ab058b507b35cBen Cheng tag, string); 310525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 310625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 310725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 310825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 310925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 311025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 311125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 311225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 311325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 311425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic char * 311525b3c049e70834cf33790a28643ab058b507b35cBen Chengformat_dwarf_addr (Dwfl_Module *dwflmod, 311625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int address_size, Dwarf_Addr address) 311725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 311825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* See if there is a name we can give for this address. */ 311925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym sym; 312025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = print_address_names 312125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? dwfl_module_addrsym (dwflmod, address, &sym, NULL) : NULL; 312225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name != NULL) 312325b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym.st_value = address - sym.st_value; 312425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 312525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Relativize the address. */ 312625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int n = dwfl_module_relocations (dwflmod); 312725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address); 312825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 312925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* In an ET_REL file there is a section name to refer to. */ 313025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *scn = (i < 0 ? NULL 313125b3c049e70834cf33790a28643ab058b507b35cBen Cheng : dwfl_module_relocation_info (dwflmod, i, NULL)); 313225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 313325b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *result; 313425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((name != NULL 313525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? (sym.st_value != 0 313625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? (scn != NULL 313725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? (address_size == 0 313825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? asprintf (&result, 313925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"), 314025b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn, address, name, sym.st_value) 314125b3c049e70834cf33790a28643ab058b507b35cBen Cheng : asprintf (&result, 314225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"), 314325b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn, 2 + address_size * 2, address, 314425b3c049e70834cf33790a28643ab058b507b35cBen Cheng name, sym.st_value)) 314525b3c049e70834cf33790a28643ab058b507b35cBen Cheng : (address_size == 0 314625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? asprintf (&result, 314725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"), 314825b3c049e70834cf33790a28643ab058b507b35cBen Cheng address, name, sym.st_value) 314925b3c049e70834cf33790a28643ab058b507b35cBen Cheng : asprintf (&result, 315025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"), 315125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2 + address_size * 2, address, 315225b3c049e70834cf33790a28643ab058b507b35cBen Cheng name, sym.st_value))) 315325b3c049e70834cf33790a28643ab058b507b35cBen Cheng : (scn != NULL 315425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? (address_size == 0 315525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? asprintf (&result, 315625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s+%#" PRIx64 " <%s>"), 315725b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn, address, name) 315825b3c049e70834cf33790a28643ab058b507b35cBen Cheng : asprintf (&result, 315925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s+%#0*" PRIx64 " <%s>"), 316025b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn, 2 + address_size * 2, address, name)) 316125b3c049e70834cf33790a28643ab058b507b35cBen Cheng : (address_size == 0 316225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? asprintf (&result, 316325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%#" PRIx64 " <%s>"), 316425b3c049e70834cf33790a28643ab058b507b35cBen Cheng address, name) 316525b3c049e70834cf33790a28643ab058b507b35cBen Cheng : asprintf (&result, 316625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%#0*" PRIx64 " <%s>"), 316725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2 + address_size * 2, address, name)))) 316825b3c049e70834cf33790a28643ab058b507b35cBen Cheng : (scn != NULL 316925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? (address_size == 0 317025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? asprintf (&result, 317125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s+%#" PRIx64), 317225b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn, address) 317325b3c049e70834cf33790a28643ab058b507b35cBen Cheng : asprintf (&result, 317425b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s+%#0*" PRIx64), 317525b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn, 2 + address_size * 2, address)) 317625b3c049e70834cf33790a28643ab058b507b35cBen Cheng : (address_size == 0 317725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? asprintf (&result, 317825b3c049e70834cf33790a28643ab058b507b35cBen Cheng "%#" PRIx64, 317925b3c049e70834cf33790a28643ab058b507b35cBen Cheng address) 318025b3c049e70834cf33790a28643ab058b507b35cBen Cheng : asprintf (&result, 318125b3c049e70834cf33790a28643ab058b507b35cBen Cheng "%#0*" PRIx64, 318225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2 + address_size * 2, address)))) < 0) 318325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, _("memory exhausted")); 318425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 318525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 318625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 318725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 318825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 318925b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_tag_string (unsigned int tag) 319025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 319125b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known_tags[] = 319225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 319325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_array_type] = "array_type", 319425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_class_type] = "class_type", 319525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_entry_point] = "entry_point", 319625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_enumeration_type] = "enumeration_type", 319725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_formal_parameter] = "formal_parameter", 319825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_imported_declaration] = "imported_declaration", 319925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_label] = "label", 320025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_lexical_block] = "lexical_block", 320125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_member] = "member", 320225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_pointer_type] = "pointer_type", 320325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_reference_type] = "reference_type", 320425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_compile_unit] = "compile_unit", 320525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_string_type] = "string_type", 320625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_structure_type] = "structure_type", 320725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_subroutine_type] = "subroutine_type", 320825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_typedef] = "typedef", 320925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_union_type] = "union_type", 321025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_unspecified_parameters] = "unspecified_parameters", 321125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_variant] = "variant", 321225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_common_block] = "common_block", 321325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_common_inclusion] = "common_inclusion", 321425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_inheritance] = "inheritance", 321525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_inlined_subroutine] = "inlined_subroutine", 321625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_module] = "module", 321725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_ptr_to_member_type] = "ptr_to_member_type", 321825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_set_type] = "set_type", 321925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_subrange_type] = "subrange_type", 322025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_with_stmt] = "with_stmt", 322125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_access_declaration] = "access_declaration", 322225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_base_type] = "base_type", 322325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_catch_block] = "catch_block", 322425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_const_type] = "const_type", 322525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_constant] = "constant", 322625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_enumerator] = "enumerator", 322725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_file_type] = "file_type", 322825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_friend] = "friend", 322925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_namelist] = "namelist", 323025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_namelist_item] = "namelist_item", 323125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_packed_type] = "packed_type", 323225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_subprogram] = "subprogram", 323325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_template_type_parameter] = "template_type_parameter", 323425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_template_value_parameter] = "template_value_parameter", 323525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_thrown_type] = "thrown_type", 323625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_try_block] = "try_block", 323725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_variant_part] = "variant_part", 323825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_variable] = "variable", 323925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_volatile_type] = "volatile_type", 324025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_dwarf_procedure] = "dwarf_procedure", 324125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_restrict_type] = "restrict_type", 324225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_interface_type] = "interface_type", 324325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_namespace] = "namespace", 324425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_imported_module] = "imported_module", 324525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_unspecified_type] = "unspecified_type", 324625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_partial_unit] = "partial_unit", 324725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_imported_unit] = "imported_unit", 324825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_mutable_type] = "mutable_type", 324925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_condition] = "condition", 325025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_shared_type] = "shared_type", 325125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_type_unit] = "type_unit", 325225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_rvalue_reference_type] = "rvalue_reference_type", 325325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_TAG_template_alias] = "template_alias", 325425b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 325525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned int nknown_tags = (sizeof (known_tags) 325625b3c049e70834cf33790a28643ab058b507b35cBen Cheng / sizeof (known_tags[0])); 325725b3c049e70834cf33790a28643ab058b507b35cBen Cheng static char buf[40]; 325825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *result = NULL; 325925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 326025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (tag < nknown_tags)) 326125b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = known_tags[tag]; 326225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 326325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (result == NULL)) 326425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There are a few known extensions. */ 326525b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (tag) 326625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 326725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_MIPS_loop: 326825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_loop"; 326925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 327025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 327125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_format_label: 327225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "format_label"; 327325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 327425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 327525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_function_template: 327625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "function_template"; 327725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 327825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 327925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_class_template: 328025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "class_template"; 328125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 328225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 328325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_GNU_BINCL: 328425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_BINCL"; 328525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 328625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 328725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_GNU_EINCL: 328825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_EINCL"; 328925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 329025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 329125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_GNU_template_template_param: 329225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_template_template_param"; 329325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 329425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 329525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_GNU_template_parameter_pack: 329625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_template_parameter_pack"; 329725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 329825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 329925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_GNU_formal_parameter_pack: 330025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_formal_parameter_pack"; 330125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 330225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 330325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_GNU_call_site: 330425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_call_site"; 330525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 330625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 330725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_GNU_call_site_parameter: 330825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_call_site_parameter"; 330925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 331025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 331125b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 331225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (tag < DW_TAG_lo_user) 331325b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof buf, gettext ("unknown tag %hx"), tag); 331425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 331525b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof buf, gettext ("unknown user tag %hx"), tag); 331625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = buf; 331725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 331825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 331925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 332025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 332125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 332225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 332325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 332425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 332525b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_attr_string (unsigned int attrnum) 332625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 332725b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known_attrs[] = 332825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 332925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_sibling] = "sibling", 333025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_location] = "location", 333125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_name] = "name", 333225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_ordering] = "ordering", 333325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_subscr_data] = "subscr_data", 333425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_byte_size] = "byte_size", 333525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_bit_offset] = "bit_offset", 333625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_bit_size] = "bit_size", 333725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_element_list] = "element_list", 333825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_stmt_list] = "stmt_list", 333925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_low_pc] = "low_pc", 334025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_high_pc] = "high_pc", 334125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_language] = "language", 334225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_member] = "member", 334325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_discr] = "discr", 334425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_discr_value] = "discr_value", 334525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_visibility] = "visibility", 334625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_import] = "import", 334725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_string_length] = "string_length", 334825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_common_reference] = "common_reference", 334925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_comp_dir] = "comp_dir", 335025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_const_value] = "const_value", 335125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_containing_type] = "containing_type", 335225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_default_value] = "default_value", 335325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_inline] = "inline", 335425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_is_optional] = "is_optional", 335525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_lower_bound] = "lower_bound", 335625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_producer] = "producer", 335725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_prototyped] = "prototyped", 335825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_return_addr] = "return_addr", 335925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_start_scope] = "start_scope", 336025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_bit_stride] = "bit_stride", 336125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_upper_bound] = "upper_bound", 336225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_abstract_origin] = "abstract_origin", 336325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_accessibility] = "accessibility", 336425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_address_class] = "address_class", 336525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_artificial] = "artificial", 336625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_base_types] = "base_types", 336725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_calling_convention] = "calling_convention", 336825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_count] = "count", 336925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_data_member_location] = "data_member_location", 337025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_decl_column] = "decl_column", 337125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_decl_file] = "decl_file", 337225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_decl_line] = "decl_line", 337325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_declaration] = "declaration", 337425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_discr_list] = "discr_list", 337525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_encoding] = "encoding", 337625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_external] = "external", 337725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_frame_base] = "frame_base", 337825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_friend] = "friend", 337925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_identifier_case] = "identifier_case", 338025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_macro_info] = "macro_info", 338125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_namelist_item] = "namelist_item", 338225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_priority] = "priority", 338325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_segment] = "segment", 338425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_specification] = "specification", 338525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_static_link] = "static_link", 338625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_type] = "type", 338725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_use_location] = "use_location", 338825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_variable_parameter] = "variable_parameter", 338925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_virtuality] = "virtuality", 339025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_vtable_elem_location] = "vtable_elem_location", 339125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_allocated] = "allocated", 339225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_associated] = "associated", 339325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_data_location] = "data_location", 339425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_byte_stride] = "byte_stride", 339525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_entry_pc] = "entry_pc", 339625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_use_UTF8] = "use_UTF8", 339725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_extension] = "extension", 339825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_ranges] = "ranges", 339925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_trampoline] = "trampoline", 340025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_call_column] = "call_column", 340125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_call_file] = "call_file", 340225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_call_line] = "call_line", 340325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_description] = "description", 340425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_binary_scale] = "binary_scale", 340525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_decimal_scale] = "decimal_scale", 340625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_small] = "small", 340725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_decimal_sign] = "decimal_sign", 340825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_digit_count] = "digit_count", 340925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_picture_string] = "picture_string", 341025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_mutable] = "mutable", 341125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_threads_scaled] = "threads_scaled", 341225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_explicit] = "explicit", 341325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_object_pointer] = "object_pointer", 341425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_endianity] = "endianity", 341525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_elemental] = "elemental", 341625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_pure] = "pure", 341725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_recursive] = "recursive", 341825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_signature] = "signature", 341925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_main_subprogram] = "main_subprogram", 342025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_data_bit_offset] = "data_bit_offset", 342125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_const_expr] = "const_expr", 342225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_enum_class] = "enum_class", 342325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_AT_linkage_name] = "linkage_name", 342425b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 342525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned int nknown_attrs = (sizeof (known_attrs) 342625b3c049e70834cf33790a28643ab058b507b35cBen Cheng / sizeof (known_attrs[0])); 342725b3c049e70834cf33790a28643ab058b507b35cBen Cheng static char buf[40]; 342825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *result = NULL; 342925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 343025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (attrnum < nknown_attrs)) 343125b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = known_attrs[attrnum]; 343225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 343325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (result == NULL)) 343425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There are a few known extensions. */ 343525b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (attrnum) 343625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 343725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_fde: 343825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_fde"; 343925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 344025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 344125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_loop_begin: 344225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_loop_begin"; 344325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 344425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 344525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_tail_loop_begin: 344625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_tail_loop_begin"; 344725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 344825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 344925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_epilog_begin: 345025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_epilog_begin"; 345125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 345225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 345325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_loop_unroll_factor: 345425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_loop_unroll_factor"; 345525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 345625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 345725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_software_pipeline_depth: 345825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_software_pipeline_depth"; 345925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 346025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 346125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_linkage_name: 346225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_linkage_name"; 346325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 346425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 346525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_stride: 346625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_stride"; 346725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 346825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 346925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_abstract_name: 347025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_abstract_name"; 347125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 347225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 347325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_clone_origin: 347425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_clone_origin"; 347525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 347625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 347725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_has_inlines: 347825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_has_inlines"; 347925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 348025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 348125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_stride_byte: 348225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_stride_byte"; 348325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 348425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 348525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_stride_elem: 348625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_stride_elem"; 348725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 348825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 348925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_ptr_dopetype: 349025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_ptr_dopetype"; 349125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 349225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 349325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_allocatable_dopetype: 349425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_allocatable_dopetype"; 349525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 349625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 349725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_assumed_shape_dopetype: 349825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_assumed_shape_dopetype"; 349925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 350025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 350125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_MIPS_assumed_size: 350225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "MIPS_assumed_size"; 350325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 350425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 350525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_sf_names: 350625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "sf_names"; 350725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 350825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 350925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_src_info: 351025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "src_info"; 351125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 351225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 351325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_mac_info: 351425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "mac_info"; 351525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 351625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 351725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_src_coords: 351825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "src_coords"; 351925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 352025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 352125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_body_begin: 352225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "body_begin"; 352325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 352425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 352525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_body_end: 352625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "body_end"; 352725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 352825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 352925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_vector: 353025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_vector"; 353125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 353225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 353325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_guarded_by: 353425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_guarded_by"; 353525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 353625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 353725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_pt_guarded_by: 353825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_pt_guarded_by"; 353925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 354025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 354125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_guarded: 354225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_guarded"; 354325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 354425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 354525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_pt_guarded: 354625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_pt_guarded"; 354725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 354825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 354925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_locks_excluded: 355025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_locks_excluded"; 355125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 355225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 355325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_exclusive_locks_required: 355425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_exclusive_locks_required"; 355525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 355625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 355725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_shared_locks_required: 355825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_shared_locks_required"; 355925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 356025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 356125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_odr_signature: 356225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_odr_signature"; 356325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 356425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 356525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_template_name: 356625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_template_name"; 356725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 356825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 356925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_value: 357025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_call_site_value"; 357125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 357225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 357325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_data_value: 357425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_call_site_data_value"; 357525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 357625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 357725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_target: 357825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_call_site_target"; 357925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 358025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 358125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_target_clobbered: 358225b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_call_site_target_clobbered"; 358325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 358425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 358525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_tail_call: 358625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_tail_call"; 358725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 358825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 358925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_all_tail_call_sites: 359025b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_all_tail_call_sites"; 359125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 359225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 359325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_all_call_sites: 359425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_all_call_sites"; 359525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 359625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 359725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_all_source_call_sites: 359825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = "GNU_all_source_call_sites"; 359925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 360025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 360125b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 360225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (attrnum < DW_AT_lo_user) 360325b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof buf, gettext ("unknown attribute %hx"), 360425b3c049e70834cf33790a28643ab058b507b35cBen Cheng attrnum); 360525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 360625b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof buf, gettext ("unknown user attribute %hx"), 360725b3c049e70834cf33790a28643ab058b507b35cBen Cheng attrnum); 360825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = buf; 360925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 361025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 361125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 361225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 361325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 361425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 361525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 361625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 361725b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_form_string (unsigned int form) 361825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 361925b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known_forms[] = 362025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 362125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_addr] = "addr", 362225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_block2] = "block2", 362325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_block4] = "block4", 362425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_data2] = "data2", 362525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_data4] = "data4", 362625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_data8] = "data8", 362725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_string] = "string", 362825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_block] = "block", 362925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_block1] = "block1", 363025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_data1] = "data1", 363125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_flag] = "flag", 363225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_sdata] = "sdata", 363325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_strp] = "strp", 363425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_udata] = "udata", 363525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_ref_addr] = "ref_addr", 363625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_ref1] = "ref1", 363725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_ref2] = "ref2", 363825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_ref4] = "ref4", 363925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_ref8] = "ref8", 364025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_ref_udata] = "ref_udata", 364125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_indirect] = "indirect", 364225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_sec_offset] = "sec_offset", 364325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_exprloc] = "exprloc", 364425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_flag_present] = "flag_present", 364525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_FORM_ref_sig8] = "ref_sig8", 364625b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 364725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned int nknown_forms = (sizeof (known_forms) 364825b3c049e70834cf33790a28643ab058b507b35cBen Cheng / sizeof (known_forms[0])); 364925b3c049e70834cf33790a28643ab058b507b35cBen Cheng static char buf[40]; 365025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *result = NULL; 365125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 365225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (form < nknown_forms)) 365325b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = known_forms[form]; 365425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 365525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (result == NULL)) 365625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 365725b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof buf, gettext ("unknown form %#" PRIx64), 365825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) form); 365925b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = buf; 366025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 366125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 366225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 366325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 366425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 366525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 366625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 366725b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_lang_string (unsigned int lang) 366825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 366925b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 367025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 367125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_C89] = "ISO C89", 367225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_C] = "C", 367325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Ada83] = "Ada83", 367425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_C_plus_plus] = "C++", 367525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Cobol74] = "Cobol74", 367625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Cobol85] = "Cobol85", 367725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Fortran77] = "Fortran77", 367825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Fortran90] = "Fortran90", 367925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Pascal83] = "Pascal83", 368025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Modula2] = "Modula2", 368125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Java] = "Java", 368225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_C99] = "ISO C99", 368325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Ada95] = "Ada95", 368425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Fortran95] = "Fortran95", 368525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_PL1] = "PL1", 368625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_Objc] = "Objective C", 368725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_ObjC_plus_plus] = "Objective C++", 368825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_UPC] = "UPC", 368925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_LANG_D] = "D", 369025b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 369125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 369225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (lang < sizeof (known) / sizeof (known[0]))) 369325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[lang]; 369425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (lang == DW_LANG_Mips_Assembler) 369525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This language tag is used for assembler in general. */ 369625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "Assembler"; 369725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 369825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (lang >= DW_LANG_lo_user && lang <= DW_LANG_hi_user) 369925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 370025b3c049e70834cf33790a28643ab058b507b35cBen Cheng static char buf[30]; 370125b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof (buf), "lo_user+%u", lang - DW_LANG_lo_user); 370225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return buf; 370325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 370425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 370525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 370625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 370725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 370825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 370925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 371025b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_inline_string (unsigned int code) 371125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 371225b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 371325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 371425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_INL_not_inlined] = "not_inlined", 371525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_INL_inlined] = "inlined", 371625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_INL_declared_not_inlined] = "declared_not_inlined", 371725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_INL_declared_inlined] = "declared_inlined" 371825b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 371925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 372025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 372125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 372225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 372325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 372425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 372525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 372625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 372725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 372825b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_encoding_string (unsigned int code) 372925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 373025b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 373125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 373225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_void] = "void", 373325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_address] = "address", 373425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_boolean] = "boolean", 373525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_complex_float] = "complex_float", 373625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_float] = "float", 373725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_signed] = "signed", 373825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_signed_char] = "signed_char", 373925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_unsigned] = "unsigned", 374025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_unsigned_char] = "unsigned_char", 374125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_imaginary_float] = "imaginary_float", 374225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_packed_decimal] = "packed_decimal", 374325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_numeric_string] = "numeric_string", 374425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_edited] = "edited", 374525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_signed_fixed] = "signed_fixed", 374625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_unsigned_fixed] = "unsigned_fixed", 374725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ATE_decimal_float] = "decimal_float", 374825b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 374925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 375025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 375125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 375225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 375325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user) 375425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 375525b3c049e70834cf33790a28643ab058b507b35cBen Cheng static char buf[30]; 375625b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_ATE_lo_user); 375725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return buf; 375825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 375925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 376025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 376125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 376225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 376325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 376425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 376525b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_access_string (unsigned int code) 376625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 376725b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 376825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 376925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ACCESS_public] = "public", 377025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ACCESS_protected] = "protected", 377125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ACCESS_private] = "private" 377225b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 377325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 377425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 377525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 377625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 377725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 377825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 377925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 378025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 378125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 378225b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_visibility_string (unsigned int code) 378325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 378425b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 378525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 378625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_VIS_local] = "local", 378725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_VIS_exported] = "exported", 378825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_VIS_qualified] = "qualified" 378925b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 379025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 379125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 379225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 379325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 379425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 379525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 379625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 379725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 379825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 379925b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_virtuality_string (unsigned int code) 380025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 380125b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 380225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 380325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_VIRTUALITY_none] = "none", 380425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_VIRTUALITY_virtual] = "virtual", 380525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_VIRTUALITY_pure_virtual] = "pure_virtual" 380625b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 380725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 380825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 380925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 381025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 381125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 381225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 381325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 381425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 381525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 381625b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_identifier_case_string (unsigned int code) 381725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 381825b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 381925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 382025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ID_case_sensitive] = "sensitive", 382125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ID_up_case] = "up_case", 382225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ID_down_case] = "down_case", 382325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ID_case_insensitive] = "insensitive" 382425b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 382525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 382625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 382725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 382825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 382925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 383025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 383125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 383225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 383325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 383425b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_calling_convention_string (unsigned int code) 383525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 383625b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 383725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 383825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_CC_normal] = "normal", 383925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_CC_program] = "program", 384025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_CC_nocall] = "nocall", 384125b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 384225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 384325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 384425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 384525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 384625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (code >= DW_CC_lo_user && code <= DW_CC_hi_user) 384725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 384825b3c049e70834cf33790a28643ab058b507b35cBen Cheng static char buf[30]; 384925b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_CC_lo_user); 385025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return buf; 385125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 385225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 385325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 385425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 385525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 385625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 385725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 385825b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_ordering_string (unsigned int code) 385925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 386025b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 386125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 386225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ORD_row_major] = "row_major", 386325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_ORD_col_major] = "col_major" 386425b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 386525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 386625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 386725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 386825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 386925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 387025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 387125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 387225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 387325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 387425b3c049e70834cf33790a28643ab058b507b35cBen Chengdwarf_discr_list_string (unsigned int code) 387525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 387625b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 387725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 387825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_DSC_label] = "label", 387925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_DSC_range] = "range" 388025b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 388125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 388225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 388325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return known[code]; 388425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 388525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return "???"; 388625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 388725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 388825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 388925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 389025b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_block (size_t n, const void *block) 389125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 389225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (n == 0) 389325b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (_("empty block")); 389425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 389525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 389625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (_("%zu byte block:"), n); 389725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *data = block; 389825b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 389925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %02x", *data++); 390025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (--n > 0); 390125b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar ('\n'); 390225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 390325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 390425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 390525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 390625b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, 390725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int vers, unsigned int addrsize, unsigned int offset_size, 390825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word len, const unsigned char *data) 390925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 391025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned int ref_size = vers < 3 ? addrsize : offset_size; 391125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 391225b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *const known[] = 391325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 391425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_addr] = "addr", 391525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_deref] = "deref", 391625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_const1u] = "const1u", 391725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_const1s] = "const1s", 391825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_const2u] = "const2u", 391925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_const2s] = "const2s", 392025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_const4u] = "const4u", 392125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_const4s] = "const4s", 392225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_const8u] = "const8u", 392325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_const8s] = "const8s", 392425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_constu] = "constu", 392525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_consts] = "consts", 392625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_dup] = "dup", 392725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_drop] = "drop", 392825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_over] = "over", 392925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_pick] = "pick", 393025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_swap] = "swap", 393125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_rot] = "rot", 393225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_xderef] = "xderef", 393325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_abs] = "abs", 393425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_and] = "and", 393525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_div] = "div", 393625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_minus] = "minus", 393725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_mod] = "mod", 393825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_mul] = "mul", 393925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_neg] = "neg", 394025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_not] = "not", 394125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_or] = "or", 394225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_plus] = "plus", 394325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_plus_uconst] = "plus_uconst", 394425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_shl] = "shl", 394525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_shr] = "shr", 394625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_shra] = "shra", 394725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_xor] = "xor", 394825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_bra] = "bra", 394925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_eq] = "eq", 395025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_ge] = "ge", 395125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_gt] = "gt", 395225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_le] = "le", 395325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lt] = "lt", 395425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_ne] = "ne", 395525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_skip] = "skip", 395625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit0] = "lit0", 395725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit1] = "lit1", 395825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit2] = "lit2", 395925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit3] = "lit3", 396025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit4] = "lit4", 396125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit5] = "lit5", 396225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit6] = "lit6", 396325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit7] = "lit7", 396425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit8] = "lit8", 396525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit9] = "lit9", 396625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit10] = "lit10", 396725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit11] = "lit11", 396825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit12] = "lit12", 396925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit13] = "lit13", 397025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit14] = "lit14", 397125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit15] = "lit15", 397225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit16] = "lit16", 397325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit17] = "lit17", 397425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit18] = "lit18", 397525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit19] = "lit19", 397625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit20] = "lit20", 397725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit21] = "lit21", 397825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit22] = "lit22", 397925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit23] = "lit23", 398025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit24] = "lit24", 398125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit25] = "lit25", 398225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit26] = "lit26", 398325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit27] = "lit27", 398425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit28] = "lit28", 398525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit29] = "lit29", 398625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit30] = "lit30", 398725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_lit31] = "lit31", 398825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg0] = "reg0", 398925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg1] = "reg1", 399025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg2] = "reg2", 399125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg3] = "reg3", 399225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg4] = "reg4", 399325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg5] = "reg5", 399425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg6] = "reg6", 399525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg7] = "reg7", 399625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg8] = "reg8", 399725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg9] = "reg9", 399825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg10] = "reg10", 399925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg11] = "reg11", 400025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg12] = "reg12", 400125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg13] = "reg13", 400225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg14] = "reg14", 400325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg15] = "reg15", 400425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg16] = "reg16", 400525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg17] = "reg17", 400625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg18] = "reg18", 400725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg19] = "reg19", 400825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg20] = "reg20", 400925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg21] = "reg21", 401025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg22] = "reg22", 401125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg23] = "reg23", 401225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg24] = "reg24", 401325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg25] = "reg25", 401425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg26] = "reg26", 401525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg27] = "reg27", 401625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg28] = "reg28", 401725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg29] = "reg29", 401825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg30] = "reg30", 401925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_reg31] = "reg31", 402025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg0] = "breg0", 402125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg1] = "breg1", 402225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg2] = "breg2", 402325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg3] = "breg3", 402425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg4] = "breg4", 402525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg5] = "breg5", 402625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg6] = "breg6", 402725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg7] = "breg7", 402825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg8] = "breg8", 402925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg9] = "breg9", 403025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg10] = "breg10", 403125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg11] = "breg11", 403225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg12] = "breg12", 403325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg13] = "breg13", 403425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg14] = "breg14", 403525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg15] = "breg15", 403625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg16] = "breg16", 403725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg17] = "breg17", 403825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg18] = "breg18", 403925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg19] = "breg19", 404025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg20] = "breg20", 404125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg21] = "breg21", 404225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg22] = "breg22", 404325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg23] = "breg23", 404425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg24] = "breg24", 404525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg25] = "breg25", 404625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg26] = "breg26", 404725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg27] = "breg27", 404825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg28] = "breg28", 404925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg29] = "breg29", 405025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg30] = "breg30", 405125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_breg31] = "breg31", 405225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_regx] = "regx", 405325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_fbreg] = "fbreg", 405425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_bregx] = "bregx", 405525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_piece] = "piece", 405625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_deref_size] = "deref_size", 405725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_xderef_size] = "xderef_size", 405825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_nop] = "nop", 405925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_push_object_address] = "push_object_address", 406025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_call2] = "call2", 406125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_call4] = "call4", 406225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_call_ref] = "call_ref", 406325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_form_tls_address] = "form_tls_address", 406425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_call_frame_cfa] = "call_frame_cfa", 406525b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_bit_piece] = "bit_piece", 406625b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_implicit_value] = "implicit_value", 406725b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_stack_value] = "stack_value", 406825b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_GNU_implicit_pointer] = "GNU_implicit_pointer", 406925b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_GNU_entry_value] = "GNU_entry_value", 407025b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_GNU_const_type] = "GNU_const_type", 407125b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_GNU_regval_type] = "GNU_regval_type", 407225b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_GNU_deref_type] = "GNU_deref_type", 407325b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_GNU_convert] = "GNU_convert", 407425b3c049e70834cf33790a28643ab058b507b35cBen Cheng [DW_OP_GNU_reinterpret] = "GNU_reinterpret", 407525b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 407625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 407725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (len == 0) 407825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 407925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s(empty)\n", indent, ""); 408025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 408125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 408225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 408325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid 408425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define CONSUME(n) NEED (n); else len -= (n) 408525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 408625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word offset = 0; 408725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (len-- > 0) 408825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 408925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t op = *data++; 409025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 409125b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (op) 409225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 409325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_addr:; 409425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Address operand. */ 409525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word addr; 409625b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (addrsize); 409725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (addrsize == 4) 409825b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = read_4ubyte_unaligned (dbg, data); 409925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 410025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 410125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (addrsize == 8); 410225b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = read_8ubyte_unaligned (dbg, data); 410325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 410425b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += addrsize; 410525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (addrsize); 410625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 410725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *a = format_dwarf_addr (dwflmod, 0, addr); 410825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %s\n", 410925b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], a); 411025b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (a); 411125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 411225b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + addrsize; 411325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 411425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 411525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_call_ref: 411625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Offset operand. */ 411725b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (ref_size); 411825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ref_size == 4) 411925b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = read_4ubyte_unaligned (dbg, data); 412025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 412125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 412225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ref_size == 8); 412325b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = read_8ubyte_unaligned (dbg, data); 412425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 412525b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += ref_size; 412625b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (ref_size); 412725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 412825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n", 412925b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 413025b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], (uintmax_t) addr); 413125b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + ref_size; 413225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 413325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 413425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_deref_size: 413525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_xderef_size: 413625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_pick: 413725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_const1u: 413825b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX value might be modified by relocation 413925b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (1); 414025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n", 414125b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 414225b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], *((uint8_t *) data)); 414325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++data; 414425b3c049e70834cf33790a28643ab058b507b35cBen Cheng --len; 414525b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 2; 414625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 414725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 414825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_const2u: 414925b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 415025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX value might be modified by relocation 415125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", 415225b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 415325b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], read_2ubyte_unaligned (dbg, data)); 415425b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (2); 415525b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += 2; 415625b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 3; 415725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 415825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 415925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_const4u: 416025b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (4); 416125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX value might be modified by relocation 416225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", 416325b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 416425b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], read_4ubyte_unaligned (dbg, data)); 416525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (4); 416625b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += 4; 416725b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 5; 416825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 416925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 417025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_const8u: 417125b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (8); 417225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX value might be modified by relocation 417325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", 417425b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 417525b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], read_8ubyte_unaligned (dbg, data)); 417625b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (8); 417725b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += 8; 417825b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 9; 417925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 418025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 418125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_const1s: 418225b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (1); 418325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX value might be modified by relocation 418425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n", 418525b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 418625b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], *((int8_t *) data)); 418725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++data; 418825b3c049e70834cf33790a28643ab058b507b35cBen Cheng --len; 418925b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 2; 419025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 419125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 419225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_const2s: 419325b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 419425b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX value might be modified by relocation 419525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n", 419625b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 419725b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], read_2sbyte_unaligned (dbg, data)); 419825b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (2); 419925b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += 2; 420025b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 3; 420125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 420225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 420325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_const4s: 420425b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (4); 420525b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX value might be modified by relocation 420625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n", 420725b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 420825b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], read_4sbyte_unaligned (dbg, data)); 420925b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (4); 421025b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += 4; 421125b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 5; 421225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 421325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 421425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_const8s: 421525b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (8); 421625b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX value might be modified by relocation 421725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", 421825b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 421925b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], read_8sbyte_unaligned (dbg, data)); 422025b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (8); 422125b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += 8; 422225b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 9; 422325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 422425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 422525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_piece: 422625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_regx: 422725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_plus_uconst: 422825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_constu:; 422925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *start = data; 423025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t uleb; 423125b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (1); 423225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 423325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", 423425b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], uleb); 423525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 423625b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 423725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 423825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 423925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_bit_piece: 424025b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 424125b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t uleb2; 424225b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 424325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 424425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb2, data); /* XXX check overrun */ 424525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n", 424625b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], uleb, uleb2); 424725b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 424825b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 424925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 425025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 425125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_fbreg: 425225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_breg0 ... DW_OP_breg31: 425325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_consts: 425425b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 425525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int64_t sleb; 425625b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (1); 425725b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (sleb, data); /* XXX check overrun */ 425825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", 425925b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], sleb); 426025b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 426125b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 426225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 426325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 426425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_bregx: 426525b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 426625b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 426725b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 426825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (sleb, data); /* XXX check overrun */ 426925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n", 427025b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], uleb, sleb); 427125b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 427225b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 427325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 427425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 427525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_call2: 427625b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 427725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", 427825b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], 427925b3c049e70834cf33790a28643ab058b507b35cBen Cheng read_2ubyte_unaligned (dbg, data)); 428025b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (2); 428125b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 3; 428225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 428325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 428425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_call4: 428525b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (4); 428625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", 428725b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], 428825b3c049e70834cf33790a28643ab058b507b35cBen Cheng read_4ubyte_unaligned (dbg, data)); 428925b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (4); 429025b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 5; 429125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 429225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 429325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_skip: 429425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_bra: 429525b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 429625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n", 429725b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], 429825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data))); 429925b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (2); 430025b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += 2; 430125b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 3; 430225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 430325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 430425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_implicit_value: 430525b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 430625b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (1); 430725b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 430825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s: ", 430925b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op]); 431025b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (uleb); 431125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_block (uleb, data); 431225b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += uleb; 431325b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 431425b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 431525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 431625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 431725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_GNU_implicit_pointer: 431825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* DIE offset operand. */ 431925b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 432025b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (ref_size + 1); 432125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ref_size == 4) 432225b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = read_4ubyte_unaligned (dbg, data); 432325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 432425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 432525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ref_size == 8); 432625b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = read_8ubyte_unaligned (dbg, data); 432725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 432825b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += ref_size; 432925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Byte offset operand. */ 433025b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (sleb, data); /* XXX check overrun */ 433125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 433225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX ", %+" PRId64 "\n", 433325b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (intmax_t) offset, 433425b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], (uintmax_t) addr, sleb); 433525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 433625b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 433725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 433825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 433925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_GNU_entry_value: 434025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Size plus expression block. */ 434125b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 434225b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (1); 434325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 434425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s:\n", 434525b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op]); 434625b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (uleb); 434725b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_ops (dwflmod, dbg, indent + 6, indent + 6, vers, 434825b3c049e70834cf33790a28643ab058b507b35cBen Cheng addrsize, offset_size, uleb, data); 434925b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += uleb; 435025b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 435125b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 435225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 435325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 435425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_GNU_const_type: 435525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* DIE offset, size plus block. */ 435625b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 435725b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 435825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 435925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint8_t usize = *(uint8_t *) data++; 436025b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (usize); 436125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ", 436225b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], uleb); 436325b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_block (usize, data); 436425b3c049e70834cf33790a28643ab058b507b35cBen Cheng data += usize; 436525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 436625b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 436725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 436825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 436925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_GNU_regval_type: 437025b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 437125b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 437225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 437325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb2, data); /* XXX check overrun */ 437425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %#" PRIx64 "\n", 437525b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], uleb, uleb2); 437625b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 437725b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 437825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 437925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 438025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_GNU_deref_type: 438125b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 438225b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (2); 438325b3c049e70834cf33790a28643ab058b507b35cBen Cheng usize = *(uint8_t *) data++; 438425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 438525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n", 438625b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, 438725b3c049e70834cf33790a28643ab058b507b35cBen Cheng known[op], usize, uleb); 438825b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 438925b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 439025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 439125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 439225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_GNU_convert: 439325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_OP_GNU_reinterpret: 439425b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = data; 439525b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEED (1); 439625b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (uleb, data); /* XXX check overrun */ 439725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n", 439825b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op], uleb); 439925b3c049e70834cf33790a28643ab058b507b35cBen Cheng CONSUME (data - start); 440025b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += 1 + (data - start); 440125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 440225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 440325b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 440425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No Operand. */ 440525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (op < sizeof known / sizeof known[0] && known[op] != NULL) 440625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %s\n", 440725b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op]); 440825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 440925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s[%4" PRIuMAX "] %#x\n", 441025b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, op); 441125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++offset; 441225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 441325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 441425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 441525b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent = indentrest; 441625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 441725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 441825b3c049e70834cf33790a28643ab058b507b35cBen Cheng invalid: 441925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"), 442025b3c049e70834cf33790a28643ab058b507b35cBen Cheng indent, "", (uintmax_t) offset, known[op]); 442125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 442225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 442325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 442425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 442525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 442625b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct listptr 442725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 442825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off offset:(64 - 3); 442925b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool addr64:1; 443025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool dwarf64:1; 443125b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool warned:1; 443225b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 443325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 443425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4) 443525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define listptr_address_size(p) ((p)->addr64 ? 8 : 4) 443625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 443725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 443825b3c049e70834cf33790a28643ab058b507b35cBen Chengcompare_listptr (const void *a, const void *b, void *arg) 443925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 444025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = arg; 444125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct listptr *p1 = (void *) a; 444225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct listptr *p2 = (void *) b; 444325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 444425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (p1->offset < p2->offset) 444525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return -1; 444625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (p1->offset > p2->offset) 444725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 444825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 444925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!p1->warned && !p2->warned) 445025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 445125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (p1->addr64 != p2->addr64) 445225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 445325b3c049e70834cf33790a28643ab058b507b35cBen Cheng p1->warned = p2->warned = true; 445425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, 445525b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s %#" PRIx64 " used with different address sizes"), 445625b3c049e70834cf33790a28643ab058b507b35cBen Cheng name, (uint64_t) p1->offset); 445725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 445825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (p1->dwarf64 != p2->dwarf64) 445925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 446025b3c049e70834cf33790a28643ab058b507b35cBen Cheng p1->warned = p2->warned = true; 446125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, 446225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s %#" PRIx64 " used with different offset sizes"), 446325b3c049e70834cf33790a28643ab058b507b35cBen Cheng name, (uint64_t) p1->offset); 446425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 446525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 446625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 446725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 446825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 446925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 447025b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct listptr_table 447125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 447225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t n; 447325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t alloc; 447425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct listptr *table; 447525b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 447625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 447725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct listptr_table known_loclistptr; 447825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct listptr_table known_rangelistptr; 447925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 448025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 448125b3c049e70834cf33790a28643ab058b507b35cBen Chengreset_listptr (struct listptr_table *table) 448225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 448325b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (table->table); 448425b3c049e70834cf33790a28643ab058b507b35cBen Cheng table->table = NULL; 448525b3c049e70834cf33790a28643ab058b507b35cBen Cheng table->n = table->alloc = 0; 448625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 448725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 448825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 448925b3c049e70834cf33790a28643ab058b507b35cBen Chengnotice_listptr (enum section_e section, struct listptr_table *table, 449025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t address_size, uint_fast8_t offset_size, 449125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off offset) 449225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 449325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (print_debug_sections & section) 449425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 449525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (table->n == table->alloc) 449625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 449725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (table->alloc == 0) 449825b3c049e70834cf33790a28643ab058b507b35cBen Cheng table->alloc = 128; 449925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 450025b3c049e70834cf33790a28643ab058b507b35cBen Cheng table->alloc *= 2; 450125b3c049e70834cf33790a28643ab058b507b35cBen Cheng table->table = xrealloc (table->table, 450225b3c049e70834cf33790a28643ab058b507b35cBen Cheng table->alloc * sizeof table->table[0]); 450325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 450425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 450525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct listptr *p = &table->table[table->n++]; 450625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 450725b3c049e70834cf33790a28643ab058b507b35cBen Cheng *p = (struct listptr) 450825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 450925b3c049e70834cf33790a28643ab058b507b35cBen Cheng .addr64 = address_size == 8, 451025b3c049e70834cf33790a28643ab058b507b35cBen Cheng .dwarf64 = offset_size == 8, 451125b3c049e70834cf33790a28643ab058b507b35cBen Cheng .offset = offset 451225b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 451325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (p->offset == offset); 451425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 451525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 451625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 451725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 451825b3c049e70834cf33790a28643ab058b507b35cBen Chengsort_listptr (struct listptr_table *table, const char *name) 451925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 452025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (table->n > 0) 452125b3c049e70834cf33790a28643ab058b507b35cBen Cheng qsort_r (table->table, table->n, sizeof table->table[0], 452225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &compare_listptr, (void *) name); 452325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 452425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 452525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool 452625b3c049e70834cf33790a28643ab058b507b35cBen Chengskip_listptr_hole (struct listptr_table *table, size_t *idxp, 452725b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep, 452825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptrdiff_t offset, unsigned char **readp, unsigned char *endp) 452925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 453025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (table->n == 0) 453125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 453225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 453325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset) 453425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++*idxp; 453525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 453625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct listptr *p = &table->table[*idxp]; 453725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 453825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (*idxp == table->n 453925b3c049e70834cf33790a28643ab058b507b35cBen Cheng || p->offset >= (Dwarf_Off) (endp - *readp + offset)) 454025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 454125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *readp = endp; 454225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"), 454325b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset); 454425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return true; 454525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 454625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 454725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (p->offset != (Dwarf_Off) offset) 454825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 454925b3c049e70834cf33790a28643ab058b507b35cBen Cheng *readp += p->offset - offset; 455025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"), 455125b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset, (Dwarf_Off) p->offset - offset); 455225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return true; 455325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 455425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 455525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (address_sizep != NULL) 455625b3c049e70834cf33790a28643ab058b507b35cBen Cheng *address_sizep = listptr_address_size (p); 455725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (offset_sizep != NULL) 455825b3c049e70834cf33790a28643ab058b507b35cBen Cheng *offset_sizep = listptr_offset_size (p); 455925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 456025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 456125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 456225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 456325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 456425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 456525b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 456625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl, GElf_Ehdr *ehdr, 456725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 456825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 456925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n" 457025b3c049e70834cf33790a28643ab058b507b35cBen Cheng " [ Code]\n"), 457125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 457225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset); 457325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 457425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off offset = 0; 457525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (offset < dbg->sectiondata[IDX_debug_abbrev]->d_size) 457625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 457725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"), 457825b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset); 457925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 458025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (1) 458125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 458225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t length; 458325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Abbrev abbrev; 458425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 458525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int res = dwarf_offabbrev (dbg, offset, &length, &abbrev); 458625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (res != 0) 458725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 458825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (res < 0)) 458925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 459025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 459125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *** error while reading abbreviation: %s\n"), 459225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 459325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 459425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 459525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 459625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is the NUL byte at the end of the section. */ 459725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++offset; 459825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 459925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 460025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 460125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We know these calls can never fail. */ 460225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int code = dwarf_getabbrevcode (&abbrev); 460325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int tag = dwarf_getabbrevtag (&abbrev); 460425b3c049e70834cf33790a28643ab058b507b35cBen Cheng int has_children = dwarf_abbrevhaschildren (&abbrev); 460525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 460625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%5u] offset: %" PRId64 460725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", children: %s, tag: %s\n"), 460825b3c049e70834cf33790a28643ab058b507b35cBen Cheng code, (int64_t) offset, 460925b3c049e70834cf33790a28643ab058b507b35cBen Cheng has_children ? gettext ("yes") : gettext ("no"), 461025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_tag_string (tag)); 461125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 461225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt = 0; 461325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int name; 461425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int form; 461525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off enoffset; 461625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (dwarf_getabbrevattr (&abbrev, cnt, 461725b3c049e70834cf33790a28643ab058b507b35cBen Cheng &name, &form, &enoffset) == 0) 461825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 461925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n", 462025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_attr_string (name), dwarf_form_string (form), 462125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) enoffset); 462225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 462325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++cnt; 462425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 462525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 462625b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += length; 462725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 462825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 462925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 463025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 463125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 463225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print content of DWARF .debug_aranges section. We fortunately do 463325b3c049e70834cf33790a28643ab058b507b35cBen Cheng not have to know a bit about the structure of the section, libdwarf 463425b3c049e70834cf33790a28643ab058b507b35cBen Cheng takes care of it. */ 463525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 463625b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 463725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 463825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr, Dwarf *dbg) 463925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 464025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Aranges *aranges; 464125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 464225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0)) 464325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 464425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get .debug_aranges content: %s"), 464525b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 464625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 464725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 464825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 464925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext ("\ 465025b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n", 465125b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\ 465225b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n", 465325b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt), 465425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 465525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset, cnt); 465625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 465725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute floor(log16(cnt)). */ 465825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t tmp = cnt; 465925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int digits = 1; 466025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (tmp >= 16) 466125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 466225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++digits; 466325b3c049e70834cf33790a28643ab058b507b35cBen Cheng tmp >>= 4; 466425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 466525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 466625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t n = 0; n < cnt; ++n) 466725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 466825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Arange *runp = dwarf_onearange (aranges, n); 466925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (runp == NULL)) 467025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 467125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1)); 467225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 467325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 467425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 467525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr start; 467625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word length; 467725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off offset; 467825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 467925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0)) 468025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%*zu] ???\n"), digits, n); 468125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 468225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%*zu] start: %0#*" PRIx64 468325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", length: %5" PRIu64 ", CU DIE offset: %6" 468425b3c049e70834cf33790a28643ab058b507b35cBen Cheng PRId64 "\n"), 468525b3c049e70834cf33790a28643ab058b507b35cBen Cheng digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18, 468625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) start, (uint64_t) length, (int64_t) offset); 468725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 468825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 468925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 469025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print content of DWARF .debug_ranges section. */ 469125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 469225b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_ranges_section (Dwfl_Module *dwflmod, 469325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl, GElf_Ehdr *ehdr, 469425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, 469525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf *dbg) 469625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 469725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 469825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 469925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 470025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 470125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get .debug_ranges content: %s"), 470225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 470325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 470425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 470525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 470625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 470725b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 470825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 470925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset); 471025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 471125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sort_listptr (&known_rangelistptr, "rangelistptr"); 471225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t listptr_idx = 0; 471325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 471425b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 471525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 471625b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool first = true; 471725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size; 471825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *readp = data->d_buf; 471925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp < endp) 472025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 472125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptrdiff_t offset = readp - (unsigned char *) data->d_buf; 472225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 472325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx, 472425b3c049e70834cf33790a28643ab058b507b35cBen Cheng &address_size, NULL, 472525b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset, &readp, endp)) 472625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 472725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 472825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data->d_size - offset < address_size * 2)) 472925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 473025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] <INVALID DATA>\n"), offset); 473125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 473225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 473325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 473425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr begin; 473525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr end; 473625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (address_size == 8) 473725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 473825b3c049e70834cf33790a28643ab058b507b35cBen Cheng begin = read_8ubyte_unaligned_inc (dbg, readp); 473925b3c049e70834cf33790a28643ab058b507b35cBen Cheng end = read_8ubyte_unaligned_inc (dbg, readp); 474025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 474125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 474225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 474325b3c049e70834cf33790a28643ab058b507b35cBen Cheng begin = read_4ubyte_unaligned_inc (dbg, readp); 474425b3c049e70834cf33790a28643ab058b507b35cBen Cheng end = read_4ubyte_unaligned_inc (dbg, readp); 474525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (begin == (Dwarf_Addr) (uint32_t) -1) 474625b3c049e70834cf33790a28643ab058b507b35cBen Cheng begin = (Dwarf_Addr) -1l; 474725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 474825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 474925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ 475025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 475125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *b = format_dwarf_addr (dwflmod, address_size, end); 475225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] base address %s\n"), offset, b); 475325b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (b); 475425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 475525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (begin == 0 && end == 0) /* End of list entry. */ 475625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 475725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first) 475825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] empty list\n"), offset); 475925b3c049e70834cf33790a28643ab058b507b35cBen Cheng first = true; 476025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 476125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 476225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 476325b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *b = format_dwarf_addr (dwflmod, address_size, begin); 476425b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *e = format_dwarf_addr (dwflmod, address_size, end); 476525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have an address range entry. */ 476625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first) /* First address range entry in a list. */ 476725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] %s..%s\n"), offset, b, e); 476825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 476925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %s..%s\n"), b, e); 477025b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (b); 477125b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (e); 477225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 477325b3c049e70834cf33790a28643ab058b507b35cBen Cheng first = false; 477425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 477525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 477625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 477725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 477825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define REGNAMESZ 16 477925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char * 478025b3c049e70834cf33790a28643ab058b507b35cBen Chengregister_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc, 478125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char name[REGNAMESZ], int *bits, int *type) 478225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 478325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *set; 478425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *pfx; 478525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int ignore; 478625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set, 478725b3c049e70834cf33790a28643ab058b507b35cBen Cheng bits ?: &ignore, type ?: &ignore); 478825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (n <= 0) 478925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 479025b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (name, REGNAMESZ, "reg%u", loc->regno); 479125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (bits != NULL) 479225b3c049e70834cf33790a28643ab058b507b35cBen Cheng *bits = loc->bits; 479325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (type != NULL) 479425b3c049e70834cf33790a28643ab058b507b35cBen Cheng *type = DW_ATE_unsigned; 479525b3c049e70834cf33790a28643ab058b507b35cBen Cheng set = "??? unrecognized"; 479625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 479725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 479825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 479925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (bits != NULL && *bits <= 0) 480025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *bits = loc->bits; 480125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (type != NULL && *type == DW_ATE_void) 480225b3c049e70834cf33790a28643ab058b507b35cBen Cheng *type = DW_ATE_unsigned; 480325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 480425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 480525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return set; 480625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 480725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 480825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 480925b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_cfa_program (const unsigned char *readp, const unsigned char *const endp, 481025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word vma_base, unsigned int code_align, 481125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int data_align, 481225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int version, unsigned int ptr_size, 481325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg) 481425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 481525b3c049e70834cf33790a28643ab058b507b35cBen Cheng char regnamebuf[REGNAMESZ]; 481625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *regname (unsigned int regno) 481725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 481825b3c049e70834cf33790a28643ab058b507b35cBen Cheng register_info (ebl, regno, NULL, regnamebuf, NULL, NULL); 481925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return regnamebuf; 482025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 482125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 482225b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts ("\n Program:"); 482325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word pc = vma_base; 482425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp < endp) 482525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 482625b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int opcode = *readp++; 482725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 482825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (opcode < DW_CFA_advance_loc) 482925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Extended opcode. */ 483025b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (opcode) 483125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 483225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t op1; 483325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int64_t sop1; 483425b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t op2; 483525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int64_t sop2; 483625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 483725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_nop: 483825b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (" nop"); 483925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 484025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_set_loc: 484125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 484225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 484325b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1 += vma_base; 484425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" set_loc %" PRIu64 "\n", op1 * code_align); 484525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 484625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_advance_loc1: 484725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" advance_loc1 %u to %#" PRIx64 "\n", 484825b3c049e70834cf33790a28643ab058b507b35cBen Cheng *readp, pc += *readp * code_align); 484925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++readp; 485025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 485125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_advance_loc2: 485225b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1 = read_2ubyte_unaligned_inc (dbg, readp); 485325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n", 485425b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, pc += op1 * code_align); 485525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 485625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_advance_loc4: 485725b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1 = read_4ubyte_unaligned_inc (dbg, readp); 485825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n", 485925b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, pc += op1 * code_align); 486025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 486125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_offset_extended: 486225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 486325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 486425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op2, readp); 486525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64 486625b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\n", 486725b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1), op2 * data_align); 486825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 486925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_restore_extended: 487025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 487125b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 487225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" restore_extended r%" PRIu64 " (%s)\n", 487325b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1)); 487425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 487525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_undefined: 487625b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 487725b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 487825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1)); 487925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 488025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_same_value: 488125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 488225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 488325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1)); 488425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 488525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_register: 488625b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 488725b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 488825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op2, readp); 488925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n", 489025b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1), op2, regname (op2)); 489125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 489225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_remember_state: 489325b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (" remember_state"); 489425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 489525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_restore_state: 489625b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (" restore_state"); 489725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 489825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_def_cfa: 489925b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 490025b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 490125b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op2, readp); 490225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n", 490325b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1), op2); 490425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 490525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_def_cfa_register: 490625b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 490725b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 490825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" def_cfa_register r%" PRIu64 " (%s)\n", 490925b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1)); 491025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 491125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_def_cfa_offset: 491225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 491325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 491425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" def_cfa_offset %" PRIu64 "\n", op1); 491525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 491625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_def_cfa_expression: 491725b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 491825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); /* Length of DW_FORM_block. */ 491925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" def_cfa_expression %" PRIu64 "\n", op1); 492025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op1, readp); 492125b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += op1; 492225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 492325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_expression: 492425b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 492525b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 492625b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op2, readp); /* Length of DW_FORM_block. */ 492725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" expression r%" PRIu64 " (%s) \n", 492825b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1)); 492925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op2, readp); 493025b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += op2; 493125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 493225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_offset_extended_sf: 493325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 493425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 493525b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (sop2, readp); 493625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+" 493725b3c049e70834cf33790a28643ab058b507b35cBen Cheng PRId64 "\n", 493825b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1), sop2 * data_align); 493925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 494025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_def_cfa_sf: 494125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 494225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 494325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (sop2, readp); 494425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n", 494525b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1), sop2 * data_align); 494625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 494725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_def_cfa_offset_sf: 494825b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 494925b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (sop1, readp); 495025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align); 495125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 495225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_val_offset: 495325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 495425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 495525b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op2, readp); 495625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n", 495725b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, op2 * data_align); 495825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 495925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_val_offset_sf: 496025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 496125b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 496225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (sop2, readp); 496325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n", 496425b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, sop2 * data_align); 496525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 496625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_val_expression: 496725b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 496825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 496925b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op2, readp); /* Length of DW_FORM_block. */ 497025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" val_expression r%" PRIu64 " (%s)\n", 497125b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, regname (op1)); 497225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op2, readp); 497325b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += op2; 497425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 497525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_MIPS_advance_loc8: 497625b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1 = read_8ubyte_unaligned_inc (dbg, readp); 497725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n", 497825b3c049e70834cf33790a28643ab058b507b35cBen Cheng op1, pc += op1 * code_align); 497925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 498025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_GNU_window_save: 498125b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (" GNU_window_save"); 498225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 498325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_CFA_GNU_args_size: 498425b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 498525b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (op1, readp); 498625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" args_size %" PRIu64 "\n", op1); 498725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 498825b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 498925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" ??? (%u)\n", opcode); 499025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 499125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 499225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (opcode < DW_CFA_offset) 499325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" advance_loc %u to %#" PRIx64 "\n", 499425b3c049e70834cf33790a28643ab058b507b35cBen Cheng opcode & 0x3f, pc += (opcode & 0x3f) * code_align); 499525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (opcode < DW_CFA_restore) 499625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 499725b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t offset; 499825b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX overflow check 499925b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (offset, readp); 500025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" offset r%u (%s) at cfa%+" PRId64 "\n", 500125b3c049e70834cf33790a28643ab058b507b35cBen Cheng opcode & 0x3f, regname (opcode & 0x3f), offset * data_align); 500225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 500325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 500425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" restore r%u (%s)\n", 500525b3c049e70834cf33790a28643ab058b507b35cBen Cheng opcode & 0x3f, regname (opcode & 0x3f)); 500625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 500725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 500825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 500925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 501025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 501125b3c049e70834cf33790a28643ab058b507b35cBen Chengencoded_ptr_size (int encoding, unsigned int ptr_size) 501225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 501325b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (encoding & 7) 501425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 501525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 2: 501625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 2; 501725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 3: 501825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 4; 501925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 4: 502025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 8; 502125b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 502225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ptr_size; 502325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 502425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 502525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 502625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 502725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 502825b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_encoding (unsigned int val) 502925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 503025b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (val & 0xf) 503125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 503225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_absptr: 503325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("absptr", stdout); 503425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 503525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_uleb128: 503625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("uleb128", stdout); 503725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 503825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata2: 503925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("udata2", stdout); 504025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 504125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata4: 504225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("udata4", stdout); 504325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 504425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata8: 504525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("udata8", stdout); 504625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 504725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sleb128: 504825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("sleb128", stdout); 504925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 505025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata2: 505125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("sdata2", stdout); 505225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 505325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata4: 505425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("sdata4", stdout); 505525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 505625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata8: 505725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("sdata8", stdout); 505825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 505925b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 506025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We did not use any of the bits after all. */ 506125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return val; 506225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 506325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 506425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return val & ~0xf; 506525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 506625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 506725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 506825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 506925b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_relinfo (unsigned int val) 507025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 507125b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (val & 0x70) 507225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 507325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_pcrel: 507425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("pcrel", stdout); 507525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 507625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_textrel: 507725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("textrel", stdout); 507825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 507925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_datarel: 508025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("datarel", stdout); 508125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 508225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_funcrel: 508325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("funcrel", stdout); 508425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 508525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_aligned: 508625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs ("aligned", stdout); 508725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 508825b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 508925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return val; 509025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 509125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 509225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return val & ~0x70; 509325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 509425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 509525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 509625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 509725b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_encoding_base (const char *pfx, unsigned int fde_encoding) 509825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 509925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("(%s", pfx); 510025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 510125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fde_encoding == DW_EH_PE_omit) 510225b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts ("omit)"); 510325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 510425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 510525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int w = fde_encoding; 510625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 510725b3c049e70834cf33790a28643ab058b507b35cBen Cheng w = print_encoding (w); 510825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 510925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (w & 0x70) 511025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 511125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (w != fde_encoding) 511225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked (' ', stdout); 511325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 511425b3c049e70834cf33790a28643ab058b507b35cBen Cheng w = print_relinfo (w); 511525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 511625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 511725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (w != 0) 511825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%s%x", w != fde_encoding ? " " : "", w); 511925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 512025b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (")"); 512125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 512225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 512325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 512425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 512525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const unsigned char * 512625b3c049e70834cf33790a28643ab058b507b35cBen Chengread_encoded (unsigned int encoding, const unsigned char *readp, 512725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const endp, uint64_t *res, Dwarf *dbg) 512825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 512925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((encoding & 0xf) == DW_EH_PE_absptr) 513025b3c049e70834cf33790a28643ab058b507b35cBen Cheng encoding = gelf_getclass (dbg->elf) == ELFCLASS32 513125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? DW_EH_PE_udata4 : DW_EH_PE_udata8; 513225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 513325b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (encoding & 0xf) 513425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 513525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_uleb128: 513625b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX buffer overrun check 513725b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (*res, readp); 513825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 513925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sleb128: 514025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX buffer overrun check 514125b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (*res, readp); 514225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 514325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata2: 514425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (readp + 2 > endp) 514525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid; 514625b3c049e70834cf33790a28643ab058b507b35cBen Cheng *res = read_2ubyte_unaligned_inc (dbg, readp); 514725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 514825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata4: 514925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (readp + 4 > endp) 515025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid; 515125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *res = read_4ubyte_unaligned_inc (dbg, readp); 515225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 515325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata8: 515425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (readp + 8 > endp) 515525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid; 515625b3c049e70834cf33790a28643ab058b507b35cBen Cheng *res = read_8ubyte_unaligned_inc (dbg, readp); 515725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 515825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata2: 515925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (readp + 2 > endp) 516025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid; 516125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *res = read_2sbyte_unaligned_inc (dbg, readp); 516225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 516325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata4: 516425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (readp + 4 > endp) 516525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid; 516625b3c049e70834cf33790a28643ab058b507b35cBen Cheng *res = read_4sbyte_unaligned_inc (dbg, readp); 516725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 516825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata8: 516925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (readp + 8 > endp) 517025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid; 517125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *res = read_8sbyte_unaligned_inc (dbg, readp); 517225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 517325b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 517425b3c049e70834cf33790a28643ab058b507b35cBen Cheng invalid: 517525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (1, 0, 517625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("invalid encoding")); 517725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 517825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 517925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return readp; 518025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 518125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 518225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 518325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 518425b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 518525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 518625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 518725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 518825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We know this call will succeed since it did in the caller. */ 518925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) elf_getshdrstrndx (ebl->elf, &shstrndx); 519025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 519125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 519225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 519325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 519425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 519525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 519625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get %s content: %s"), 519725b3c049e70834cf33790a28643ab058b507b35cBen Cheng scnname, elf_errmsg (-1)); 519825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 519925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 520025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0; 520125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 520225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (is_eh_frame) 520325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 520425b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 520525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset); 520625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 520725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 520825b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 520925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset); 521025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 521125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct cieinfo 521225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 521325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptrdiff_t cie_offset; 521425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *augmentation; 521525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int code_alignment_factor; 521625b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int data_alignment_factor; 521725b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint8_t address_size; 521825b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint8_t fde_encoding; 521925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint8_t lsda_encoding; 522025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct cieinfo *next; 522125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } *cies = NULL; 522225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 522325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *readp = data->d_buf; 522425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const dataend = ((unsigned char *) data->d_buf 522525b3c049e70834cf33790a28643ab058b507b35cBen Cheng + data->d_size); 522625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp < dataend) 522725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 522825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 4 > dataend)) 522925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 523025b3c049e70834cf33790a28643ab058b507b35cBen Cheng invalid_data: 523125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("invalid data in section [%zu] '%s'"), 523225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), scnname); 523325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 523425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 523525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 523625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* At the beginning there must be a CIE. There can be multiple, 523725b3c049e70834cf33790a28643ab058b507b35cBen Cheng hence we test tis in a loop. */ 523825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptrdiff_t offset = readp - (unsigned char *) data->d_buf; 523925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 524025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp); 524125b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int length = 4; 524225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (unit_length == 0xffffffff)) 524325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 524425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 8 > dataend)) 524525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 524625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 524725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unit_length = read_8ubyte_unaligned_inc (dbg, readp); 524825b3c049e70834cf33790a28643ab058b507b35cBen Cheng length = 8; 524925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 525025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 525125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (unit_length == 0)) 525225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 525325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\n [%6tx] Zero terminator\n"), offset); 525425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 525525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 525625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 525725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 525825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 525925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptrdiff_t start = readp - (unsigned char *) data->d_buf; 526025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const cieend = readp + unit_length; 526125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (cieend > dataend || readp + 8 > dataend)) 526225b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 526325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 526425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off cie_id; 526525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (length == 4) 526625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 526725b3c049e70834cf33790a28643ab058b507b35cBen Cheng cie_id = read_4ubyte_unaligned_inc (dbg, readp); 526825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!is_eh_frame && cie_id == DW_CIE_ID_32) 526925b3c049e70834cf33790a28643ab058b507b35cBen Cheng cie_id = DW_CIE_ID_64; 527025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 527125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 527225b3c049e70834cf33790a28643ab058b507b35cBen Cheng cie_id = read_8ubyte_unaligned_inc (dbg, readp); 527325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 527425b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t version = 2; 527525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int code_alignment_factor; 527625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int data_alignment_factor; 527725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int fde_encoding = 0; 527825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int lsda_encoding = 0; 527925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word initial_location = 0; 528025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word vma_base = 0; 528125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 528225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64)) 528325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 528425b3c049e70834cf33790a28643ab058b507b35cBen Cheng version = *readp++; 528525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *const augmentation = (const char *) readp; 528625b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = memchr (readp, '\0', cieend - readp); 528725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp == NULL)) 528825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 528925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++readp; 529025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 529125b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t segment_size = 0; 529225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (version >= 4) 529325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 529425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cieend - readp < 5) 529525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 529625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptr_size = *readp++; 529725b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment_size = *readp++; 529825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 529925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 530025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Check overflow 530125b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (code_alignment_factor, readp); 530225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Check overflow 530325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (data_alignment_factor, readp); 530425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 530525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* In some variant for unwind data there is another field. */ 530625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (augmentation, "eh") == 0) 530725b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 530825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 530925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int return_address_register; 531025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (version == 1)) 531125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return_address_register = *readp++; 531225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 531325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Check overflow 531425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (return_address_register, readp); 531525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 531625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\n [%6tx] CIE length=%" PRIu64 "\n" 531725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " CIE_id: %" PRIu64 "\n" 531825b3c049e70834cf33790a28643ab058b507b35cBen Cheng " version: %u\n" 531925b3c049e70834cf33790a28643ab058b507b35cBen Cheng " augmentation: \"%s\"\n", 532025b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset, (uint64_t) unit_length, (uint64_t) cie_id, 532125b3c049e70834cf33790a28643ab058b507b35cBen Cheng version, augmentation); 532225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (version >= 4) 532325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" address_size: %u\n" 532425b3c049e70834cf33790a28643ab058b507b35cBen Cheng " segment_size: %u\n", 532525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptr_size, segment_size); 532625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" code_alignment_factor: %u\n" 532725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " data_alignment_factor: %d\n" 532825b3c049e70834cf33790a28643ab058b507b35cBen Cheng " return_address_register: %u\n", 532925b3c049e70834cf33790a28643ab058b507b35cBen Cheng code_alignment_factor, 533025b3c049e70834cf33790a28643ab058b507b35cBen Cheng data_alignment_factor, return_address_register); 533125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 533225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (augmentation[0] == 'z') 533325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 533425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int augmentationlen; 533525b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (augmentationlen, readp); 533625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 533725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (augmentationlen > (size_t) (dataend - readp)) 533825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (1, 0, gettext ("invalid augmentation length")); 533925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 534025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *hdr = "Augmentation data:"; 534125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *cp = augmentation + 1; 534225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (*cp != '\0') 534325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 534425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %-26s%#x ", hdr, *readp); 534525b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr = ""; 534625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 534725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (*cp == 'R') 534825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 534925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fde_encoding = *readp++; 535025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding_base (gettext ("FDE address encoding: "), 535125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fde_encoding); 535225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 535325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (*cp == 'L') 535425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 535525b3c049e70834cf33790a28643ab058b507b35cBen Cheng lsda_encoding = *readp++; 535625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding_base (gettext ("LSDA pointer encoding: "), 535725b3c049e70834cf33790a28643ab058b507b35cBen Cheng lsda_encoding); 535825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 535925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (*cp == 'P') 536025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 536125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Personality. This field usually has a relocation 536225b3c049e70834cf33790a28643ab058b507b35cBen Cheng attached pointing to __gcc_personality_v0. */ 536325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *startp = readp; 536425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int encoding = *readp++; 536525b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t val = 0; 536625b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = read_encoded (encoding, readp, 536725b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp - 1 + augmentationlen, 536825b3c049e70834cf33790a28643ab058b507b35cBen Cheng &val, dbg); 536925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 537025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (++startp < readp) 537125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%#x ", *startp); 537225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 537325b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar ('('); 537425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding (encoding); 537525b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar (' '); 537625b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (encoding & 0xf) 537725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 537825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sleb128: 537925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata2: 538025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata4: 538125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%" PRId64 ")\n", val); 538225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 538325b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 538425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%#" PRIx64 ")\n", val); 538525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 538625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 538725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 538825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 538925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("(%x)\n", *readp++); 539025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 539125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++cp; 539225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 539325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 539425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 539525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (ptr_size == 4 || ptr_size == 8)) 539625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 539725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct cieinfo *newp = alloca (sizeof (*newp)); 539825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->cie_offset = offset; 539925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->augmentation = augmentation; 540025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->fde_encoding = fde_encoding; 540125b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->lsda_encoding = lsda_encoding; 540225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->address_size = ptr_size; 540325b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->code_alignment_factor = code_alignment_factor; 540425b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->data_alignment_factor = data_alignment_factor; 540525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->next = cies; 540625b3c049e70834cf33790a28643ab058b507b35cBen Cheng cies = newp; 540725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 540825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 540925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 541025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 541125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct cieinfo *cie = cies; 541225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (cie != NULL) 541325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (is_eh_frame 541425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? start - (ptrdiff_t) cie_id == cie->cie_offset 541525b3c049e70834cf33790a28643ab058b507b35cBen Cheng : (ptrdiff_t) cie_id == cie->cie_offset) 541625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 541725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 541825b3c049e70834cf33790a28643ab058b507b35cBen Cheng cie = cie->next; 541925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (cie == NULL)) 542025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 542125b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts ("invalid CIE reference in FDE"); 542225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 542325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 542425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 542525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Initialize from CIE data. */ 542625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fde_encoding = cie->fde_encoding; 542725b3c049e70834cf33790a28643ab058b507b35cBen Cheng lsda_encoding = cie->lsda_encoding; 542825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptr_size = encoded_ptr_size (fde_encoding, cie->address_size); 542925b3c049e70834cf33790a28643ab058b507b35cBen Cheng code_alignment_factor = cie->code_alignment_factor; 543025b3c049e70834cf33790a28643ab058b507b35cBen Cheng data_alignment_factor = cie->data_alignment_factor; 543125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 543225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *base = readp; 543325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX There are sometimes relocations for this value 543425b3c049e70834cf33790a28643ab058b507b35cBen Cheng initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp); 543525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word address_range 543625b3c049e70834cf33790a28643ab058b507b35cBen Cheng = read_ubyte_unaligned_inc (ptr_size, dbg, readp); 543725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 543825b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *a = format_dwarf_addr (dwflmod, cie->address_size, 543925b3c049e70834cf33790a28643ab058b507b35cBen Cheng initial_location); 544025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n" 544125b3c049e70834cf33790a28643ab058b507b35cBen Cheng " CIE_pointer: %" PRIu64 "\n" 544225b3c049e70834cf33790a28643ab058b507b35cBen Cheng " initial_location: %s", 544325b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset, (uint64_t) unit_length, 544425b3c049e70834cf33790a28643ab058b507b35cBen Cheng cie->cie_offset, (uint64_t) cie_id, a); 544525b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (a); 544625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((fde_encoding & 0x70) == DW_EH_PE_pcrel) 544725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 544825b3c049e70834cf33790a28643ab058b507b35cBen Cheng vma_base = (((uint64_t) shdr->sh_offset 544925b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (base - (const unsigned char *) data->d_buf) 545025b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (uint64_t) initial_location) 545125b3c049e70834cf33790a28643ab058b507b35cBen Cheng & (ptr_size == 4 545225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? UINT64_C (0xffffffff) 545325b3c049e70834cf33790a28643ab058b507b35cBen Cheng : UINT64_C (0xffffffffffffffff))); 545425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" (offset: %#" PRIx64 ")"), 545525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) vma_base); 545625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 545725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 545825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\n address_range: %#" PRIx64, 545925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) address_range); 546025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((fde_encoding & 0x70) == DW_EH_PE_pcrel) 546125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" (end offset: %#" PRIx64 ")"), 546225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((uint64_t) vma_base + (uint64_t) address_range) 546325b3c049e70834cf33790a28643ab058b507b35cBen Cheng & (ptr_size == 4 546425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? UINT64_C (0xffffffff) 546525b3c049e70834cf33790a28643ab058b507b35cBen Cheng : UINT64_C (0xffffffffffffffff))); 546625b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar ('\n'); 546725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 546825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cie->augmentation[0] == 'z') 546925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 547025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int augmentationlen; 547125b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (augmentationlen, readp); 547225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 547325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (augmentationlen > 0) 547425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 547525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *hdr = "Augmentation data:"; 547625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *cp = cie->augmentation + 1; 547725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int u = 0; 547825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (*cp != '\0') 547925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 548025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (*cp == 'L') 548125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 548225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t lsda_pointer; 548325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *p 548425b3c049e70834cf33790a28643ab058b507b35cBen Cheng = read_encoded (lsda_encoding, &readp[u], 548525b3c049e70834cf33790a28643ab058b507b35cBen Cheng &readp[augmentationlen], 548625b3c049e70834cf33790a28643ab058b507b35cBen Cheng &lsda_pointer, dbg); 548725b3c049e70834cf33790a28643ab058b507b35cBen Cheng u = p - readp; 548825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 548925b3c049e70834cf33790a28643ab058b507b35cBen Cheng %-26sLSDA pointer: %#" PRIx64 "\n"), 549025b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr, lsda_pointer); 549125b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr = ""; 549225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 549325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++cp; 549425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 549525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 549625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (u < augmentationlen) 549725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 549825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %-26s%#x\n", hdr, readp[u++]); 549925b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr = ""; 550025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 550125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 550225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 550325b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += augmentationlen; 550425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 550525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 550625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 550725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle the initialization instructions. */ 550825b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_cfa_program (readp, cieend, vma_base, code_alignment_factor, 550925b3c049e70834cf33790a28643ab058b507b35cBen Cheng data_alignment_factor, version, ptr_size, 551025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwflmod, ebl, dbg); 551125b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = cieend; 551225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 551325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 551425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 551525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 551625b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct attrcb_args 551725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 551825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwfl_Module *dwflmod; 551925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf *dbg; 552025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int level; 552125b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool silent; 552225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int version; 552325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int addrsize; 552425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int offset_size; 552525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off cu_offset; 552625b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 552725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 552825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 552925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 553025b3c049e70834cf33790a28643ab058b507b35cBen Chengattr_callback (Dwarf_Attribute *attrp, void *arg) 553125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 553225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct attrcb_args *cbargs = (struct attrcb_args *) arg; 553325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const int level = cbargs->level; 553425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 553525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int attr = dwarf_whatattr (attrp); 553625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (attr == 0)) 553725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 553825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!cbargs->silent) 553925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get attribute code: %s"), 554025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 554125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_ABORT; 554225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 554325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 554425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int form = dwarf_whatform (attrp); 554525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (form == 0)) 554625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 554725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!cbargs->silent) 554825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get attribute form: %s"), 554925b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 555025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_ABORT; 555125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 555225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 555325b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (form) 555425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 555525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_addr: 555625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!cbargs->silent) 555725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 555825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr addr; 555925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (dwarf_formaddr (attrp, &addr) != 0)) 556025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 556125b3c049e70834cf33790a28643ab058b507b35cBen Cheng attrval_out: 556225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!cbargs->silent) 556325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get attribute value: %s"), 556425b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 556525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_ABORT; 556625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 556725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr); 556825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) %s\n", 556925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 557025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), a); 557125b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (a); 557225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 557325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 557425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 557525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_indirect: 557625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_strp: 557725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_string: 557825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cbargs->silent) 557925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 558025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *str = dwarf_formstring (attrp); 558125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (str == NULL)) 558225b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto attrval_out; 558325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) \"%s\"\n", 558425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 558525b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), str); 558625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 558725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 558825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_ref_addr: 558925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_ref_udata: 559025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_ref8: 559125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_ref4: 559225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_ref2: 559325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_ref1:; 559425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cbargs->silent) 559525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 559625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Die ref; 559725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (dwarf_formref_die (attrp, &ref) == NULL)) 559825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto attrval_out; 559925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 560025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n", 560125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 560225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), (uintmax_t) dwarf_dieoffset (&ref)); 560325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 560425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 560525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_ref_sig8: 560625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cbargs->silent) 560725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 560825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) {%6" PRIx64 "}\n", 560925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 561025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), 561125b3c049e70834cf33790a28643ab058b507b35cBen Cheng read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp)); 561225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 561325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 561425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_sec_offset: 561525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_udata: 561625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_sdata: 561725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_data8: 561825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_data4: 561925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_data2: 562025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_data1:; 562125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word num; 562225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (dwarf_formudata (attrp, &num) != 0)) 562325b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto attrval_out; 562425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 562525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *valuestr = NULL; 562625b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (attr) 562725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 562825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This case can take either a constant or a loclistptr. */ 562925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_data_member_location: 563025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (form != DW_FORM_sec_offset 563125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (cbargs->version >= 4 563225b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (form != DW_FORM_data4 && form != DW_FORM_data8))) 563325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 563425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!cbargs->silent) 563525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) %" PRIxMAX "\n", 563625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 563725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), (uintmax_t) num); 563825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_OK; 563925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 564025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* else fallthrough */ 564125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 564225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* These cases always take a loclistptr and no constant. */ 564325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_location: 564425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_data_location: 564525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_vtable_elem_location: 564625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_string_length: 564725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_use_location: 564825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_frame_base: 564925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_return_addr: 565025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_static_link: 565125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_value: 565225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_data_value: 565325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_target: 565425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_target_clobbered: 565525b3c049e70834cf33790a28643ab058b507b35cBen Cheng notice_listptr (section_loc, &known_loclistptr, 565625b3c049e70834cf33790a28643ab058b507b35cBen Cheng cbargs->addrsize, cbargs->offset_size, num); 565725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!cbargs->silent) 565825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n", 565925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 566025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), (uintmax_t) num); 566125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_OK; 566225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 566325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_ranges: 566425b3c049e70834cf33790a28643ab058b507b35cBen Cheng notice_listptr (section_ranges, &known_rangelistptr, 566525b3c049e70834cf33790a28643ab058b507b35cBen Cheng cbargs->addrsize, cbargs->offset_size, num); 566625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!cbargs->silent) 566725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n", 566825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 566925b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), (uintmax_t) num); 567025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_OK; 567125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 567225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_language: 567325b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_lang_string (num); 567425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 567525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_encoding: 567625b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_encoding_string (num); 567725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 567825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_accessibility: 567925b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_access_string (num); 568025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 568125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_visibility: 568225b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_visibility_string (num); 568325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 568425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_virtuality: 568525b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_virtuality_string (num); 568625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 568725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_identifier_case: 568825b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_identifier_case_string (num); 568925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 569025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_calling_convention: 569125b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_calling_convention_string (num); 569225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 569325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_inline: 569425b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_inline_string (num); 569525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 569625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_ordering: 569725b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_ordering_string (num); 569825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 569925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_discr_list: 570025b3c049e70834cf33790a28643ab058b507b35cBen Cheng valuestr = dwarf_discr_list_string (num); 570125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 570225b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 570325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Nothing. */ 570425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 570525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 570625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 570725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cbargs->silent) 570825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 570925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 571025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (valuestr == NULL) 571125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) %" PRIuMAX "\n", 571225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 571325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), (uintmax_t) num); 571425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 571525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) %s (%" PRIuMAX ")\n", 571625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 571725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), valuestr, (uintmax_t) num); 571825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 571925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 572025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_flag: 572125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cbargs->silent) 572225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 572325b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool flag; 572425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (dwarf_formflag (attrp, &flag) != 0)) 572525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto attrval_out; 572625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 572725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) %s\n", 572825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 572925b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), nl_langinfo (flag ? YESSTR : NOSTR)); 573025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 573125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 573225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_flag_present: 573325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cbargs->silent) 573425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 573525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) %s\n", 573625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 573725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form), nl_langinfo (YESSTR)); 573825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 573925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 574025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_exprloc: 574125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_block4: 574225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_block2: 574325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_block1: 574425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_FORM_block: 574525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cbargs->silent) 574625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 574725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Block block; 574825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (dwarf_formblock (attrp, &block) != 0)) 574925b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto attrval_out; 575025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 575125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (%s) ", 575225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 575325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_form_string (form)); 575425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 575525b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (attr) 575625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 575725b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 575825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (form != DW_FORM_exprloc) 575925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 576025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_block (block.length, block.data); 576125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 576225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 576325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fall through. */ 576425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 576525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_location: 576625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_data_location: 576725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_data_member_location: 576825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_vtable_elem_location: 576925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_string_length: 577025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_use_location: 577125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_frame_base: 577225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_return_addr: 577325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_static_link: 577425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_allocated: 577525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_associated: 577625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_bit_size: 577725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_bit_offset: 577825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_bit_stride: 577925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_byte_size: 578025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_byte_stride: 578125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_count: 578225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_lower_bound: 578325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_upper_bound: 578425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_value: 578525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_data_value: 578625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_target: 578725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_AT_GNU_call_site_target_clobbered: 578825b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar ('\n'); 578925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_ops (cbargs->dwflmod, cbargs->dbg, 579025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12 + level * 2, 12 + level * 2, 579125b3c049e70834cf33790a28643ab058b507b35cBen Cheng cbargs->version, cbargs->addrsize, cbargs->offset_size, 579225b3c049e70834cf33790a28643ab058b507b35cBen Cheng block.length, block.data); 579325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 579425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 579525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 579625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 579725b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 579825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cbargs->silent) 579925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 580025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %*s%-20s (form: %#x) ???\n", 580125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) (level * 2), "", dwarf_attr_string (attr), 580225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) form); 580325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 580425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 580525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 580625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_OK; 580725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 580825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 580925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 581025b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_units (Dwfl_Module *dwflmod, 581125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl, GElf_Ehdr *ehdr, 581225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, 581325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf *dbg, bool debug_types) 581425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 581525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const bool silent = !(print_debug_sections & section_info); 581625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *secname = section_name (ebl, ehdr, shdr); 581725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 581825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent) 581925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 582025b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"), 582125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset); 582225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 582325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the section is empty we don't have to do anything. */ 582425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent && shdr->sh_size == 0) 582525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 582625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 582725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int maxdies = 20; 582825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die)); 582925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 583025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off offset = 0; 583125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 583225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* New compilation unit. */ 583325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cuhl; 583425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Half version; 583525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off abbroffset; 583625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint8_t addrsize; 583725b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint8_t offsize; 583825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off nextcu; 583925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t typesig; 584025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off typeoff; 584125b3c049e70834cf33790a28643ab058b507b35cBen Cheng next_cu: 584225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version, 584325b3c049e70834cf33790a28643ab058b507b35cBen Cheng &abbroffset, &addrsize, &offsize, 584425b3c049e70834cf33790a28643ab058b507b35cBen Cheng debug_types ? &typesig : NULL, 584525b3c049e70834cf33790a28643ab058b507b35cBen Cheng debug_types ? &typeoff : NULL) != 0) 584625b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto do_return; 584725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 584825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent) 584925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 585025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (debug_types) 585125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Type unit at offset %" PRIu64 ":\n" 585225b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Version: %" PRIu16 ", Abbreviation section offset: %" 585325b3c049e70834cf33790a28643ab058b507b35cBen Cheng PRIu64 ", Address size: %" PRIu8 585425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", Offset size: %" PRIu8 585525b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\n Type signature: %#" PRIx64 585625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", Type offset: %#" PRIx64 "\n"), 585725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) offset, version, abbroffset, addrsize, offsize, 585825b3c049e70834cf33790a28643ab058b507b35cBen Cheng typesig, (uint64_t) typeoff); 585925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 586025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Compilation unit at offset %" PRIu64 ":\n" 586125b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Version: %" PRIu16 ", Abbreviation section offset: %" 586225b3c049e70834cf33790a28643ab058b507b35cBen Cheng PRIu64 ", Address size: %" PRIu8 586325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", Offset size: %" PRIu8 "\n"), 586425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) offset, version, abbroffset, addrsize, offsize); 586525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 586625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 586725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct attrcb_args args = 586825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 586925b3c049e70834cf33790a28643ab058b507b35cBen Cheng .dwflmod = dwflmod, 587025b3c049e70834cf33790a28643ab058b507b35cBen Cheng .dbg = dbg, 587125b3c049e70834cf33790a28643ab058b507b35cBen Cheng .silent = silent, 587225b3c049e70834cf33790a28643ab058b507b35cBen Cheng .version = version, 587325b3c049e70834cf33790a28643ab058b507b35cBen Cheng .addrsize = addrsize, 587425b3c049e70834cf33790a28643ab058b507b35cBen Cheng .offset_size = offsize, 587525b3c049e70834cf33790a28643ab058b507b35cBen Cheng .cu_offset = offset 587625b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 587725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 587825b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += cuhl; 587925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 588025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int level = 0; 588125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 588225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie) 588325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (dbg, offset, &dies[level]) == NULL)) 588425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 588525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent) 588625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get DIE at offset %" PRIu64 588725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " in section '%s': %s"), 588825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) offset, secname, dwarf_errmsg (-1)); 588925b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto do_return; 589025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 589125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 589225b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 589325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 589425b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = dwarf_dieoffset (&dies[level]); 589525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (offset == ~0ul)) 589625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 589725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent) 589825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get DIE offset: %s"), 589925b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 590025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto do_return; 590125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 590225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 590325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int tag = dwarf_tag (&dies[level]); 590425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (tag == DW_TAG_invalid)) 590525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 590625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent) 590725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64 590825b3c049e70834cf33790a28643ab058b507b35cBen Cheng " in section '%s': %s"), 590925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) offset, secname, dwarf_errmsg (-1)); 591025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto do_return; 591125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 591225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 591325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent) 591425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%6" PRIx64 "] %*s%s\n", 591525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) offset, (int) (level * 2), "", 591625b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_tag_string (tag)); 591725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 591825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Print the attribute values. */ 591925b3c049e70834cf33790a28643ab058b507b35cBen Cheng args.level = level; 592025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0); 592125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 592225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make room for the next level's DIE. */ 592325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (level + 1 == maxdies) 592425b3c049e70834cf33790a28643ab058b507b35cBen Cheng dies = (Dwarf_Die *) xrealloc (dies, 592525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (maxdies += 10) 592625b3c049e70834cf33790a28643ab058b507b35cBen Cheng * sizeof (Dwarf_Die)); 592725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 592825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int res = dwarf_child (&dies[level], &dies[level + 1]); 592925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (res > 0) 593025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 593125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1) 593225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (level-- == 0) 593325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 593425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 593525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (res == -1)) 593625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 593725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent) 593825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get next DIE: %s\n"), 593925b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 594025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto do_return; 594125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 594225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 594325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (res < 0)) 594425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 594525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!silent) 594625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get next DIE: %s"), 594725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 594825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto do_return; 594925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 595025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 595125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++level; 595225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 595325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (level >= 0); 595425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 595525b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = nextcu; 595625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (offset != 0) 595725b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto next_cu; 595825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 595925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do_return: 596025b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (dies); 596125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 596225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 596325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 596425b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 596525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 596625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 596725b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false); 596825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 596925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 597025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 597125b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 597225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 597325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 597425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true); 597525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 597625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 597725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 597825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 597925b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 598025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 598125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 598225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 598325b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 598425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 598525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset); 598625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 598725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_size == 0) 598825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 598925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 599025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There is no functionality in libdw to read the information in the 599125b3c049e70834cf33790a28643ab058b507b35cBen Cheng way it is represented here. Hardcode the decoder. */ 599225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 599325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL || data->d_buf == NULL)) 599425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 599525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get line data section data: %s"), 599625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 599725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 599825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 599925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 600025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *linep = (const unsigned char *) data->d_buf; 600125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *lineendp; 600225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 600325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (linep 600425b3c049e70834cf33790a28643ab058b507b35cBen Cheng < (lineendp = (const unsigned char *) data->d_buf + data->d_size)) 600525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 600625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t start_offset = linep - (const unsigned char *) data->d_buf; 600725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 600825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nTable at offset %Zu:\n"), start_offset); 600925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 601025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); 601125b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int length = 4; 601225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (unit_length == 0xffffffff)) 601325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 601425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (linep + 8 > lineendp)) 601525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 601625b3c049e70834cf33790a28643ab058b507b35cBen Cheng invalid_data: 601725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("invalid data in section [%zu] '%s'"), 601825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr)); 601925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 602025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 602125b3c049e70834cf33790a28643ab058b507b35cBen Cheng unit_length = read_8ubyte_unaligned_inc (dbg, linep); 602225b3c049e70834cf33790a28643ab058b507b35cBen Cheng length = 8; 602325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 602425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 602525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether we have enough room in the section. */ 602625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unit_length < 2 + length + 5 * 1 602725b3c049e70834cf33790a28643ab058b507b35cBen Cheng || unlikely (linep + unit_length > lineendp)) 602825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 602925b3c049e70834cf33790a28643ab058b507b35cBen Cheng lineendp = linep + unit_length; 603025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 603125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The next element of the header is the version identifier. */ 603225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); 603325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 603425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Next comes the header length. */ 603525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word header_length; 603625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (length == 4) 603725b3c049e70834cf33790a28643ab058b507b35cBen Cheng header_length = read_4ubyte_unaligned_inc (dbg, linep); 603825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 603925b3c049e70834cf33790a28643ab058b507b35cBen Cheng header_length = read_8ubyte_unaligned_inc (dbg, linep); 604025b3c049e70834cf33790a28643ab058b507b35cBen Cheng //const unsigned char *header_start = linep; 604125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 604225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Next the minimum instruction length. */ 604325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t minimum_instr_len = *linep++; 604425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 604525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Next the maximum operations per instruction, in version 4 format. */ 604625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++; 604725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 604825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Then the flag determining the default value of the is_stmt 604925b3c049e70834cf33790a28643ab058b507b35cBen Cheng register. */ 605025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t default_is_stmt = *linep++; 605125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 605225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now the line base. */ 605325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int_fast8_t line_base = *((const int_fast8_t *) linep); 605425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++linep; 605525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 605625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And the line range. */ 605725b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t line_range = *linep++; 605825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 605925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The opcode base. */ 606025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t opcode_base = *linep++; 606125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 606225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Print what we got so far. */ 606325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\n" 606425b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Length: %" PRIu64 "\n" 606525b3c049e70834cf33790a28643ab058b507b35cBen Cheng " DWARF version: %" PRIuFAST16 "\n" 606625b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Prologue length: %" PRIu64 "\n" 606725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Minimum instruction length: %" PRIuFAST8 "\n" 606825b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Maximum operations per instruction: %" PRIuFAST8 "\n" 606925b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Initial value if '%s': %" PRIuFAST8 "\n" 607025b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Line base: %" PRIdFAST8 "\n" 607125b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Line range: %" PRIuFAST8 "\n" 607225b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Opcode base: %" PRIuFAST8 "\n" 607325b3c049e70834cf33790a28643ab058b507b35cBen Cheng "\n" 607425b3c049e70834cf33790a28643ab058b507b35cBen Cheng "Opcodes:\n"), 607525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) unit_length, version, (uint64_t) header_length, 607625b3c049e70834cf33790a28643ab058b507b35cBen Cheng minimum_instr_len, max_ops_per_instr, 607725b3c049e70834cf33790a28643ab058b507b35cBen Cheng "is_stmt", default_is_stmt, line_base, 607825b3c049e70834cf33790a28643ab058b507b35cBen Cheng line_range, opcode_base); 607925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 608025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (linep + opcode_base - 1 >= lineendp)) 608125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 608225b3c049e70834cf33790a28643ab058b507b35cBen Cheng invalid_unit: 608325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, 608425b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("invalid data at offset %tu in section [%zu] '%s'"), 608525b3c049e70834cf33790a28643ab058b507b35cBen Cheng linep - (const unsigned char *) data->d_buf, 608625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr)); 608725b3c049e70834cf33790a28643ab058b507b35cBen Cheng linep = lineendp; 608825b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 608925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 609025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int opcode_base_l10 = 1; 609125b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int tmp = opcode_base; 609225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (tmp > 10) 609325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 609425b3c049e70834cf33790a28643ab058b507b35cBen Cheng tmp /= 10; 609525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++opcode_base_l10; 609625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 609725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const uint8_t *standard_opcode_lengths = linep - 1; 609825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt) 609925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n", 610025b3c049e70834cf33790a28643ab058b507b35cBen Cheng " [%*" PRIuFAST8 "] %hhu arguments\n", 610125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) linep[cnt - 1]), 610225b3c049e70834cf33790a28643ab058b507b35cBen Cheng opcode_base_l10, cnt, linep[cnt - 1]); 610325b3c049e70834cf33790a28643ab058b507b35cBen Cheng linep += opcode_base - 1; 610425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (linep >= lineendp)) 610525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 610625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 610725b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("\nDirectory table:")); 610825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (*linep != 0) 610925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 611025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *endp = memchr (linep, '\0', lineendp - linep); 611125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (endp == NULL)) 611225b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 611325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 611425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %s\n", (char *) linep); 611525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 611625b3c049e70834cf33790a28643ab058b507b35cBen Cheng linep = endp + 1; 611725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 611825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Skip the final NUL byte. */ 611925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++linep; 612025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 612125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (linep >= lineendp)) 612225b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 612325b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("\nFile name table:\n" 612425b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Entry Dir Time Size Name")); 612525b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (unsigned int cnt = 1; *linep != 0; ++cnt) 612625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 612725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First comes the file name. */ 612825b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *fname = (char *) linep; 612925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *endp = memchr (fname, '\0', lineendp - linep); 613025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (endp == NULL)) 613125b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 613225b3c049e70834cf33790a28643ab058b507b35cBen Cheng linep = endp + 1; 613325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 613425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Then the index. */ 613525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int diridx; 613625b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (diridx, linep); 613725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 613825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Next comes the modification time. */ 613925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int mtime; 614025b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (mtime, linep); 614125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 614225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Finally the length of the file. */ 614325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int fsize; 614425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (fsize, linep); 614525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 614625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %-5u %-5u %-9u %-9u %s\n", 614725b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt, diridx, mtime, fsize, fname); 614825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 614925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Skip the final NUL byte. */ 615025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++linep; 615125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 615225b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("\nLine number statements:")); 615325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word address = 0; 615425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int op_index = 0; 615525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t line = 1; 615625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t is_stmt = default_is_stmt; 615725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 615825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Default address value, in case we do not find the CU. */ 615925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t address_size 616025b3c049e70834cf33790a28643ab058b507b35cBen Cheng = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8; 616125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 616225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the CU this block is for. */ 616325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off cuoffset; 616425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off ncuoffset = 0; 616525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t hsize; 616625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize, 616725b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL, NULL, NULL) == 0) 616825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 616925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Die cudie; 617025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL) 617125b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 617225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Attribute stmt_list; 617325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL) 617425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 617525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word lineoff; 617625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_formudata (&stmt_list, &lineoff) != 0) 617725b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 617825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (lineoff == start_offset) 617925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 618025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Found the CU. */ 618125b3c049e70834cf33790a28643ab058b507b35cBen Cheng address_size = cudie.cu->address_size; 618225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 618325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 618425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 618525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 618625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Apply the "operation advance" from a special opcode 618725b3c049e70834cf33790a28643ab058b507b35cBen Cheng or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */ 618825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int op_addr_advance; 618925b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool show_op_index; 619025b3c049e70834cf33790a28643ab058b507b35cBen Cheng inline void advance_pc (unsigned int op_advance) 619125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 619225b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_addr_advance = minimum_instr_len * ((op_index + op_advance) 619325b3c049e70834cf33790a28643ab058b507b35cBen Cheng / max_ops_per_instr); 619425b3c049e70834cf33790a28643ab058b507b35cBen Cheng address += op_advance; 619525b3c049e70834cf33790a28643ab058b507b35cBen Cheng show_op_index = (op_index > 0 || 619625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (op_index + op_advance) % max_ops_per_instr > 0); 619725b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_index = (op_index + op_advance) % max_ops_per_instr; 619825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 619925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 620025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (linep < lineendp) 620125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 620225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t offset = linep - (const unsigned char *) data->d_buf; 620325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int u128; 620425b3c049e70834cf33790a28643ab058b507b35cBen Cheng int s128; 620525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 620625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Read the opcode. */ 620725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int opcode = *linep++; 620825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 620925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%6" PRIx64 "]", (uint64_t)offset); 621025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Is this a special opcode? */ 621125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (opcode >= opcode_base)) 621225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 621325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Yes. Handling this is quite easy since the opcode value 621425b3c049e70834cf33790a28643ab058b507b35cBen Cheng is computed with 621525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 621625b3c049e70834cf33790a28643ab058b507b35cBen Cheng opcode = (desired line increment - line_base) 621725b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (line_range * address advance) + opcode_base 621825b3c049e70834cf33790a28643ab058b507b35cBen Cheng */ 621925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int line_increment = (line_base 622025b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (opcode - opcode_base) % line_range); 622125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 622225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Perform the increments. */ 622325b3c049e70834cf33790a28643ab058b507b35cBen Cheng line += line_increment; 622425b3c049e70834cf33790a28643ab058b507b35cBen Cheng advance_pc ((opcode - opcode_base) / line_range); 622525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 622625b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 622725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (show_op_index) 622825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 622925b3c049e70834cf33790a28643ab058b507b35cBen Cheng special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"), 623025b3c049e70834cf33790a28643ab058b507b35cBen Cheng opcode, op_addr_advance, a, op_index, 623125b3c049e70834cf33790a28643ab058b507b35cBen Cheng line_increment, line); 623225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 623325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 623425b3c049e70834cf33790a28643ab058b507b35cBen Cheng special opcode %u: address+%u = %s, line%+d = %zu\n"), 623525b3c049e70834cf33790a28643ab058b507b35cBen Cheng opcode, op_addr_advance, a, line_increment, line); 623625b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (a); 623725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 623825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (opcode == 0) 623925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 624025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This an extended opcode. */ 624125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (linep + 2 > lineendp)) 624225b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 624325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 624425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The length. */ 624525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int len = *linep++; 624625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 624725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (linep + len > lineendp)) 624825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 624925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 625025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The sub-opcode. */ 625125b3c049e70834cf33790a28643ab058b507b35cBen Cheng opcode = *linep++; 625225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 625325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" extended opcode %u: "), opcode); 625425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 625525b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (opcode) 625625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 625725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNE_end_sequence: 625825b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext (" end of sequence")); 625925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 626025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Reset the registers we care about. */ 626125b3c049e70834cf33790a28643ab058b507b35cBen Cheng address = 0; 626225b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_index = 0; 626325b3c049e70834cf33790a28643ab058b507b35cBen Cheng line = 1; 626425b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_stmt = default_is_stmt; 626525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 626625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 626725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNE_set_address: 626825b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_index = 0; 626925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (address_size == 4) 627025b3c049e70834cf33790a28643ab058b507b35cBen Cheng address = read_4ubyte_unaligned_inc (dbg, linep); 627125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 627225b3c049e70834cf33790a28643ab058b507b35cBen Cheng address = read_8ubyte_unaligned_inc (dbg, linep); 627325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 627425b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 627525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" set address to %s\n"), a); 627625b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (a); 627725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 627825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 627925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 628025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNE_define_file: 628125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 628225b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *fname = (char *) linep; 628325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *endp = memchr (linep, '\0', 628425b3c049e70834cf33790a28643ab058b507b35cBen Cheng lineendp - linep); 628525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (endp == NULL)) 628625b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 628725b3c049e70834cf33790a28643ab058b507b35cBen Cheng linep = endp + 1; 628825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 628925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int diridx; 629025b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (diridx, linep); 629125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word mtime; 629225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (mtime, linep); 629325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word filelength; 629425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (filelength, linep); 629525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 629625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 629725b3c049e70834cf33790a28643ab058b507b35cBen Cheng define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"), 629825b3c049e70834cf33790a28643ab058b507b35cBen Cheng diridx, (uint64_t) mtime, (uint64_t) filelength, 629925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname); 630025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 630125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 630225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 630325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNE_set_discriminator: 630425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes one ULEB128 parameter, the discriminator. */ 630525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (standard_opcode_lengths[opcode] != 1)) 630625b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 630725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 630825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128, linep); 630925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" set discriminator to %u\n"), u128); 631025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 631125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 631225b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 631325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Unknown, ignore it. */ 631425b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext (" unknown opcode")); 631525b3c049e70834cf33790a28643ab058b507b35cBen Cheng linep += len - 1; 631625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 631725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 631825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 631925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (opcode <= DW_LNS_set_isa) 632025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 632125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is a known standard opcode. */ 632225b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (opcode) 632325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 632425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_copy: 632525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes no argument. */ 632625b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext (" copy")); 632725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 632825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 632925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_advance_pc: 633025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes one uleb128 parameter which is added to the 633125b3c049e70834cf33790a28643ab058b507b35cBen Cheng address. */ 633225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128, linep); 633325b3c049e70834cf33790a28643ab058b507b35cBen Cheng advance_pc (u128); 633425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 633525b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 633625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (show_op_index) 633725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 633825b3c049e70834cf33790a28643ab058b507b35cBen Cheng advance address by %u to %s, op_index to %u\n"), 633925b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_addr_advance, a, op_index); 634025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 634125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" advance address by %u to %s\n"), 634225b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_addr_advance, a); 634325b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (a); 634425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 634525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 634625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 634725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_advance_line: 634825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes one sleb128 parameter which is added to the 634925b3c049e70834cf33790a28643ab058b507b35cBen Cheng line. */ 635025b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (s128, linep); 635125b3c049e70834cf33790a28643ab058b507b35cBen Cheng line += s128; 635225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 635325b3c049e70834cf33790a28643ab058b507b35cBen Cheng advance line by constant %d to %" PRId64 "\n"), 635425b3c049e70834cf33790a28643ab058b507b35cBen Cheng s128, (int64_t) line); 635525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 635625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 635725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_set_file: 635825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes one uleb128 parameter which is stored in file. */ 635925b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128, linep); 636025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" set file to %" PRIu64 "\n"), 636125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) u128); 636225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 636325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 636425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_set_column: 636525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes one uleb128 parameter which is stored in column. */ 636625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (standard_opcode_lengths[opcode] != 1)) 636725b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 636825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 636925b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128, linep); 637025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" set column to %" PRIu64 "\n"), 637125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) u128); 637225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 637325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 637425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_negate_stmt: 637525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes no argument. */ 637625b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_stmt = 1 - is_stmt; 637725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" set '%s' to %" PRIuFAST8 "\n"), 637825b3c049e70834cf33790a28643ab058b507b35cBen Cheng "is_stmt", is_stmt); 637925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 638025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 638125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_set_basic_block: 638225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes no argument. */ 638325b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext (" set basic block flag")); 638425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 638525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 638625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_const_add_pc: 638725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes no argument. */ 638825b3c049e70834cf33790a28643ab058b507b35cBen Cheng advance_pc ((255 - opcode_base) / line_range); 638925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 639025b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 639125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (show_op_index) 639225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 639325b3c049e70834cf33790a28643ab058b507b35cBen Cheng advance address by constant %u to %s, op_index to %u\n"), 639425b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_addr_advance, a, op_index); 639525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 639625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 639725b3c049e70834cf33790a28643ab058b507b35cBen Cheng advance address by constant %u to %s\n"), 639825b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_addr_advance, a); 639925b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (a); 640025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 640125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 640225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 640325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_fixed_advance_pc: 640425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes one 16 bit parameter which is added to the 640525b3c049e70834cf33790a28643ab058b507b35cBen Cheng address. */ 640625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (standard_opcode_lengths[opcode] != 1)) 640725b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 640825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 640925b3c049e70834cf33790a28643ab058b507b35cBen Cheng u128 = read_2ubyte_unaligned_inc (dbg, linep); 641025b3c049e70834cf33790a28643ab058b507b35cBen Cheng address += u128; 641125b3c049e70834cf33790a28643ab058b507b35cBen Cheng op_index = 0; 641225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 641325b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 641425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 641525b3c049e70834cf33790a28643ab058b507b35cBen Cheng advance address by fixed value %u to %s\n"), 641625b3c049e70834cf33790a28643ab058b507b35cBen Cheng u128, a); 641725b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (a); 641825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 641925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 642025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 642125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_set_prologue_end: 642225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes no argument. */ 642325b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext (" set prologue end flag")); 642425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 642525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 642625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_set_epilogue_begin: 642725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes no argument. */ 642825b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext (" set epilogue begin flag")); 642925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 643025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 643125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_LNS_set_isa: 643225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Takes one uleb128 parameter which is stored in isa. */ 643325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (standard_opcode_lengths[opcode] != 1)) 643425b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_unit; 643525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 643625b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128, linep); 643725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" set isa to %u\n"), u128); 643825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 643925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 644025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 644125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 644225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 644325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is a new opcode the generator but not we know about. 644425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Read the parameters associated with it but then discard 644525b3c049e70834cf33790a28643ab058b507b35cBen Cheng everything. Read all the parameters for this opcode. */ 644625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (ngettext (" unknown opcode with %" PRIu8 " parameter:", 644725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " unknown opcode with %" PRIu8 " parameters:", 644825b3c049e70834cf33790a28643ab058b507b35cBen Cheng standard_opcode_lengths[opcode]), 644925b3c049e70834cf33790a28643ab058b507b35cBen Cheng standard_opcode_lengths[opcode]); 645025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int n = standard_opcode_lengths[opcode]; n > 0; --n) 645125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 645225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128, linep); 645325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (n != standard_opcode_lengths[opcode]) 645425b3c049e70834cf33790a28643ab058b507b35cBen Cheng putc_unlocked (',', stdout); 645525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %u", u128); 645625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 645725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 645825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Next round, ignore this opcode. */ 645925b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 646025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 646125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 646225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 646325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 646425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There must only be one data block. */ 646525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (elf_getdata (scn, data) == NULL); 646625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 646725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 646825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 646925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 647025b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_loc_section (Dwfl_Module *dwflmod, 647125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl, GElf_Ehdr *ehdr, 647225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 647325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 647425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 647525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 647625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 647725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 647825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get .debug_loc content: %s"), 647925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 648025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 648125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 648225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 648325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 648425b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 648525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 648625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset); 648725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 648825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sort_listptr (&known_loclistptr, "loclistptr"); 648925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t listptr_idx = 0; 649025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 649125b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 649225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast8_t offset_size = 4; 649325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 649425b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool first = true; 649525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *readp = data->d_buf; 649625b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size; 649725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp < endp) 649825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 649925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ptrdiff_t offset = readp - (unsigned char *) data->d_buf; 650025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 650125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx, 650225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &address_size, &offset_size, 650325b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset, &readp, endp)) 650425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 650525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 650625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data->d_size - offset < address_size * 2)) 650725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 650825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] <INVALID DATA>\n"), offset); 650925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 651025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 651125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 651225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr begin; 651325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr end; 651425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (address_size == 8) 651525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 651625b3c049e70834cf33790a28643ab058b507b35cBen Cheng begin = read_8ubyte_unaligned_inc (dbg, readp); 651725b3c049e70834cf33790a28643ab058b507b35cBen Cheng end = read_8ubyte_unaligned_inc (dbg, readp); 651825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 651925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 652025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 652125b3c049e70834cf33790a28643ab058b507b35cBen Cheng begin = read_4ubyte_unaligned_inc (dbg, readp); 652225b3c049e70834cf33790a28643ab058b507b35cBen Cheng end = read_4ubyte_unaligned_inc (dbg, readp); 652325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (begin == (Dwarf_Addr) (uint32_t) -1) 652425b3c049e70834cf33790a28643ab058b507b35cBen Cheng begin = (Dwarf_Addr) -1l; 652525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 652625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 652725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ 652825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 652925b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *b = format_dwarf_addr (dwflmod, address_size, end); 653025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] base address %s\n"), offset, b); 653125b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (b); 653225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 653325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (begin == 0 && end == 0) /* End of list entry. */ 653425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 653525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first) 653625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] empty list\n"), offset); 653725b3c049e70834cf33790a28643ab058b507b35cBen Cheng first = true; 653825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 653925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 654025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 654125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have a location expression entry. */ 654225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp); 654325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 654425b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *b = format_dwarf_addr (dwflmod, address_size, begin); 654525b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *e = format_dwarf_addr (dwflmod, address_size, end); 654625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 654725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first) /* First entry in a list. */ 654825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%6tx] %s..%s"), offset, b, e); 654925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 655025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %s..%s"), b, e); 655125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 655225b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (b); 655325b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (e); 655425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 655525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (endp - readp <= (ptrdiff_t) len) 655625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 655725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs (gettext (" <INVALID DATA>\n"), stdout); 655825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 655925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 656025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 656125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_ops (dwflmod, dbg, 1, 18 + (address_size * 4), 656225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 3 /*XXX*/, address_size, offset_size, len, readp); 656325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 656425b3c049e70834cf33790a28643ab058b507b35cBen Cheng first = false; 656525b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += len; 656625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 656725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 656825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 656925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 657025b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct mac_culist 657125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 657225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Die die; 657325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off offset; 657425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Files *files; 657525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct mac_culist *next; 657625b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 657725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 657825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 657925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 658025b3c049e70834cf33790a28643ab058b507b35cBen Chengmac_compare (const void *p1, const void *p2) 658125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 658225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct mac_culist *m1 = (struct mac_culist *) p1; 658325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct mac_culist *m2 = (struct mac_culist *) p2; 658425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 658525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (m1->offset < m2->offset) 658625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return -1; 658725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (m1->offset > m2->offset) 658825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 658925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 659025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 659125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 659225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 659325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 659425b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 659525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl, GElf_Ehdr *ehdr, 659625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 659725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 659825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 659925b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 660025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 660125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset); 660225b3c049e70834cf33790a28643ab058b507b35cBen Cheng putc_unlocked ('\n', stdout); 660325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 660425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There is no function in libdw to iterate over the raw content of 660525b3c049e70834cf33790a28643ab058b507b35cBen Cheng the section but it is easy enough to do. */ 660625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 660725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL || data->d_buf == NULL)) 660825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 660925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get macro information section data: %s"), 661025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 661125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 661225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 661325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 661425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the source file information for all CUs. */ 661525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off offset; 661625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off ncu = 0; 661725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t hsize; 661825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct mac_culist *culist = NULL; 661925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nculist = 0; 662025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0) 662125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 662225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Die cudie; 662325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL) 662425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 662525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 662625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Attribute attr; 662725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL) 662825b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 662925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 663025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word macoff; 663125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_formudata (&attr, &macoff) != 0) 663225b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 663325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 663425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp)); 663525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->die = cudie; 663625b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->offset = macoff; 663725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->files = NULL; 663825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->next = culist; 663925b3c049e70834cf33790a28643ab058b507b35cBen Cheng culist = newp; 664025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nculist; 664125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 664225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 664325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Convert the list into an array for easier consumption. */ 664425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1) 664525b3c049e70834cf33790a28643ab058b507b35cBen Cheng * sizeof (*cus)); 664625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add sentinel. */ 664725b3c049e70834cf33790a28643ab058b507b35cBen Cheng cus[nculist].offset = data->d_size; 664825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (nculist > 0) 664925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 665025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = nculist - 1; culist != NULL; --cnt) 665125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 665225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (cnt < nculist); 665325b3c049e70834cf33790a28643ab058b507b35cBen Cheng cus[cnt] = *culist; 665425b3c049e70834cf33790a28643ab058b507b35cBen Cheng culist = culist->next; 665525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 665625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 665725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Sort the array according to the offset in the .debug_macinfo 665825b3c049e70834cf33790a28643ab058b507b35cBen Cheng section. Note we keep the sentinel at the end. */ 665925b3c049e70834cf33790a28643ab058b507b35cBen Cheng qsort (cus, nculist, sizeof (*cus), mac_compare); 666025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 666125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 666225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *readp = (const unsigned char *) data->d_buf; 666325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *readendp = readp + data->d_size; 666425b3c049e70834cf33790a28643ab058b507b35cBen Cheng int level = 1; 666525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 666625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp < readendp) 666725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 666825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int opcode = *readp++; 666925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int u128; 667025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int u128_2; 667125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *endp; 667225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 667325b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (opcode) 667425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 667525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_MACINFO_define: 667625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_MACINFO_undef: 667725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_MACINFO_vendor_ext: 667825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* For the first two opcodes the parameters are 667925b3c049e70834cf33790a28643ab058b507b35cBen Cheng line, string 668025b3c049e70834cf33790a28643ab058b507b35cBen Cheng For the latter 668125b3c049e70834cf33790a28643ab058b507b35cBen Cheng number, string. 668225b3c049e70834cf33790a28643ab058b507b35cBen Cheng We can treat these cases together. */ 668325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128, readp); 668425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 668525b3c049e70834cf33790a28643ab058b507b35cBen Cheng endp = memchr (readp, '\0', readendp - readp); 668625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (endp == NULL)) 668725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 668825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 668925b3c049e70834cf33790a28643ab058b507b35cBen Cheng%*s*** non-terminated string at end of section"), 669025b3c049e70834cf33790a28643ab058b507b35cBen Cheng level, ""); 669125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 669225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 669325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 669425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (opcode == DW_MACINFO_define) 669525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s#define %s, line %u\n", 669625b3c049e70834cf33790a28643ab058b507b35cBen Cheng level, "", (char *) readp, u128); 669725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (opcode == DW_MACINFO_undef) 669825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s#undef %s, line %u\n", 669925b3c049e70834cf33790a28643ab058b507b35cBen Cheng level, "", (char *) readp, u128); 670025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 670125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" #vendor-ext %s, number %u\n", (char *) readp, u128); 670225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 670325b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = endp + 1; 670425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 670525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 670625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_MACINFO_start_file: 670725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The two parameters are line and file index, in this order. */ 670825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128, readp); 670925b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (u128_2, readp); 671025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 671125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the CU DIE for this file. */ 671225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t macoff = readp - (const unsigned char *) data->d_buf; 671325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *fname = "???"; 671425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (macoff >= cus[0].offset) 671525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 671625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (macoff >= cus[1].offset) 671725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++cus; 671825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 671925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cus[0].files == NULL 672025b3c049e70834cf33790a28643ab058b507b35cBen Cheng && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0) 672125b3c049e70834cf33790a28643ab058b507b35cBen Cheng cus[0].files = (Dwarf_Files *) -1l; 672225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 672325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cus[0].files != (Dwarf_Files *) -1l) 672425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL) 672525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ?: "???"); 672625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 672725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 672825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*sstart_file %u, [%u] %s\n", 672925b3c049e70834cf33790a28643ab058b507b35cBen Cheng level, "", u128, u128_2, fname); 673025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++level; 673125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 673225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 673325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_MACINFO_end_file: 673425b3c049e70834cf33790a28643ab058b507b35cBen Cheng --level; 673525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*send_file\n", level, ""); 673625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Nothing more to do. */ 673725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 673825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 673925b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 674025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX gcc seems to generate files with a trailing zero. 674125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (opcode != 0 || readp != readendp)) 674225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s*** invalid opcode %u\n", level, "", opcode); 674325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 674425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 674525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 674625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 674725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 674825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 674925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Callback for printing global names. */ 675025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 675125b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global, 675225b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *arg) 675325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 675425b3c049e70834cf33790a28643ab058b507b35cBen Cheng int *np = (int *) arg; 675525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 675625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%5d] DIE offset: %6" PRId64 675725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", CU DIE offset: %6" PRId64 ", name: %s\n"), 675825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (*np)++, global->die_offset, global->cu_offset, global->name); 675925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 676025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 676125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 676225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 676325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 676425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the known exported symbols in the DWARF section '.debug_pubnames'. */ 676525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 676625b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 676725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl, GElf_Ehdr *ehdr, 676825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 676925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 677025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 677125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 677225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset); 677325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 677425b3c049e70834cf33790a28643ab058b507b35cBen Cheng int n = 0; 677525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0); 677625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 677725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 677825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the content of the DWARF string section '.debug_str'. */ 677925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 678025b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 678125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl, GElf_Ehdr *ehdr, 678225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 678325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 678425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const size_t sh_size = dbg->sectiondata[IDX_debug_str]->d_size; 678525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 678625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute floor(log16(shdr->sh_size)). */ 678725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Addr tmp = sh_size; 678825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int digits = 1; 678925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (tmp >= 16) 679025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 679125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++digits; 679225b3c049e70834cf33790a28643ab058b507b35cBen Cheng tmp >>= 4; 679325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 679425b3c049e70834cf33790a28643ab058b507b35cBen Cheng digits = MAX (4, digits); 679525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 679625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n" 679725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " %*s String\n"), 679825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), 679925b3c049e70834cf33790a28643ab058b507b35cBen Cheng section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset, 680025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* TRANS: the debugstr| prefix makes the string unique. */ 680125b3c049e70834cf33790a28643ab058b507b35cBen Cheng digits + 2, sgettext ("debugstr|Offset")); 680225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 680325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Off offset = 0; 680425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (offset < sh_size) 680525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 680625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len; 680725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *str = dwarf_getstring (dbg, offset, &len); 680825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (str == NULL)) 680925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 681025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" *** error while reading strings: %s\n"), 681125b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwarf_errmsg (-1)); 681225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 681325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 681425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 681525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str); 681625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 681725b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += len + 1; 681825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 681925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 682025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 682125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 682225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the content of the call frame search table section 682325b3c049e70834cf33790a28643ab058b507b35cBen Cheng '.eh_frame_hdr'. */ 682425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 682525b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 682625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl __attribute__ ((unused)), 682725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 682825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 682925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 683025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 683125b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nCall frame search table section [%2zu] '.eh_frame_hdr':\n"), 683225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn)); 683325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 683425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 683525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 683625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 683725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 683825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get %s content: %s"), 683925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ".eh_frame_hdr", elf_errmsg (-1)); 684025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 684125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 684225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 684325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *readp = data->d_buf; 684425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const dataend = ((unsigned char *) data->d_buf 684525b3c049e70834cf33790a28643ab058b507b35cBen Cheng + data->d_size); 684625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 684725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 4 > dataend)) 684825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 684925b3c049e70834cf33790a28643ab058b507b35cBen Cheng invalid_data: 685025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("invalid data")); 685125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 685225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 685325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 685425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int version = *readp++; 685525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int eh_frame_ptr_enc = *readp++; 685625b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int fde_count_enc = *readp++; 685725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int table_enc = *readp++; 685825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 685925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" version: %u\n" 686025b3c049e70834cf33790a28643ab058b507b35cBen Cheng " eh_frame_ptr_enc: %#x ", 686125b3c049e70834cf33790a28643ab058b507b35cBen Cheng version, eh_frame_ptr_enc); 686225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding_base ("", eh_frame_ptr_enc); 686325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" fde_count_enc: %#x ", fde_count_enc); 686425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding_base ("", fde_count_enc); 686525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" table_enc: %#x ", table_enc); 686625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding_base ("", table_enc); 686725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 686825b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t eh_frame_ptr = 0; 686925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (eh_frame_ptr_enc != DW_EH_PE_omit) 687025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 687125b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr, 687225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dbg); 687325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp == NULL)) 687425b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 687525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 687625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr); 687725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel) 687825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" (offset: %#" PRIx64 ")", 687925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* +4 because of the 4 byte header of the section. */ 688025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr); 688125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 688225b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked ('\n'); 688325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 688425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 688525b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t fde_count = 0; 688625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fde_count_enc != DW_EH_PE_omit) 688725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 688825b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg); 688925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp == NULL)) 689025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 689125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 689225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" fde_count: %" PRIu64 "\n", fde_count); 689325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 689425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 689525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fde_count == 0 || table_enc == DW_EH_PE_omit) 689625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 689725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 689825b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (" Table:"); 689925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 690025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Optimize for the most common case. */ 690125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4)) 690225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (fde_count > 0 && readp + 8 <= dataend) 690325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 690425b3c049e70834cf33790a28643ab058b507b35cBen Cheng int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp); 690525b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t initial_offset = ((uint64_t) shdr->sh_offset 690625b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (int64_t) initial_location); 690725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int32_t address = read_4sbyte_unaligned_inc (dbg, readp); 690825b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Possibly print symbol name or section offset for initial_offset 690925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32 691025b3c049e70834cf33790a28643ab058b507b35cBen Cheng " fde=[%6" PRIx64 "]\n", 691125b3c049e70834cf33790a28643ab058b507b35cBen Cheng initial_location, initial_offset, 691225b3c049e70834cf33790a28643ab058b507b35cBen Cheng address, address - (eh_frame_ptr + 4)); 691325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 691425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 691525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (0 && readp < dataend) 691625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 691725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 691825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 691925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 692025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 692125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 692225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the content of the exception handling table section 692325b3c049e70834cf33790a28643ab058b507b35cBen Cheng '.eh_frame_hdr'. */ 692425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 692525b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), 692625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Ebl *ebl __attribute__ ((unused)), 692725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 692825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, 692925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr __attribute__ ((unused)), 693025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf *dbg __attribute__ ((unused))) 693125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 693225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 693325b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nException handling table section [%2zu] '.gcc_except_table':\n"), 693425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn)); 693525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 693625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 693725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 693825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 693925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 694025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get %s content: %s"), 694125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ".gcc_except_table", elf_errmsg (-1)); 694225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 694325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 694425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 694525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *readp = data->d_buf; 694625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const dataend = readp + data->d_size; 694725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 694825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 1 > dataend)) 694925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 695025b3c049e70834cf33790a28643ab058b507b35cBen Cheng invalid_data: 695125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("invalid data")); 695225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 695325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 695425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int lpstart_encoding = *readp++; 695525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" LPStart encoding: %#x "), lpstart_encoding); 695625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding_base ("", lpstart_encoding); 695725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (lpstart_encoding != DW_EH_PE_omit) 695825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 695925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t lpstart; 696025b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg); 696125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" LPStart: %#" PRIx64 "\n", lpstart); 696225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 696325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 696425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 1 > dataend)) 696525b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 696625b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int ttype_encoding = *readp++; 696725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" TType encoding: %#x "), ttype_encoding); 696825b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding_base ("", ttype_encoding); 696925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *ttype_base = NULL; 697025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ttype_encoding != DW_EH_PE_omit) 697125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 697225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int ttype_base_offset; 697325b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (ttype_base_offset, readp); 697425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" TType base offset: %#x\n", ttype_base_offset); 697525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ttype_base = readp + ttype_base_offset; 697625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 697725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 697825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 1 > dataend)) 697925b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 698025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int call_site_encoding = *readp++; 698125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Call site encoding: %#x "), call_site_encoding); 698225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_encoding_base ("", call_site_encoding); 698325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int call_site_table_len; 698425b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (call_site_table_len, readp); 698525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 698625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const action_table = readp + call_site_table_len; 698725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (action_table > dataend)) 698825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 698925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int u = 0; 699025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int max_action = 0; 699125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp < action_table) 699225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 699325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (u == 0) 699425b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (gettext ("\n Call site table:")); 699525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 699625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t call_site_start; 699725b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = read_encoded (call_site_encoding, readp, dataend, 699825b3c049e70834cf33790a28643ab058b507b35cBen Cheng &call_site_start, dbg); 699925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t call_site_length; 700025b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = read_encoded (call_site_encoding, readp, dataend, 700125b3c049e70834cf33790a28643ab058b507b35cBen Cheng &call_site_length, dbg); 700225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t landing_pad; 700325b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = read_encoded (call_site_encoding, readp, dataend, 700425b3c049e70834cf33790a28643ab058b507b35cBen Cheng &landing_pad, dbg); 700525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int action; 700625b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_uleb128 (action, readp); 700725b3c049e70834cf33790a28643ab058b507b35cBen Cheng max_action = MAX (action, max_action); 700825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n" 700925b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Call site length: %" PRIu64 "\n" 701025b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Landing pad: %#" PRIx64 "\n" 701125b3c049e70834cf33790a28643ab058b507b35cBen Cheng " Action: %u\n"), 701225b3c049e70834cf33790a28643ab058b507b35cBen Cheng u++, call_site_start, call_site_length, landing_pad, action); 701325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 701425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (readp == action_table); 701525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 701625b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int max_ar_filter = 0; 701725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (max_action > 0) 701825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 701925b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts ("\n Action table:"); 702025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 702125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const action_table_end 702225b3c049e70834cf33790a28643ab058b507b35cBen Cheng = action_table + max_action + 1; 702325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 702425b3c049e70834cf33790a28643ab058b507b35cBen Cheng u = 0; 702525b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 702625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 702725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int ar_filter; 702825b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (ar_filter, readp); 702925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter) 703025b3c049e70834cf33790a28643ab058b507b35cBen Cheng max_ar_filter = ar_filter; 703125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int ar_disp; 703225b3c049e70834cf33790a28643ab058b507b35cBen Cheng get_sleb128 (ar_disp, readp); 703325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 703425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%4u] ar_filter: % d\n" 703525b3c049e70834cf33790a28643ab058b507b35cBen Cheng " ar_disp: % -5d", 703625b3c049e70834cf33790a28643ab058b507b35cBen Cheng u, ar_filter, ar_disp); 703725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (abs (ar_disp) & 1) 703825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" -> [%4u]\n", u + (ar_disp + 1) / 2); 703925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (ar_disp != 0) 704025b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (" -> ???"); 704125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 704225b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked ('\n'); 704325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++u; 704425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 704525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp < action_table_end); 704625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 704725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 704825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (max_ar_filter > 0) 704925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 705025b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts ("\n TType table:"); 705125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 705225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Not *4, size of encoding; 705325b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (ttype_encoding & 7) 705425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 705525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata2: 705625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata2: 705725b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = ttype_base - max_ar_filter * 2; 705825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 705925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata4: 706025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata4: 706125b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = ttype_base - max_ar_filter * 4; 706225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 706325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_udata8: 706425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_EH_PE_sdata8: 706525b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = ttype_base - max_ar_filter * 8; 706625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 706725b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 706825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (1, 0, gettext ("invalid TType encoding")); 706925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 707025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 707125b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 707225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 707325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t ttype; 707425b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype, 707525b3c049e70834cf33790a28643ab058b507b35cBen Cheng dbg); 707625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype); 707725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 707825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp < ttype_base); 707925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 708025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 708125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 708225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the content of the '.gdb_index' section. 708325b3c049e70834cf33790a28643ab058b507b35cBen Cheng http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html 708425b3c049e70834cf33790a28643ab058b507b35cBen Cheng*/ 708525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 708625b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 708725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 708825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 708925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64 709025b3c049e70834cf33790a28643ab058b507b35cBen Cheng " contains %" PRId64 " bytes :\n"), 709125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 709225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size); 709325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 709425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 709525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 709625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (data == NULL)) 709725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 709825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get %s content: %s"), 709925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ".gdb_index", elf_errmsg (-1)); 710025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 710125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 710225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 710325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // .gdb_index is always in little endian. 710425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB }; 710525b3c049e70834cf33790a28643ab058b507b35cBen Cheng dbg = &dummy_dbg; 710625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 710725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *readp = data->d_buf; 710825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *const dataend = readp + data->d_size; 710925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 711025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 4 > dataend)) 711125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 711225b3c049e70834cf33790a28643ab058b507b35cBen Cheng invalid_data: 711325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("invalid data")); 711425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 711525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 711625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 711725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int32_t vers = read_4ubyte_unaligned (dbg, readp); 711825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" Version: %" PRId32 "\n"), vers); 711925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 712025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // The only difference between version 4 and version 5 is the 712125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // hash used for generating the table. 712225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (vers < 4 || vers > 5) 712325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 712425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" unknown version, cannot parse section\n")); 712525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 712625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 712725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 712825b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 4; 712925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 4 > dataend)) 713025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 713125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 713225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t cu_off = read_4ubyte_unaligned (dbg, readp); 713325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off); 713425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 713525b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 4; 713625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 4 > dataend)) 713725b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 713825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 713925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t tu_off = read_4ubyte_unaligned (dbg, readp); 714025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off); 714125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 714225b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 4; 714325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 4 > dataend)) 714425b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 714525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 714625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t addr_off = read_4ubyte_unaligned (dbg, readp); 714725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off); 714825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 714925b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 4; 715025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 4 > dataend)) 715125b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 715225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 715325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t sym_off = read_4ubyte_unaligned (dbg, readp); 715425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off); 715525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 715625b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 4; 715725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readp + 4 > dataend)) 715825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 715925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 716025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t const_off = read_4ubyte_unaligned (dbg, readp); 716125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off); 716225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 716325b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = data->d_buf + cu_off; 716425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 716525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *nextp = data->d_buf + tu_off; 716625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nr = (nextp - readp) / 16; 716725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 716825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\n CU list at offset %#" PRIx32 716925b3c049e70834cf33790a28643ab058b507b35cBen Cheng " contains %zu entries:\n"), 717025b3c049e70834cf33790a28643ab058b507b35cBen Cheng cu_off, nr); 717125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 717225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t n = 0; 717325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp + 16 <= dataend && n < nr) 717425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 717525b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t off = read_8ubyte_unaligned (dbg, readp); 717625b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 8; 717725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 717825b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t len = read_8ubyte_unaligned (dbg, readp); 717925b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 8; 718025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 718125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%4zu] start: %0#8" PRIx64 718225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", length: %5" PRIu64 "\n", n, off, len); 718325b3c049e70834cf33790a28643ab058b507b35cBen Cheng n++; 718425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 718525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 718625b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = data->d_buf + tu_off; 718725b3c049e70834cf33790a28643ab058b507b35cBen Cheng nextp = data->d_buf + addr_off; 718825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nr = (nextp - readp) / 24; 718925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 719025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\n TU list at offset %#" PRIx32 719125b3c049e70834cf33790a28643ab058b507b35cBen Cheng " contains %zu entries:\n"), 719225b3c049e70834cf33790a28643ab058b507b35cBen Cheng tu_off, nr); 719325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 719425b3c049e70834cf33790a28643ab058b507b35cBen Cheng n = 0; 719525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp + 24 <= dataend && n < nr) 719625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 719725b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t off = read_8ubyte_unaligned (dbg, readp); 719825b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 8; 719925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 720025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t type = read_8ubyte_unaligned (dbg, readp); 720125b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 8; 720225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 720325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t sig = read_8ubyte_unaligned (dbg, readp); 720425b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 8; 720525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 720625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%4zu] CU offset: %5" PRId64 720725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", type offset: %5" PRId64 720825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ", signature: %0#8" PRIx64 "\n", n, off, type, sig); 720925b3c049e70834cf33790a28643ab058b507b35cBen Cheng n++; 721025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 721125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 721225b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = data->d_buf + addr_off; 721325b3c049e70834cf33790a28643ab058b507b35cBen Cheng nextp = data->d_buf + sym_off; 721425b3c049e70834cf33790a28643ab058b507b35cBen Cheng nr = (nextp - readp) / 20; 721525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 721625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\n Address list at offset %#" PRIx32 721725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " contains %zu entries:\n"), 721825b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr_off, nr); 721925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 722025b3c049e70834cf33790a28643ab058b507b35cBen Cheng n = 0; 722125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp + 20 <= dataend && n < nr) 722225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 722325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t low = read_8ubyte_unaligned (dbg, readp); 722425b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 8; 722525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 722625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t high = read_8ubyte_unaligned (dbg, readp); 722725b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 8; 722825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 722925b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t idx = read_4ubyte_unaligned (dbg, readp); 723025b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 4; 723125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 723225b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *l = format_dwarf_addr (dwflmod, 8, low); 723325b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *h = format_dwarf_addr (dwflmod, 8, high - 1); 723425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n", 723525b3c049e70834cf33790a28643ab058b507b35cBen Cheng n, l, h, idx); 723625b3c049e70834cf33790a28643ab058b507b35cBen Cheng n++; 723725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 723825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 723925b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp = data->d_buf + sym_off; 724025b3c049e70834cf33790a28643ab058b507b35cBen Cheng nextp = data->d_buf + const_off; 724125b3c049e70834cf33790a28643ab058b507b35cBen Cheng nr = (nextp - readp) / 8; 724225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 724325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\n Symbol table at offset %#" PRIx32 724425b3c049e70834cf33790a28643ab058b507b35cBen Cheng " contains %zu slots:\n"), 724525b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr_off, nr); 724625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 724725b3c049e70834cf33790a28643ab058b507b35cBen Cheng n = 0; 724825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (readp + 8 <= dataend && n < nr) 724925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 725025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t name = read_4ubyte_unaligned (dbg, readp); 725125b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 4; 725225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 725325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t vector = read_4ubyte_unaligned (dbg, readp); 725425b3c049e70834cf33790a28643ab058b507b35cBen Cheng readp += 4; 725525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 725625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name != 0 || vector != 0) 725725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 725825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *sym = data->d_buf + const_off + name; 725925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (sym > dataend)) 726025b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 726125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 726225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%4zu] symbol: %s, CUs: ", n, sym); 726325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 726425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *readcus = data->d_buf + const_off + vector; 726525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (readcus + 8 > dataend)) 726625b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto invalid_data; 726725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 726825b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t cus = read_4ubyte_unaligned (dbg, readcus); 726925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (cus--) 727025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 727125b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t cu; 727225b3c049e70834cf33790a28643ab058b507b35cBen Cheng readcus += 4; 727325b3c049e70834cf33790a28643ab058b507b35cBen Cheng cu = read_4ubyte_unaligned (dbg, readcus); 727425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%" PRId32 "%s", cu, ((cus > 0) ? ", " : "")); 727525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 727625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\n"); 727725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 727825b3c049e70834cf33790a28643ab058b507b35cBen Cheng n++; 727925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 728025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 728125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 728225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 728325b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr) 728425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 728525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Before we start the real work get a debug context descriptor. */ 728625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr dwbias; 728725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias); 728825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf dummy_dbg = 728925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 729025b3c049e70834cf33790a28643ab058b507b35cBen Cheng .elf = ebl->elf, 729125b3c049e70834cf33790a28643ab058b507b35cBen Cheng .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA] 729225b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 729325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dbg == NULL) 729425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 729525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((print_debug_sections & ~section_exception) != 0) 729625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get debug context descriptor: %s"), 729725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dwfl_errmsg (-1)); 729825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((print_debug_sections & section_exception) == 0) 729925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 730025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dbg = &dummy_dbg; 730125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 730225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 730325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 730425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 730525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 730625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 730725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 730825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 730925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Look through all the sections for the debugging sections to print. */ 731025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 731125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 731225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 731325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 731425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 731525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 731625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL && shdr->sh_type == SHT_PROGBITS) 731725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 731825b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const struct 731925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 732025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name; 732125b3c049e70834cf33790a28643ab058b507b35cBen Cheng enum section_e bitmask; 732225b3c049e70834cf33790a28643ab058b507b35cBen Cheng void (*fp) (Dwfl_Module *, Ebl *, 732325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *); 732425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } debug_sections[] = 732525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 732625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define NEW_SECTION(name) \ 732725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { ".debug_" #name, section_##name, print_debug_##name##_section } 732825b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (abbrev), 732925b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (aranges), 733025b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (frame), 733125b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (info), 733225b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (types), 733325b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (line), 733425b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (loc), 733525b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (pubnames), 733625b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (str), 733725b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (macinfo), 733825b3c049e70834cf33790a28643ab058b507b35cBen Cheng NEW_SECTION (ranges), 733925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { ".eh_frame", section_frame | section_exception, 734025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_frame_section }, 734125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { ".eh_frame_hdr", section_frame | section_exception, 734225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_frame_hdr_section }, 734325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { ".gcc_except_table", section_frame | section_exception, 734425b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_debug_exception_table }, 734525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { ".gdb_index", section_gdb_index, print_gdb_index_section } 734625b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 734725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const int ndebug_sections = (sizeof (debug_sections) 734825b3c049e70834cf33790a28643ab058b507b35cBen Cheng / sizeof (debug_sections[0])); 734925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = elf_strptr (ebl->elf, shstrndx, 735025b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name); 735125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int n; 735225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 735325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (n = 0; n < ndebug_sections; ++n) 735425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (name, debug_sections[n].name) == 0 735525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if USE_ZLIB 735625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (name[0] == '.' && name[1] == 'z' 735725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && debug_sections[n].name[1] == 'd' 735825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && strcmp (&name[2], &debug_sections[n].name[1]) == 0) 735925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 736025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ) 736125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 736225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((print_debug_sections | implicit_debug_sections) 736325b3c049e70834cf33790a28643ab058b507b35cBen Cheng & debug_sections[n].bitmask) 736425b3c049e70834cf33790a28643ab058b507b35cBen Cheng debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg); 736525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 736625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 736725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 736825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 736925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 737025b3c049e70834cf33790a28643ab058b507b35cBen Cheng reset_listptr (&known_loclistptr); 737125b3c049e70834cf33790a28643ab058b507b35cBen Cheng reset_listptr (&known_rangelistptr); 737225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 737325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 737425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 737525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define ITEM_INDENT 4 737625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define ITEM_WRAP_COLUMN 150 737725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define REGISTER_WRAP_COLUMN 75 737825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 737925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print "NAME: FORMAT", wrapping when FORMAT_MAX chars of FORMAT would 738025b3c049e70834cf33790a28643ab058b507b35cBen Cheng make the line exceed ITEM_WRAP_COLUMN. Unpadded numbers look better 738125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for the core items. But we do not want the line breaks to depend on 738225b3c049e70834cf33790a28643ab058b507b35cBen Cheng the particular values. */ 738325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 738425b3c049e70834cf33790a28643ab058b507b35cBen Cheng__attribute__ ((format (printf, 7, 8))) 738525b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_core_item (unsigned int colno, char sep, unsigned int wrap, 738625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t name_width, const char *name, 738725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t format_max, const char *format, ...) 738825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 738925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len = strlen (name); 739025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name_width < len) 739125b3c049e70834cf33790a28643ab058b507b35cBen Cheng name_width = len; 739225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 739325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t n = name_width + sizeof ": " - 1 + format_max; 739425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 739525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (colno == 0) 739625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 739725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s", ITEM_INDENT, ""); 739825b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = ITEM_INDENT + n; 739925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 740025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (colno + 2 + n < wrap) 740125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 740225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%c ", sep); 740325b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno += 2 + n; 740425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 740525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 740625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 740725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\n%*s", ITEM_INDENT, ""); 740825b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = ITEM_INDENT + n; 740925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 741025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 741125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%s: %*s", name, (int) (name_width - len), ""); 741225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 741325b3c049e70834cf33790a28643ab058b507b35cBen Cheng va_list ap; 741425b3c049e70834cf33790a28643ab058b507b35cBen Cheng va_start (ap, format); 741525b3c049e70834cf33790a28643ab058b507b35cBen Cheng vprintf (format, ap); 741625b3c049e70834cf33790a28643ab058b507b35cBen Cheng va_end (ap); 741725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 741825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return colno; 741925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 742025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 742125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const void * 742225b3c049e70834cf33790a28643ab058b507b35cBen Chengconvert (Elf *core, Elf_Type type, uint_fast16_t count, 742325b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *value, const void *data, size_t size) 742425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 742525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data valuedata = 742625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 742725b3c049e70834cf33790a28643ab058b507b35cBen Cheng .d_type = type, 742825b3c049e70834cf33790a28643ab058b507b35cBen Cheng .d_buf = value, 742925b3c049e70834cf33790a28643ab058b507b35cBen Cheng .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT), 743025b3c049e70834cf33790a28643ab058b507b35cBen Cheng .d_version = EV_CURRENT, 743125b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 743225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data indata = 743325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 743425b3c049e70834cf33790a28643ab058b507b35cBen Cheng .d_type = type, 743525b3c049e70834cf33790a28643ab058b507b35cBen Cheng .d_buf = (void *) data, 743625b3c049e70834cf33790a28643ab058b507b35cBen Cheng .d_size = valuedata.d_size, 743725b3c049e70834cf33790a28643ab058b507b35cBen Cheng .d_version = EV_CURRENT, 743825b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 743925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 744025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *d = (gelf_getclass (core) == ELFCLASS32 744125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? elf32_xlatetom : elf64_xlatetom) 744225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]); 744325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (d == NULL) 744425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 744525b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot convert core note data: %s"), elf_errmsg (-1)); 744625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 744725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return data + indata.d_size; 744825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 744925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 745025b3c049e70834cf33790a28643ab058b507b35cBen Chengtypedef uint8_t GElf_Byte; 745125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 745225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 745325b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, 745425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int colno, size_t *repeated_size) 745525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 745625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint_fast16_t count = item->count ?: 1; 745725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 745825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define TYPES \ 745925b3c049e70834cf33790a28643ab058b507b35cBen Cheng DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8, 4); \ 746025b3c049e70834cf33790a28643ab058b507b35cBen Cheng DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16, 6); \ 746125b3c049e70834cf33790a28643ab058b507b35cBen Cheng DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32, 11); \ 746225b3c049e70834cf33790a28643ab058b507b35cBen Cheng DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32, 11); \ 746325b3c049e70834cf33790a28643ab058b507b35cBen Cheng DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64, 20); \ 746425b3c049e70834cf33790a28643ab058b507b35cBen Cheng DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64, 20) 746525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 746625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define DO_TYPE(NAME, Name, hex, dec, max) GElf_##Name Name[count] 746725b3c049e70834cf33790a28643ab058b507b35cBen Cheng union { TYPES; } value; 746825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef DO_TYPE 746925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 747025b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *data = &value; 747125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t size = gelf_fsize (core, item->type, count, EV_CURRENT); 747225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t convsize = size; 747325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (repeated_size != NULL) 747425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 747525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (*repeated_size > size && (item->format == 'b' || item->format == 'B')) 747625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 747725b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = alloca (*repeated_size); 747825b3c049e70834cf33790a28643ab058b507b35cBen Cheng count *= *repeated_size / size; 747925b3c049e70834cf33790a28643ab058b507b35cBen Cheng convsize = count * size; 748025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *repeated_size -= convsize; 748125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 748225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (item->count != 0 || item->format != '\n') 748325b3c049e70834cf33790a28643ab058b507b35cBen Cheng *repeated_size -= size; 748425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 748525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 748625b3c049e70834cf33790a28643ab058b507b35cBen Cheng convert (core, item->type, count, data, desc + item->offset, convsize); 748725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 748825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Type type = item->type; 748925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (type == ELF_T_ADDR) 749025b3c049e70834cf33790a28643ab058b507b35cBen Cheng type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD; 749125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 749225b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (item->format) 749325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 749425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'd': 749525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (count == 1); 749625b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (type) 749725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 749825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define DO_TYPE(NAME, Name, hex, dec, max) \ 749925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case ELF_T_##NAME: \ 750025b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, \ 750125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 0, item->name, max, dec, value.Name[0]); \ 750225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break 750325b3c049e70834cf33790a28643ab058b507b35cBen Cheng TYPES; 750425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef DO_TYPE 750525b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 750625b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 750725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 750825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 750925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 751025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'x': 751125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (count == 1); 751225b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (type) 751325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 751425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define DO_TYPE(NAME, Name, hex, dec, max) \ 751525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case ELF_T_##NAME: \ 751625b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, \ 751725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 0, item->name, max, hex, value.Name[0]); \ 751825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break 751925b3c049e70834cf33790a28643ab058b507b35cBen Cheng TYPES; 752025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef DO_TYPE 752125b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 752225b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 752325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 752425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 752525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 752625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'b': 752725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'B': 752825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (size % sizeof (unsigned int) == 0); 752925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int nbits = count * size * 8; 753025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int pop = 0; 753125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (const unsigned int *i = data; (void *) i < data + count * size; ++i) 753225b3c049e70834cf33790a28643ab058b507b35cBen Cheng pop += __builtin_popcount (*i); 753325b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool negate = pop > nbits / 2; 753425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned int bias = item->format == 'b'; 753525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 753625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 753725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char printed[(negate ? nbits - pop : pop) * 16]; 753825b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *p = printed; 753925b3c049e70834cf33790a28643ab058b507b35cBen Cheng *p = '\0'; 754025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 754125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int)) 754225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 754325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (size == sizeof (unsigned int) * 2); 754425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (unsigned int *i = data; 754525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void *) i < data + count * size; i += 2) 754625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 754725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int w = i[1]; 754825b3c049e70834cf33790a28643ab058b507b35cBen Cheng i[1] = i[0]; 754925b3c049e70834cf33790a28643ab058b507b35cBen Cheng i[0] = w; 755025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 755125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 755225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 755325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int lastbit = 0; 755425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (const unsigned int *i = data; 755525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void *) i < data + count * size; ++i) 755625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 755725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int bit = ((void *) i - data) * 8; 755825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int w = negate ? ~*i : *i; 755925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int run = 0; 756025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (w != 0) 756125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 756225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int n = ffs (w); 756325b3c049e70834cf33790a28643ab058b507b35cBen Cheng w >>= n; 756425b3c049e70834cf33790a28643ab058b507b35cBen Cheng bit += n; 756525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 756625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (lastbit + 1 == bit) 756725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++run; 756825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 756925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 757025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (lastbit == 0) 757125b3c049e70834cf33790a28643ab058b507b35cBen Cheng p += sprintf (p, "%u", bit - bias); 757225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (run == 0) 757325b3c049e70834cf33790a28643ab058b507b35cBen Cheng p += sprintf (p, ",%u", bit - bias); 757425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 757525b3c049e70834cf33790a28643ab058b507b35cBen Cheng p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias); 757625b3c049e70834cf33790a28643ab058b507b35cBen Cheng run = 0; 757725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 757825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 757925b3c049e70834cf33790a28643ab058b507b35cBen Cheng lastbit = bit; 758025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 758125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 758225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (lastbit > 0 && lastbit + 1 != nbits) 758325b3c049e70834cf33790a28643ab058b507b35cBen Cheng p += sprintf (p, "-%u", nbits - bias); 758425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 758525b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name, 758625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4 + nbits * 4, 758725b3c049e70834cf33790a28643ab058b507b35cBen Cheng negate ? "~<%s>" : "<%s>", printed); 758825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 758925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 759025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 759125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'T': 759225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case (char) ('T'|0x80): 759325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (count == 2); 759425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word sec; 759525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word usec; 759625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t maxfmt = 7; 759725b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (type) 759825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 759925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define DO_TYPE(NAME, Name, hex, dec, max) \ 760025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case ELF_T_##NAME: \ 760125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sec = value.Name[0]; \ 760225b3c049e70834cf33790a28643ab058b507b35cBen Cheng usec = value.Name[1]; \ 760325b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxfmt += max; \ 760425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break 760525b3c049e70834cf33790a28643ab058b507b35cBen Cheng TYPES; 760625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef DO_TYPE 760725b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 760825b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 760925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 761025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (item->format == (char) ('T'|0x80))) 761125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 761225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is a hack for an ill-considered 64-bit ABI where 761325b3c049e70834cf33790a28643ab058b507b35cBen Cheng tv_usec is actually a 32-bit field with 32 bits of padding 761425b3c049e70834cf33790a28643ab058b507b35cBen Cheng rounding out struct timeval. We've already converted it as 761525b3c049e70834cf33790a28643ab058b507b35cBen Cheng a 64-bit field. For little-endian, this just means the 761625b3c049e70834cf33790a28643ab058b507b35cBen Cheng high half is the padding; it's presumably zero, but should 761725b3c049e70834cf33790a28643ab058b507b35cBen Cheng be ignored anyway. For big-endian, it means the 32-bit 761825b3c049e70834cf33790a28643ab058b507b35cBen Cheng field went into the high half of USEC. */ 761925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr ehdr_mem; 762025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem); 762125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)) 762225b3c049e70834cf33790a28643ab058b507b35cBen Cheng usec >>= 32; 762325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 762425b3c049e70834cf33790a28643ab058b507b35cBen Cheng usec &= UINT32_MAX; 762525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 762625b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name, 762725b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxfmt, "%" PRIu64 ".%.6" PRIu64, sec, usec); 762825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 762925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 763025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'c': 763125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (count == 1); 763225b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name, 763325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1, "%c", value.Byte[0]); 763425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 763525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 763625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 's': 763725b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name, 763825b3c049e70834cf33790a28643ab058b507b35cBen Cheng count, "%.*s", (int) count, value.Byte); 763925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 764025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 764125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case '\n': 764225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is a list of strings separated by '\n'. */ 764325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (item->count == 0); 764425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (repeated_size != NULL); 764525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (item->name == NULL); 764625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (item->offset >= *repeated_size)) 764725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 764825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 764925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *s = desc + item->offset; 765025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size = *repeated_size - item->offset; 765125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *repeated_size = 0; 765225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (size > 0) 765325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 765425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *eol = memchr (s, '\n', size); 765525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int len = size; 765625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (eol != NULL) 765725b3c049e70834cf33790a28643ab058b507b35cBen Cheng len = eol - s; 765825b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s%.*s\n", ITEM_INDENT, "", len, s); 765925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (eol == NULL) 766025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 766125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size -= eol + 1 - s; 766225b3c049e70834cf33790a28643ab058b507b35cBen Cheng s = eol + 1; 766325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 766425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 766525b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = ITEM_WRAP_COLUMN; 766625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 766725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 766825b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 766925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, "XXX not handling format '%c' for %s", 767025b3c049e70834cf33790a28643ab058b507b35cBen Cheng item->format, item->name); 767125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 767225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 767325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 767425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef TYPES 767525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 767625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return colno; 767725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 767825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 767925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 768025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Sort items by group, and by layout offset within each group. */ 768125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 768225b3c049e70834cf33790a28643ab058b507b35cBen Chengcompare_core_items (const void *a, const void *b) 768325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 768425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *const *p1 = a; 768525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *const *p2 = b; 768625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *item1 = *p1; 768725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *item2 = *p2; 768825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 768925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ((item1->group == item2->group ? 0 769025b3c049e70834cf33790a28643ab058b507b35cBen Cheng : strcmp (item1->group, item2->group)) 769125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ?: (int) item1->offset - (int) item2->offset); 769225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 769325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 769425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Sort item groups by layout offset of the first item in the group. */ 769525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 769625b3c049e70834cf33790a28643ab058b507b35cBen Chengcompare_core_item_groups (const void *a, const void *b) 769725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 769825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *const *const *p1 = a; 769925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *const *const *p2 = b; 770025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *const *group1 = *p1; 770125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *const *group2 = *p2; 770225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *item1 = *group1; 770325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *item2 = *group2; 770425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 770525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return (int) item1->offset - (int) item2->offset; 770625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 770725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 770825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 770925b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_core_items (Elf *core, const void *desc, size_t descsz, 771025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *items, size_t nitems) 771125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 771225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (nitems == 0) 771325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 771425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 771525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Sort to collect the groups together. */ 771625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *sorted_items[nitems]; 771725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < nitems; ++i) 771825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sorted_items[i] = &items[i]; 771925b3c049e70834cf33790a28643ab058b507b35cBen Cheng qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items); 772025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 772125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Collect the unique groups and sort them. */ 772225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item **groups[nitems]; 772325b3c049e70834cf33790a28643ab058b507b35cBen Cheng groups[0] = &sorted_items[0]; 772425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t ngroups = 1; 772525b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 1; i < nitems; ++i) 772625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sorted_items[i]->group != sorted_items[i - 1]->group 772725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group)) 772825b3c049e70834cf33790a28643ab058b507b35cBen Cheng groups[ngroups++] = &sorted_items[i]; 772925b3c049e70834cf33790a28643ab058b507b35cBen Cheng qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups); 773025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 773125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Write out all the groups. */ 773225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int colno = 0; 773325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 773425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const void *last = desc; 773525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (nitems == 1) 773625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 773725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t size = descsz; 773825b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = handle_core_item (core, sorted_items[0], desc, colno, &size); 773925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (size == 0) 774025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return colno; 774125b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc += descsz - size; 774225b3c049e70834cf33790a28643ab058b507b35cBen Cheng descsz = size; 774325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 774425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 774525b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 774625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 774725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < ngroups; ++i) 774825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 774925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (const Ebl_Core_Item **item = groups[i]; 775025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (item < &sorted_items[nitems] 775125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && ((*item)->group == groups[i][0]->group 775225b3c049e70834cf33790a28643ab058b507b35cBen Cheng || !strcmp ((*item)->group, groups[i][0]->group))); 775325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++item) 775425b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = handle_core_item (core, *item, desc, colno, NULL); 775525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 775625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Force a line break at the end of the group. */ 775725b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = ITEM_WRAP_COLUMN; 775825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 775925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 776025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (descsz == 0) 776125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 776225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 776325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This set of items consumed a certain amount of the note's data. 776425b3c049e70834cf33790a28643ab058b507b35cBen Cheng If there is more data there, we have another unit of the same size. 776525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Loop to print that out too. */ 776625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *item = &items[nitems - 1]; 776725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t eltsz = item->offset + gelf_fsize (core, item->type, 776825b3c049e70834cf33790a28643ab058b507b35cBen Cheng item->count ?: 1, EV_CURRENT); 776925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 777025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int reps = -1; 777125b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 777225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 777325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++reps; 777425b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc += eltsz; 777525b3c049e70834cf33790a28643ab058b507b35cBen Cheng descsz -= eltsz; 777625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 777725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (descsz >= eltsz && !memcmp (desc, last, eltsz)); 777825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 777925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (reps == 1) 778025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 778125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* For just one repeat, print it unabridged twice. */ 778225b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc -= eltsz; 778325b3c049e70834cf33790a28643ab058b507b35cBen Cheng descsz += eltsz; 778425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 778525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (reps > 1) 778625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\n%*s... <repeats %u more times> ..."), 778725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ITEM_INDENT, "", reps); 778825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 778925b3c049e70834cf33790a28643ab058b507b35cBen Cheng last = desc; 779025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 779125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (descsz > 0); 779225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 779325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return colno; 779425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 779525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 779625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 779725b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_bit_registers (const Ebl_Register_Location *regloc, const void *desc, 779825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int colno) 779925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 780025b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc += regloc->offset; 780125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 780225b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); /* XXX */ 780325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return colno; 780425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 780525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 780625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 780725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 780825b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_core_register (Ebl *ebl, Elf *core, int maxregname, 780925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Register_Location *regloc, const void *desc, 781025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int colno) 781125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 781225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (regloc->bits % 8 != 0) 781325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return handle_bit_registers (regloc, desc, colno); 781425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 781525b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc += regloc->offset; 781625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 781725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg) 781825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 781925b3c049e70834cf33790a28643ab058b507b35cBen Cheng char name[REGNAMESZ]; 782025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int bits; 782125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int type; 782225b3c049e70834cf33790a28643ab058b507b35cBen Cheng register_info (ebl, reg, regloc, name, &bits, &type); 782325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 782425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define TYPES \ 782525b3c049e70834cf33790a28643ab058b507b35cBen Cheng BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8, 4); \ 782625b3c049e70834cf33790a28643ab058b507b35cBen Cheng BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16, 6); \ 782725b3c049e70834cf33790a28643ab058b507b35cBen Cheng BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32, 11); \ 782825b3c049e70834cf33790a28643ab058b507b35cBen Cheng BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64, 20) 782925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 783025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define BITS(bits, xtype, sfmt, ufmt, max) \ 783125b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint##bits##_t b##bits; int##bits##_t b##bits##s 783225b3c049e70834cf33790a28643ab058b507b35cBen Cheng union { TYPES; uint64_t b128[2]; } value; 783325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef BITS 783425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 783525b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (type) 783625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 783725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_ATE_unsigned: 783825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_ATE_signed: 783925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_ATE_address: 784025b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (bits) 784125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 784225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define BITS(bits, xtype, sfmt, ufmt, max) \ 784325b3c049e70834cf33790a28643ab058b507b35cBen Cheng case bits: \ 784425b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \ 784525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (type == DW_ATE_signed) \ 784625b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, \ 784725b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxregname, name, \ 784825b3c049e70834cf33790a28643ab058b507b35cBen Cheng max, sfmt, value.b##bits##s); \ 784925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else \ 785025b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, \ 785125b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxregname, name, \ 785225b3c049e70834cf33790a28643ab058b507b35cBen Cheng max, ufmt, value.b##bits); \ 785325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break 785425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 785525b3c049e70834cf33790a28643ab058b507b35cBen Cheng TYPES; 785625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 785725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 128: 785825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (type == DW_ATE_unsigned); 785925b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0); 786025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB; 786125b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, 786225b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxregname, name, 786325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 34, "0x%.16" PRIx64 "%.16" PRIx64, 786425b3c049e70834cf33790a28643ab058b507b35cBen Cheng value.b128[!be], value.b128[be]); 786525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 786625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 786725b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 786825b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 786925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef BITS 787025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 787125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 787225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 787325b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 787425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Print each byte in hex, the whole thing in native byte order. */ 787525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (bits % 8 == 0); 787625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const uint8_t *bytes = desc; 787725b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc += bits / 8; 787825b3c049e70834cf33790a28643ab058b507b35cBen Cheng char hex[bits / 4 + 1]; 787925b3c049e70834cf33790a28643ab058b507b35cBen Cheng hex[bits / 4] = '\0'; 788025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int incr = 1; 788125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB) 788225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 788325b3c049e70834cf33790a28643ab058b507b35cBen Cheng bytes += bits / 8 - 1; 788425b3c049e70834cf33790a28643ab058b507b35cBen Cheng incr = -1; 788525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 788625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t idx = 0; 788725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (char *h = hex; bits > 0; bits -= 8, idx += incr) 788825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 788925b3c049e70834cf33790a28643ab058b507b35cBen Cheng *h++ = "0123456789abcdef"[bytes[idx] >> 4]; 789025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *h++ = "0123456789abcdef"[bytes[idx] & 0xf]; 789125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 789225b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, 789325b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxregname, name, 789425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2 + sizeof hex - 1, "0x%s", hex); 789525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 789625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 789725b3c049e70834cf33790a28643ab058b507b35cBen Cheng desc += regloc->pad; 789825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 789925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#undef TYPES 790025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 790125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 790225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return colno; 790325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 790425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 790525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 790625b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct register_info 790725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 790825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Register_Location *regloc; 790925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *set; 791025b3c049e70834cf33790a28643ab058b507b35cBen Cheng char name[REGNAMESZ]; 791125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int regno; 791225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int bits; 791325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int type; 791425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 791525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 791625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 791725b3c049e70834cf33790a28643ab058b507b35cBen Chengregister_bitpos (const struct register_info *r) 791825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 791925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return (r->regloc->offset * 8 792025b3c049e70834cf33790a28643ab058b507b35cBen Cheng + ((r->regno - r->regloc->regno) 792125b3c049e70834cf33790a28643ab058b507b35cBen Cheng * (r->regloc->bits + r->regloc->pad * 8))); 792225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 792325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 792425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 792525b3c049e70834cf33790a28643ab058b507b35cBen Chengcompare_sets_by_info (const struct register_info *r1, 792625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct register_info *r2) 792725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 792825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ((int) r2->bits - (int) r1->bits 792925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ?: register_bitpos (r1) - register_bitpos (r2)); 793025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 793125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 793225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Sort registers by set, and by size and layout offset within each set. */ 793325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 793425b3c049e70834cf33790a28643ab058b507b35cBen Chengcompare_registers (const void *a, const void *b) 793525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 793625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct register_info *r1 = a; 793725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct register_info *r2 = b; 793825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 793925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Unused elements sort last. */ 794025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (r1->regloc == NULL) 794125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return r2->regloc == NULL ? 0 : 1; 794225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (r2->regloc == NULL) 794325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return -1; 794425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 794525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set)) 794625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ?: compare_sets_by_info (r1, r2)); 794725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 794825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 794925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Sort register sets by layout offset of the first register in the set. */ 795025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 795125b3c049e70834cf33790a28643ab058b507b35cBen Chengcompare_register_sets (const void *a, const void *b) 795225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 795325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct register_info *const *p1 = a; 795425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct register_info *const *p2 = b; 795525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return compare_sets_by_info (*p1, *p2); 795625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 795725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 795825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned int 795925b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_core_registers (Ebl *ebl, Elf *core, const void *desc, 796025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Register_Location *reglocs, size_t nregloc) 796125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 796225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (nregloc == 0) 796325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 796425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 796525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL); 796625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (maxnreg <= 0) 796725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 796825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < nregloc; ++i) 796925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (maxnreg < reglocs[i].regno + reglocs[i].count) 797025b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxnreg = reglocs[i].regno + reglocs[i].count; 797125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (maxnreg > 0); 797225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 797325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 797425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct register_info regs[maxnreg]; 797525b3c049e70834cf33790a28643ab058b507b35cBen Cheng memset (regs, 0, sizeof regs); 797625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 797725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Sort to collect the sets together. */ 797825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int maxreg = 0; 797925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < nregloc; ++i) 798025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int reg = reglocs[i].regno; 798125b3c049e70834cf33790a28643ab058b507b35cBen Cheng reg < reglocs[i].regno + reglocs[i].count; 798225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++reg) 798325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 798425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (reg < maxnreg); 798525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (reg > maxreg) 798625b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxreg = reg; 798725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct register_info *info = ®s[reg]; 798825b3c049e70834cf33790a28643ab058b507b35cBen Cheng info->regloc = ®locs[i]; 798925b3c049e70834cf33790a28643ab058b507b35cBen Cheng info->regno = reg; 799025b3c049e70834cf33790a28643ab058b507b35cBen Cheng info->set = register_info (ebl, reg, ®locs[i], 799125b3c049e70834cf33790a28643ab058b507b35cBen Cheng info->name, &info->bits, &info->type); 799225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 799325b3c049e70834cf33790a28643ab058b507b35cBen Cheng qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers); 799425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 799525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Collect the unique sets and sort them. */ 799625b3c049e70834cf33790a28643ab058b507b35cBen Cheng inline bool same_set (const struct register_info *a, 799725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct register_info *b) 799825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 799925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return (a < ®s[maxnreg] && a->regloc != NULL 800025b3c049e70834cf33790a28643ab058b507b35cBen Cheng && b < ®s[maxnreg] && b->regloc != NULL 800125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && a->bits == b->bits 800225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (a->set == b->set || !strcmp (a->set, b->set))); 800325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 800425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct register_info *sets[maxreg + 1]; 800525b3c049e70834cf33790a28643ab058b507b35cBen Cheng sets[0] = ®s[0]; 800625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsets = 1; 800725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int i = 1; i <= maxreg; ++i) 800825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1])) 800925b3c049e70834cf33790a28643ab058b507b35cBen Cheng sets[nsets++] = ®s[i]; 801025b3c049e70834cf33790a28643ab058b507b35cBen Cheng qsort (sets, nsets, sizeof sets[0], &compare_register_sets); 801125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 801225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Write out all the sets. */ 801325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int colno = 0; 801425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < nsets; ++i) 801525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 801625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the longest name of a register in this set. */ 801725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t maxname = 0; 801825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const struct register_info *end; 801925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (end = sets[i]; same_set (sets[i], end); ++end) 802025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 802125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len = strlen (end->name); 802225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (len > maxname) 802325b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxname = len; 802425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 802525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 802625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (const struct register_info *reg = sets[i]; 802725b3c049e70834cf33790a28643ab058b507b35cBen Cheng reg < end; 802825b3c049e70834cf33790a28643ab058b507b35cBen Cheng reg += reg->regloc->count ?: 1) 802925b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = handle_core_register (ebl, core, maxname, 803025b3c049e70834cf33790a28643ab058b507b35cBen Cheng reg->regloc, desc, colno); 803125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 803225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Force a line break at the end of the group. */ 803325b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = REGISTER_WRAP_COLUMN; 803425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 803525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 803625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return colno; 803725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 803825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 803925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 804025b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos) 804125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 804225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV); 804325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 804425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_error: 804525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 804625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot convert core note data: %s"), elf_errmsg (-1)); 804725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 804825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT); 804925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < nauxv; ++i) 805025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 805125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_auxv_t av_mem; 805225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem); 805325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (av == NULL) 805425b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto elf_error; 805525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 805625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name; 805725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *fmt; 805825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0) 805925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 806025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Unknown type. */ 806125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (av->a_un.a_val == 0) 806225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %" PRIu64 "\n", av->a_type); 806325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 806425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %" PRIu64 ": %#" PRIx64 "\n", 806525b3c049e70834cf33790a28643ab058b507b35cBen Cheng av->a_type, av->a_un.a_val); 806625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 806725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 806825b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (fmt[0]) 806925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 807025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case '\0': /* Normally zero. */ 807125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (av->a_un.a_val == 0) 807225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 807325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %s\n", name); 807425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 807525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 807625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fall through */ 807725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'x': /* hex */ 807825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'p': /* address */ 807925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 's': /* address of string */ 808025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val); 808125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 808225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'u': 808325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val); 808425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 808525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'd': 808625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %s: %" PRId64 "\n", name, av->a_un.a_val); 808725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 808825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 808925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'b': 809025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val); 809125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Xword bit = 1; 809225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *pfx = "<"; 809325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1) 809425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 809525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (av->a_un.a_val & bit) 809625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 809725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%s%s", pfx, p); 809825b3c049e70834cf33790a28643ab058b507b35cBen Cheng pfx = " "; 809925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 810025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bit <<= 1; 810125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 810225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (">\n"); 810325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 810425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 810525b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 810625b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 810725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 810825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 810925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 811025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 811125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 811225b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, 811325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name, const void *desc) 811425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 811525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Word regs_offset; 811625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nregloc; 811725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Register_Location *reglocs; 811825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nitems; 811925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Ebl_Core_Item *items; 812025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 812125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! ebl_core_note (ebl, nhdr, name, 812225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ®s_offset, &nregloc, ®locs, &nitems, &items)) 812325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 812425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 812525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Pass 0 for DESCSZ when there are registers in the note, 812625b3c049e70834cf33790a28643ab058b507b35cBen Cheng so that the ITEMS array does not describe the whole thing. 812725b3c049e70834cf33790a28643ab058b507b35cBen Cheng For non-register notes, the actual descsz might be a multiple 812825b3c049e70834cf33790a28643ab058b507b35cBen Cheng of the unit size, not just exactly the unit size. */ 812925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int colno = handle_core_items (ebl->elf, desc, 813025b3c049e70834cf33790a28643ab058b507b35cBen Cheng nregloc == 0 ? nhdr->n_descsz : 0, 813125b3c049e70834cf33790a28643ab058b507b35cBen Cheng items, nitems); 813225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (colno != 0) 813325b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked ('\n'); 813425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 813525b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset, 813625b3c049e70834cf33790a28643ab058b507b35cBen Cheng reglocs, nregloc); 813725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (colno != 0) 813825b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar_unlocked ('\n'); 813925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 814025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 814125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 814225b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr, 814325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Off start, Elf_Data *data) 814425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 814525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (gettext (" Owner Data size Type\n"), stdout); 814625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 814725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 814825b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto bad_note; 814925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 815025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t offset = 0; 815125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Nhdr nhdr; 815225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t name_offset; 815325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t desc_offset; 815425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (offset < data->d_size 815525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (offset = gelf_getnote (data, offset, 815625b3c049e70834cf33790a28643ab058b507b35cBen Cheng &nhdr, &name_offset, &desc_offset)) > 0) 815725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 815825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = data->d_buf + name_offset; 815925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *desc = data->d_buf + desc_offset; 816025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 816125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[100]; 816225b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf2[100]; 816325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext (" %-13.*s %9" PRId32 " %s\n"), 816425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) nhdr.n_namesz, name, nhdr.n_descsz, 816525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_type == ET_CORE 816625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ebl_core_note_type_name (ebl, nhdr.n_type, 816725b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)) 816825b3c049e70834cf33790a28643ab058b507b35cBen Cheng : ebl_object_note_type_name (ebl, name, nhdr.n_type, 816925b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf2, sizeof (buf2))); 817025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 817125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Filter out invalid entries. */ 817225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (memchr (name, '\0', nhdr.n_namesz) != NULL 817325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX For now help broken Linux kernels. */ 817425b3c049e70834cf33790a28643ab058b507b35cBen Cheng || 1) 817525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 817625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_type == ET_CORE) 817725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 817825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (nhdr.n_type == NT_AUXV 817925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */ 818025b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (nhdr.n_namesz == 5 && name[4] == '\0')) 818125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && !memcmp (name, "CORE", 4)) 818225b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz, 818325b3c049e70834cf33790a28643ab058b507b35cBen Cheng start + desc_offset); 818425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 818525b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_core_note (ebl, &nhdr, name, desc); 818625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 818725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 818825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc); 818925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 819025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 819125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 819225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (offset == data->d_size) 819325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 819425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 819525b3c049e70834cf33790a28643ab058b507b35cBen Cheng bad_note: 819625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 819725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get content of note section: %s"), 819825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 819925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 820025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 820125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 820225b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_notes (Ebl *ebl, GElf_Ehdr *ehdr) 820325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 820425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we have section headers, just look for SHT_NOTE sections. 820525b3c049e70834cf33790a28643ab058b507b35cBen Cheng In a debuginfo file, the program headers are not reliable. */ 820625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shnum != 0) 820725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 820825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 820925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 821025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) 821125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 821225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 821325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 821425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 821525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 821625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 821725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 821825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 821925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 822025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL || shdr->sh_type != SHT_NOTE) 822125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Not what we are looking for. */ 822225b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 822325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 822425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 822525b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"), 822625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), 822725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 822825b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size, shdr->sh_offset); 822925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 823025b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_notes_data (ebl, ehdr, shdr->sh_offset, 823125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_getdata (scn, NULL)); 823225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 823325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 823425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 823525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 823625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to look through the program header to find the note 823725b3c049e70834cf33790a28643ab058b507b35cBen Cheng sections. There can be more than one. */ 823825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = 0; cnt < phnum; ++cnt) 823925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 824025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr mem; 824125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem); 824225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 824325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (phdr == NULL || phdr->p_type != PT_NOTE) 824425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Not what we are looking for. */ 824525b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 824625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 824725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\ 824825b3c049e70834cf33790a28643ab058b507b35cBen Cheng\nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"), 824925b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_filesz, phdr->p_offset); 825025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 825125b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle_notes_data (ebl, ehdr, phdr->p_offset, 825225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_getdata_rawchunk (ebl->elf, 825325b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_offset, phdr->p_filesz, 825425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ELF_T_NHDR)); 825525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 825625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 825725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 825825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 825925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 826025b3c049e70834cf33790a28643ab058b507b35cBen Chenghex_dump (const uint8_t *data, size_t len) 826125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 826225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t pos = 0; 826325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (pos < len) 826425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 826525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" 0x%08Zx ", pos); 826625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 826725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const size_t chunk = MIN (len - pos, 16); 826825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 826925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < chunk; ++i) 827025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (i % 4 == 3) 827125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%02x ", data[pos + i]); 827225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 827325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%02x", data[pos + i]); 827425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 827525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (chunk < 16) 827625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), ""); 827725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 827825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t i = 0; i < chunk; ++i) 827925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 828025b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char b = data[pos + i]; 828125b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%c", isprint (b) ? b : '.'); 828225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 828325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 828425b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar ('\n'); 828525b3c049e70834cf33790a28643ab058b507b35cBen Cheng pos += chunk; 828625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 828725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 828825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 828925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 829025b3c049e70834cf33790a28643ab058b507b35cBen Chengdump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) 829125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 829225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS) 829325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"), 829425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), name); 829525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 829625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 829725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 829825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 829925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"), 830025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), name, elf_errmsg (-1)); 830125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 830225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 830325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64 830425b3c049e70834cf33790a28643ab058b507b35cBen Cheng " bytes at offset %#0" PRIx64 ":\n"), 830525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), name, 830625b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size, shdr->sh_offset); 830725b3c049e70834cf33790a28643ab058b507b35cBen Cheng hex_dump (data->d_buf, data->d_size); 830825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 830925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 831025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 831125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 831225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 831325b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) 831425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 831525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS) 831625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nSection [%Zu] '%s' has no strings to dump.\n"), 831725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), name); 831825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 831925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 832025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_rawdata (scn, NULL); 832125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 832225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"), 832325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), name, elf_errmsg (-1)); 832425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 832525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 832625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64 832725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " bytes at offset %#0" PRIx64 ":\n"), 832825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (scn), name, 832925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size, shdr->sh_offset); 833025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 833125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *start = data->d_buf; 833225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *const limit = start + data->d_size; 833325b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 833425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 833525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *end = memchr (start, '\0', limit - start); 833625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const size_t pos = start - (const char *) data->d_buf; 833725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (end == NULL)) 833825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 833925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%6Zx]- %.*s\n", 834025b3c049e70834cf33790a28643ab058b507b35cBen Cheng pos, (int) (limit - start), start); 834125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 834225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 834325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" [%6Zx] %s\n", pos, start); 834425b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = end + 1; 834525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } while (start < limit); 834625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 834725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 834825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 834925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 835025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 835125b3c049e70834cf33790a28643ab058b507b35cBen Chengfor_each_section_argument (Elf *elf, const struct section_argument *list, 835225b3c049e70834cf33790a28643ab058b507b35cBen Cheng void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr, 835325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name)) 835425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 835525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 835625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 835725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_getshdrstrndx (elf, &shstrndx) < 0) 835825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 835925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 836025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 836125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (const struct section_argument *a = list; a != NULL; a = a->next) 836225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 836325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn; 836425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 836525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = NULL; 836625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 836725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *endp = NULL; 836825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned long int shndx = strtoul (a->arg, &endp, 0); 836925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (endp != a->arg && *endp == '\0') 837025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 837125b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = elf_getscn (elf, shndx); 837225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (scn == NULL) 837325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 837425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx); 837525b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 837625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 837725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 837825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (gelf_getshdr (scn, &shdr_mem) == NULL) 837925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"), 838025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 838125b3c049e70834cf33790a28643ab058b507b35cBen Cheng name = elf_strptr (elf, shstrndx, shdr_mem.sh_name); 838225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 838325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 838425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 838525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Need to look up the section by name. */ 838625b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = NULL; 838725b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool found = false; 838825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (elf, scn)) != NULL) 838925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 839025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (gelf_getshdr (scn, &shdr_mem) == NULL) 839125b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 839225b3c049e70834cf33790a28643ab058b507b35cBen Cheng name = elf_strptr (elf, shstrndx, shdr_mem.sh_name); 839325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name == NULL) 839425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 839525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!strcmp (name, a->arg)) 839625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 839725b3c049e70834cf33790a28643ab058b507b35cBen Cheng found = true; 839825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (*dump) (scn, &shdr_mem, name); 839925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 840025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 840125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 840225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (!found) && !a->implicit) 840325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg); 840425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 840525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 840625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 840725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 840825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 840925b3c049e70834cf33790a28643ab058b507b35cBen Chengdump_data (Ebl *ebl) 841025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 841125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section); 841225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 841325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 841425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 841525b3c049e70834cf33790a28643ab058b507b35cBen Chengdump_strings (Ebl *ebl) 841625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 841725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for_each_section_argument (ebl->elf, string_sections, &print_string_section); 841825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 841925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 842025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 842125b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_strings (Ebl *ebl) 842225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 842325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header string table index. */ 842425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 842525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 842625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 842725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get section header string table index")); 842825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 842925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn; 843025b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 843125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name; 843225b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = NULL; 843325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 843425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 843525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (gelf_getshdr (scn, &shdr_mem) == NULL) 843625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 843725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 843825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr_mem.sh_type != SHT_PROGBITS 843925b3c049e70834cf33790a28643ab058b507b35cBen Cheng || !(shdr_mem.sh_flags & SHF_STRINGS)) 844025b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 844125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 844225b3c049e70834cf33790a28643ab058b507b35cBen Cheng name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name); 844325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name == NULL) 844425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 844525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 844625b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_string_section (scn, &shdr_mem, name); 844725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 844825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 844925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 845025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 845125b3c049e70834cf33790a28643ab058b507b35cBen Chengdump_archive_index (Elf *elf, const char *fname) 845225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 845325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t narsym; 845425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Elf_Arsym *arsym = elf_getarsym (elf, &narsym); 845525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (arsym == NULL) 845625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 845725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int result = elf_errno (); 845825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (result != ELF_E_NO_INDEX)) 845925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 846025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get symbol index of archive '%s': %s"), 846125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname, elf_errmsg (result)); 846225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 846325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nArchive '%s' has no symbol index\n"), fname); 846425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 846525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 846625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 846725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"), 846825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname, narsym); 846925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 847025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t as_off = 0; 847125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s) 847225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 847325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (s->as_off != as_off) 847425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 847525b3c049e70834cf33790a28643ab058b507b35cBen Cheng as_off = s->as_off; 847625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 847725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *subelf; 847825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_rand (elf, as_off) == 0) 847925b3c049e70834cf33790a28643ab058b507b35cBen Cheng || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf)) 848025b3c049e70834cf33790a28643ab058b507b35cBen Cheng == NULL)) 848125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7) 848225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (1) 848325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 848425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 848525b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot extract member at offset %Zu in '%s': %s"), 848625b3c049e70834cf33790a28643ab058b507b35cBen Cheng as_off, fname, elf_errmsg (-1)); 848725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 848825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Elf_Arhdr *h = elf_getarhdr (subelf); 848925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 849025b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (gettext ("Archive member '%s' contains:\n"), h->ar_name); 849125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 849225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_end (subelf); 849325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 849425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 849525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("\t%s\n", s->as_name); 849625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 849725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 849825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 849925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "debugpred.h" 8500