1441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print information from ELF file in human-readable form. 2cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Red Hat, Inc. 3cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng This file is part of Red Hat elfutils. 4441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Written by Ulrich Drepper <drepper@redhat.com>, 1999. 5441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Red Hat elfutils is free software; you can redistribute it and/or modify 7cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng it under the terms of the GNU General Public License as published by the 8cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Free Software Foundation; version 2 of the License. 9441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 10cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Red Hat elfutils is distributed in the hope that it will be useful, but 11cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 12cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng General Public License for more details. 14cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 15cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng You should have received a copy of the GNU General Public License along 16cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng with Red Hat elfutils; if not, write to the Free Software Foundation, 17cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 18cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 19cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Red Hat elfutils is an included package of the Open Invention Network. 20cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng An included package of the Open Invention Network is a package for which 21cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Open Invention Network licensees cross-license their patents. No patent 22cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng license is granted, either expressly or impliedly, by designation as an 23cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng included package. Should you wish to participate in the Open Invention 24cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Network licensing program, please visit www.openinventionnetwork.com 25cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng <http://www.openinventionnetwork.com>. */ 26441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 27441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifdef HAVE_CONFIG_H 28441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project# include <config.h> 29441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif 30441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 31441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <argp.h> 32441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <assert.h> 33cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <ctype.h> 34441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <dwarf.h> 35441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <errno.h> 36441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <error.h> 37441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <fcntl.h> 38441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <gelf.h> 39441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <inttypes.h> 40441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <langinfo.h> 41441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libdw.h> 42cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <libdwfl.h> 43441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libintl.h> 44441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <locale.h> 45cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <stdarg.h> 46441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdbool.h> 47441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdlib.h> 48441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <string.h> 49441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <time.h> 50441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <unistd.h> 51441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <sys/param.h> 52441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 53441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <system.h> 54cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include "../libelf/libelfP.h" 55cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include "../libelf/common.h" 56cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include "../libebl/libeblP.h" 57441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include "../libdw/libdwP.h" 58cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include "../libdwfl/libdwflP.h" 59441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include "../libdw/memory-access.h" 60441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 61441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 62441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Name and version of program. */ 63441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_version (FILE *stream, struct argp_state *state); 64441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectvoid (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; 65441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 66cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Bug report address. */ 67cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengconst char *argp_program_bug_address = PACKAGE_BUGREPORT; 68cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 69441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Definitions of arguments for argp functions. */ 70441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const struct argp_option options[] = 71441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 72cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { NULL, 0, NULL, 0, N_("Output selection:"), 0 }, 73cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "all", 'a', NULL, 0, N_("Equivalent to: -h -l"), 0 }, 74cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 }, 75cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 }, 76441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { "histogram", 'I', NULL, 0, 77cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng N_("Display histogram of bucket list lengths"), 0 }, 78cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 }, 79cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 80cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 }, 81cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "section-headers", 'S', NULL, 0, N_("Display the sections' header"), 0 }, 82cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 83cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 }, 84cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 }, 85441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL, 86441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project N_("Display DWARF section content. SECTION can be one of abbrev, " 87cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng "aranges, frame, info, loc, line, ranges, pubnames, str, or macinfo."), 88cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 0 }, 89cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "notes", 'n', NULL, 0, N_("Display the core notes"), 0 }, 90441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { "arch-specific", 'A', NULL, 0, 91cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng N_("Display architecture specific information (if any)"), 0 }, 92cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "hex-dump", 'x', "SECTION", 0, 93cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 }, 94cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL, 95cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng N_("Print string contents of sections"), 0 }, 96cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 97cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { "archive-index", 'c', NULL, 0, 98cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng N_("Display the symbol index of an archive"), 0 }, 99cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 100cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { NULL, 0, NULL, 0, N_("Output control:"), 0 }, 101cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 102cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { NULL, 0, NULL, 0, NULL, 0 } 103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}; 104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Short description of program. */ 106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char doc[] = N_("\ 107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectPrint information from ELF file in human-readable form."); 108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Strings for arguments in help texts. */ 110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char args_doc[] = N_("FILE..."); 111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Prototype for option handler. */ 113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Data structure to communicate with argp functions. */ 116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic struct argp argp = 117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 118cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng options, parse_opt, args_doc, doc, NULL, NULL, NULL 119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}; 120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Flags set by the option controlling the output. */ 123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if dynamic segment should be printed. */ 125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_dynamic_table; 126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if the file header should be printed. */ 128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_file_header; 129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if the program headers should be printed. */ 131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_program_header; 132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if relocations should be printed. */ 134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_relocations; 135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if the section headers should be printed. */ 137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_section_header; 138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if the symbol table should be printed. */ 140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_symbol_table; 141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if the version information should be printed. */ 143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_version_info; 144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if section groups should be printed. */ 146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_section_groups; 147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if bucket list length histogram should be printed. */ 149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_histogram; 150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if the architecture specific data should be printed. */ 152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_arch; 153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if note section content should be printed. */ 155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool print_notes; 156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 157cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* True if SHF_STRINGS section content should be printed. */ 158cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic bool print_string_sections; 159cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 160cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* True if archive index should be printed. */ 161cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic bool print_archive_index; 162cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 163cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* True if any of the control options except print_archive_index is set. */ 164cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic bool any_control_option; 165cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Select printing of debugging sections. */ 167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic enum section_e 168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_abbrev = 1, /* .debug_abbrev */ 170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_aranges = 2, /* .debug_aranges */ 171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_frame = 4, /* .debug_frame or .eh_frame */ 172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_info = 8, /* .debug_info */ 173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_line = 16, /* .debug_line */ 174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_loc = 32, /* .debug_loc */ 175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_pubnames = 64,/* .debug_pubnames */ 176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_str = 128, /* .debug_str */ 177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_macinfo = 256,/* .debug_macinfo */ 178cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng section_ranges = 512, /* .debug_ranges */ 179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_all = (section_abbrev | section_aranges | section_frame 180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project | section_info | section_line | section_loc 181cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng | section_pubnames | section_str | section_macinfo 182cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng | section_ranges) 183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} print_debug_sections; 184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 185cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Select hex dumping of sections. */ 186cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic struct section_argument *dump_data_sections; 187cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic struct section_argument **dump_data_sections_tail = &dump_data_sections; 188cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 189cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Select string dumping of sections. */ 190cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic struct section_argument *string_sections; 191cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic struct section_argument **string_sections_tail = &string_sections; 192cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 193cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstruct section_argument 194cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 195cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct section_argument *next; 196cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *arg; 197cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}; 198cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Number of sections in the file. */ 200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic size_t shnum; 201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Declarations of local functions. */ 204cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void process_file (int fd, const char *fname, bool only_one); 205cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void process_elf_file (Dwfl_Module *dwflmod, int fd); 206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr); 207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr); 208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); 209cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_scngrp (Ebl *ebl); 210441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr); 211cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_relocs (Ebl *ebl); 212cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 213cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 214cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_symtab (Ebl *ebl, int type); 215cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 216cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_verinfo (Ebl *ebl); 217cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 218cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 219cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void handle_versym (Ebl *ebl, Elf_Scn *scn, 220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr); 221cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr); 222cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void handle_hash (Ebl *ebl); 223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr); 224cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_liblist (Ebl *ebl); 225cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr); 226cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void dump_data (Ebl *ebl); 227cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void dump_strings (Ebl *ebl); 228cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_strings (Ebl *ebl); 229cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void dump_archive_index (Elf *, const char *); 230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectint 233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmain (int argc, char *argv[]) 234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Set locale. */ 236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project setlocale (LC_ALL, ""); 237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Initialize the message catalog. */ 239cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng textdomain (PACKAGE_TARNAME); 240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Parse and process arguments. */ 242cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int remaining; 243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project argp_parse (&argp, argc, argv, 0, &remaining, NULL); 244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Before we start tell the ELF library which version we are using. */ 246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_version (EV_CURRENT); 247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Now process all the files given at the command line. */ 249cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bool only_one = remaining + 1 == argc; 250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project do 251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Open the file. */ 253cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int fd = open (argv[remaining], O_RDONLY); 254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (fd == -1) 255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, errno, gettext ("cannot open input file")); 257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 260cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng process_file (fd, argv[remaining], only_one); 261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project close (fd); 263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (++remaining < argc); 265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return error_message_count != 0; 267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Handle program arguments. */ 271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic error_t 272cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengparse_opt (int key, char *arg, 273cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct argp_state *state __attribute__ ((unused))) 274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (key) 276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'a': 278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_file_header = true; 279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_program_header = true; 280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_relocations = true; 281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_section_header = true; 282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_symbol_table = true; 283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_version_info = true; 284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_dynamic_table = true; 285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_section_groups = true; 286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_histogram = true; 287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_arch = true; 288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_notes = true; 289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'A': 292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_arch = true; 293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'd': 296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_dynamic_table = true; 297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'g': 300441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_section_groups = true; 301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'h': 304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_file_header = true; 305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'I': 308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_histogram = true; 309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'l': 312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_program_header = true; 313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'n': 316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_notes = true; 317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'r': 320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_relocations = true; 321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'S': 324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_section_header = true; 325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 's': 328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_symbol_table = true; 329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'V': 332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_version_info = true; 333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project any_control_option = true; 334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 335cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'c': 336cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_archive_index = true; 337cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'w': 339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (arg == NULL) 340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections = section_all; 341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "abbrev") == 0) 342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_abbrev; 343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "aranges") == 0) 344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_aranges; 345cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (strcmp (arg, "ranges") == 0) 346cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_debug_sections |= section_ranges; 347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "frame") == 0) 348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_frame; 349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "info") == 0) 350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_info; 351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "loc") == 0) 352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_loc; 353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "line") == 0) 354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_line; 355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "pubnames") == 0) 356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_pubnames; 357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "str") == 0) 358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_str; 359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (arg, "macinfo") == 0) 360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_debug_sections |= section_macinfo; 361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 363441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"), 364441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project arg); 365441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project argp_help (&argp, stderr, ARGP_HELP_SEE, 366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project program_invocation_short_name); 367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project exit (1); 368441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 369cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng any_control_option = true; 370cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 371cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'p': 372cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng any_control_option = true; 373cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (arg == NULL) 374cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 375cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_string_sections = true; 376cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 377cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 378cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Fall through. */ 379cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'x': 380cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 381cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct section_argument *a = xmalloc (sizeof *a); 382cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng a->arg = arg; 383cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng a->next = NULL; 384cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct section_argument ***tailp 385cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng = key == 'x' ? &dump_data_sections_tail : &string_sections_tail; 386cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng **tailp = a; 387cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng *tailp = &a->next; 388cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 389cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng any_control_option = true; 390cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 391cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case ARGP_KEY_NO_ARGS: 392cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs (gettext ("Missing file name.\n"), stderr); 393cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto do_argp_help; 394cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case ARGP_KEY_FINI: 395cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (! any_control_option && ! print_archive_index) 396cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 397cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs (gettext ("No operation specified.\n"), stderr); 398cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng do_argp_help: 399cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, 400cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng program_invocation_short_name); 401cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng exit (1); 402cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return ARGP_ERR_UNKNOWN; 406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return 0; 408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the version information. */ 412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 413cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 415cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fprintf (stream, gettext ("\ 417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectCopyright (C) %s Red Hat, Inc.\n\ 418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectThis is free software; see the source for copying conditions. There is NO\n\ 419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 420cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng"), "2008"); 421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 425cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Check if the file is an archive, and if so dump its index. */ 426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 427cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengcheck_archive_index (int fd, const char *fname, bool only_one) 428cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 429cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Create an `Elf' descriptor. */ 430cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 431cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (elf == NULL) 432cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot generate Elf descriptor: %s"), 433cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_errmsg (-1)); 434cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 435cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 436cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (elf_kind (elf) == ELF_K_AR) 437cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 438cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (!only_one) 439cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("\n%s:\n\n", fname); 440cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dump_archive_index (elf, fname); 441cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 442cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 443cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, 444cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("'%s' is not an archive, cannot print archive index"), 445cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fname); 446cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 447cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Now we can close the descriptor. */ 448cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (elf_end (elf) != 0) 449cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("error while closing Elf descriptor: %s"), 450cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_errmsg (-1)); 451cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 452cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 453cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 454cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Trivial callback used for checking if we opened an archive. */ 455cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 456cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengcount_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)), 457cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void **userdata __attribute__ ((unused)), 458cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *name __attribute__ ((unused)), 459cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr base __attribute__ ((unused)), 460cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void *arg) 461cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 462cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (*(bool *) arg) 463cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return DWARF_CB_ABORT; 464cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng *(bool *) arg = true; 465cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return DWARF_CB_OK; 466cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 467cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 468cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstruct process_dwflmod_args 469cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 470cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int fd; 471cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bool only_one; 472cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}; 473cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 474cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 475cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprocess_dwflmod (Dwfl_Module *dwflmod, 476cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void **userdata __attribute__ ((unused)), 477cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *name __attribute__ ((unused)), 478cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr base __attribute__ ((unused)), 479cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void *arg) 480441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 481cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const struct process_dwflmod_args *a = arg; 482441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 483cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Print the file name. */ 484cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (!a->only_one) 485441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 486cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *fname; 487cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL); 488441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 489cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("\n%s:\n\n", fname); 490cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 491441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 492cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng process_elf_file (dwflmod, a->fd); 493441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 494cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return DWARF_CB_OK; 495cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 496441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 497cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Stub libdwfl callback, only the ELF handle already open is ever used. */ 498cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 499cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengfind_no_debuginfo (Dwfl_Module *mod __attribute__ ((unused)), 500cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void **userdata __attribute__ ((unused)), 501cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *modname __attribute__ ((unused)), 502cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr base __attribute__ ((unused)), 503cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *file_name __attribute__ ((unused)), 504cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *debuglink_file __attribute__ ((unused)), 505cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Word debuglink_crc __attribute__ ((unused)), 506cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char **debuginfo_file_name __attribute__ ((unused))) 507cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 508cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return -1; 509cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 510441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 511cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Process one input file. */ 512cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 513cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprocess_file (int fd, const char *fname, bool only_one) 514cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 515cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (print_archive_index) 516cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng check_archive_index (fd, fname, only_one); 517441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 518cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (!any_control_option) 519cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 520cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 521cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Duplicate an fd for dwfl_report_offline to swallow. */ 522cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int dwfl_fd = dup (fd); 523cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (dwfl_fd < 0)) 524cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, errno, "dup"); 525cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 526cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Use libdwfl in a trivial way to open the libdw handle for us. 527cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng This takes care of applying relocations to DWARF data in ET_REL files. */ 528cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const Dwfl_Callbacks callbacks = 529cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 530cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .section_address = dwfl_offline_section_address, 531cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .find_debuginfo = find_no_debuginfo 532cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 533cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwfl *dwfl = dwfl_begin (&callbacks); 534cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (dwfl != NULL)) 535cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Let 0 be the logical address of the file (or first in archive). */ 536cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwfl->offline_next_address = 0; 537cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL) 538cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 539cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct stat64 st; 540441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (fstat64 (fd, &st) != 0) 541441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, errno, gettext ("cannot stat input file")); 542cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (unlikely (st.st_size == 0)) 543441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("input file is empty")); 544441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 545cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("failed reading '%s': %s"), 546cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fname, dwfl_errmsg (-1)); 547cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 548cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 549cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 550cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwfl_report_end (dwfl, NULL, NULL); 551cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 552cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (only_one) 553cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 554cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Clear ONLY_ONE if we have multiple modules, from an archive. */ 555cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bool seen = false; 556cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0; 557cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 558cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 559cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Process the one or more modules gleaned from this file. */ 560cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct process_dwflmod_args a = { .fd = fd, .only_one = only_one }; 561cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwfl_getmodules (dwfl, &process_dwflmod, &a, 0); 562441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 563cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwfl_end (dwfl); 564441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 565441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 567cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Process one ELF file. */ 568441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 569cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprocess_elf_file (Dwfl_Module *dwflmod, int fd) 570441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 571cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Addr dwflbias; 572cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias); 573cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 574441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Ehdr ehdr_mem; 575441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 576441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 577441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr == NULL) 578441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 579cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_error: 580441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1)); 581441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 582441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 583441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 584cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl = ebl_openbackend (elf); 585cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (ebl == NULL)) 586441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 587cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ebl_error: 588441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, errno, gettext ("cannot create EBL handle")); 589441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 590441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 591441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 592441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Determine the number of sections. */ 593cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshnum (ebl->elf, &shnum) < 0)) 594441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 595441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot determine number of sections: %s"), 596441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 597441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 598cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* For an ET_REL file, libdwfl has adjusted the in-core shdrs 599cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng and may have applied relocation to some sections. 600cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng So we need to get a fresh Elf handle on the file to display those. */ 601cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bool print_unrelocated = (print_section_header 602cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || print_relocations 603cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || dump_data_sections != NULL 604cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || print_notes); 605cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 606cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf *pure_elf = NULL; 607cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *pure_ebl = ebl; 608cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (ehdr->e_type == ET_REL && print_unrelocated) 609cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 610cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Read the file afresh. */ 611cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng off64_t aroff = elf_getaroff (elf); 612cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 613cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (aroff > 0) 614cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 615cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Archive member. */ 616cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (void) elf_rand (pure_elf, aroff); 617cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf); 618cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_end (pure_elf); 619cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng pure_elf = armem; 620cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 621cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (pure_elf == NULL) 622cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto elf_error; 623cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng pure_ebl = ebl_openbackend (pure_elf); 624cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (pure_ebl == NULL) 625cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto ebl_error; 626cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 627cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 628441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_file_header) 629441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_ehdr (ebl, ehdr); 630441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_section_header) 631cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_shdr (pure_ebl, ehdr); 632441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_program_header) 633441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_phdr (ebl, ehdr); 634441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_section_groups) 635cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_scngrp (ebl); 636441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_dynamic_table) 637441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_dynamic (ebl, ehdr); 638441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_relocations) 639cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_relocs (pure_ebl); 640441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_histogram) 641cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_hash (ebl); 642441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_symbol_table) 643cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_symtab (ebl, SHT_DYNSYM); 644441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_version_info) 645cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_verinfo (ebl); 646441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_symbol_table) 647cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_symtab (ebl, SHT_SYMTAB); 648cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (print_arch) 649cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_liblist (ebl); 650441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_arch) 651cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_attributes (ebl, ehdr); 652cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (dump_data_sections != NULL) 653cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dump_data (pure_ebl); 654cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (string_sections != NULL) 655cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dump_strings (ebl); 656441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_debug_sections != 0) 657cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_debug (dwflmod, ebl, ehdr); 658441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_notes) 659cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_notes (pure_ebl, ehdr); 660cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (print_string_sections) 661cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_strings (ebl); 662441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 663441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_closebackend (ebl); 664cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 665cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (pure_ebl != ebl) 666cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 667cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ebl_closebackend (pure_ebl); 668cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_end (pure_elf); 669cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 670441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 671441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 672441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 673441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print file type. */ 674441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 675441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_file_type (unsigned short int e_type) 676441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 677cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (e_type <= ET_CORE)) 678441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 679cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const knowntypes[] = 680441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 681441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project N_("NONE (None)"), 682441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project N_("REL (Relocatable file)"), 683441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project N_("EXEC (Executable file)"), 684441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project N_("DYN (Shared object file)"), 685441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project N_("CORE (Core file)") 686441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 687441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext (knowntypes[e_type])); 688441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 689441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (e_type >= ET_LOOS && e_type <= ET_HIOS) 690441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("OS Specific: (%x)\n"), e_type); 691441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */) 692441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("Processor Specific: (%x)\n"), e_type); 693441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 694441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts ("???"); 695441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 696441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 697441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 698441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print ELF header. */ 699441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 700441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_ehdr (Ebl *ebl, GElf_Ehdr *ehdr) 701441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 702441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout); 703cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt) 704441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %02hhx", ehdr->e_ident[cnt]); 705441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 706441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\n Class: %s\n"), 707441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32" 708441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64" 709441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : "\?\?\?"); 710441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 711441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Data: %s\n"), 712441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_DATA] == ELFDATA2LSB 713441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? "2's complement, little endian" 714441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : ehdr->e_ident[EI_DATA] == ELFDATA2MSB 715441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? "2's complement, big endian" : "\?\?\?"); 716441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 717cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" Ident Version: %hhd %s\n"), 718441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_VERSION], 719441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)") 720441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : "(\?\?\?)"); 721441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 722cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char buf[512]; 723441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" OS/ABI: %s\n"), 724441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 725441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 726441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" ABI Version: %hhd\n"), 727441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_ABIVERSION]); 728441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 729441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (gettext (" Type: "), stdout); 730441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_file_type (ehdr->e_type); 731441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 732441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Machine: %s\n"), ebl->name); 733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 734441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Version: %d %s\n"), 735441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_version, 736441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)"); 737441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 738441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Entry point address: %#" PRIx64 "\n"), 739441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_entry); 740441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 741441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Start of program headers: %" PRId64 " %s\n"), 742441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_phoff, gettext ("(bytes into file)")); 743441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 744441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Start of section headers: %" PRId64 " %s\n"), 745441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_shoff, gettext ("(bytes into file)")); 746441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 747441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Flags: %s\n"), 748441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 749441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 750441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Size of this header: %" PRId16 " %s\n"), 751441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ehsize, gettext ("(bytes)")); 752441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 753441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Size of program header entries: %" PRId16 " %s\n"), 754441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_phentsize, gettext ("(bytes)")); 755441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 756441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Number of program headers entries: %" PRId16 "\n"), 757441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_phnum); 758441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 759441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Size of section header entries: %" PRId16 " %s\n"), 760441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_shentsize, gettext ("(bytes)")); 761441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 762441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Number of section headers entries: %" PRId16), 763441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_shnum); 764441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_shnum == 0) 765441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 766441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 767cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 768441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr != NULL) 769441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" (%" PRIu32 " in [0].sh_size)"), 770441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint32_t) shdr->sh_size); 771441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 772441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (gettext (" ([0] not available)"), stdout); 773441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 774441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputc_unlocked ('\n', stdout); 775441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 776cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (ehdr->e_shstrndx == SHN_XINDEX)) 777441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 778441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 779cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 780441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr != NULL) 781441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We managed to get the zeroth section. */ 782441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"), 783441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint32_t) shdr->sh_link); 784441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 785441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 786441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project strncpy (buf, gettext (" ([0] not available)"), sizeof (buf)); 787441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf[sizeof (buf) - 1] = '\0'; 788441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 789441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 790441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Section header string table index: XINDEX%s\n\n"), 791441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf); 792441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 793441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 794441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Section header string table index: %" PRId16 "\n\n"), 795441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_shstrndx); 796441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 797441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 798441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 799441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char * 800441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectget_visibility_type (int value) 801441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 802441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (value) 803441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 804441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case STV_DEFAULT: 805441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return "DEFAULT"; 806441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case STV_INTERNAL: 807441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return "INTERNAL"; 808441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case STV_HIDDEN: 809441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return "HIDDEN"; 810441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case STV_PROTECTED: 811441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return "PROTECTED"; 812441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 813441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return "???"; 814441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 815441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 816441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 817441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 818441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the section headers. */ 819441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 820441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_shdr (Ebl *ebl, GElf_Ehdr *ehdr) 821441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 822441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 823441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t shstrndx; 824441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 825441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (! print_file_header) 826441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 827441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectThere are %d section headers, starting at offset %#" PRIx64 ":\n\ 828441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\n"), 829441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_shnum, ehdr->e_shoff); 830441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 831441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 832cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 833441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 834441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 835441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 836441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("Section Headers:")); 837441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 838441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 839441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); 840441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 841441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); 842441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 843441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 0; cnt < shnum; ++cnt) 844441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 845441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = elf_getscn (ebl->elf, cnt); 846441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 847cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (scn == NULL)) 848441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"), 849441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 850441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 851441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header. */ 852cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr shdr_mem; 853cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 854cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (shdr == NULL)) 855441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"), 856441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 857441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 858cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char flagbuf[20]; 859cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *cp = flagbuf; 860441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_WRITE) 861441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'W'; 862441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_ALLOC) 863441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'A'; 864441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_EXECINSTR) 865441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'X'; 866441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_MERGE) 867441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'M'; 868441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_STRINGS) 869441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'S'; 870441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_INFO_LINK) 871441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'I'; 872441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_LINK_ORDER) 873441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'L'; 874441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_OS_NONCONFORMING) 875441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'N'; 876441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_GROUP) 877441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'G'; 878441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_TLS) 879441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'T'; 880441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_ORDERED) 881441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'O'; 882441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_EXCLUDE) 883441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = 'E'; 884441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp = '\0'; 885441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 886cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char buf[128]; 887441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64 888441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32 889441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " %2" PRId64 "\n", 890441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, 891441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name) 892441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ?: "<corrupt>", 893441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)), 894441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr, 895441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset, 896441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size, 897441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info, 898441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_addralign); 899441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 900441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 901441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputc_unlocked ('\n', stdout); 902441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 903441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 904441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 905441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the program header. */ 906441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 907441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_phdr (Ebl *ebl, GElf_Ehdr *ehdr) 908441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 909441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_phnum == 0) 910441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* No program header, this is OK in relocatable objects. */ 911441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 912441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 913441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("Program Headers:")); 914441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 915441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("\ 916441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); 917441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 918441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("\ 919441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); 920441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 921441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Process all program headers. */ 922441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool has_relro = false; 923441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Addr relro_from = 0; 924441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Addr relro_to = 0; 925cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t cnt = 0; cnt < ehdr->e_phnum; ++cnt) 926441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 927441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[128]; 928441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr mem; 929441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem); 930441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 931441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* If for some reason the header cannot be returned show this. */ 932cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (phdr == NULL)) 933441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 934441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (" ???"); 935441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 936441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 937441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 938441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64 939441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n", 940441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)), 941441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr->p_offset, 942441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr, 943441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr, 944441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr->p_filesz, 945441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr->p_memsz, 946441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr->p_flags & PF_R ? 'R' : ' ', 947441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr->p_flags & PF_W ? 'W' : ' ', 948441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr->p_flags & PF_X ? 'E' : ' ', 949441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr->p_align); 950441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 951441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr->p_type == PT_INTERP) 952441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 953441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We can show the user the name of the interpreter. */ 954441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t maxsize; 955441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char *filedata = elf_rawfile (ebl->elf, &maxsize); 956441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 957441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (filedata != NULL && phdr->p_offset < maxsize) 958441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\t[Requesting program interpreter: %s]\n"), 959441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project filedata + phdr->p_offset); 960441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 961441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (phdr->p_type == PT_GNU_RELRO) 962441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 963441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project has_relro = true; 964441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project relro_from = phdr->p_vaddr; 965441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project relro_to = relro_from + phdr->p_memsz; 966441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 967441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 968441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 969441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 970cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 971cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 972441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 973441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 974441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 975441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("\n Section to Segment mapping:\n Segment Sections...")); 976441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 977cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t cnt = 0; cnt < ehdr->e_phnum; ++cnt) 978441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 979441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Print the segment number. */ 980441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %2.2zu ", cnt); 981441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 982cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Phdr phdr_mem; 983cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 984441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This must not happen. */ 985cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (phdr == NULL)) 986441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"), 987441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 988441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 989441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Iterate over the sections. */ 990441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool in_relro = false; 991cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bool in_ro = false; 992cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t inner = 1; inner < shnum; ++inner) 993441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 994441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = elf_getscn (ebl->elf, inner); 995cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* This should not happen. */ 996cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (scn == NULL)) 997441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"), 998441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 999441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1000441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header. */ 1001cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr shdr_mem; 1002cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1003cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (shdr == NULL)) 1004441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 1005441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header: %s"), 1006441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 1007441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1008441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_size > 0 1009441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Compare allocated sections by VMA, unallocated 1010441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sections by file offset. */ 1011441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (shdr->sh_flags & SHF_ALLOC 1012441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? (shdr->sh_addr >= phdr->p_vaddr 1013441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (shdr->sh_addr + shdr->sh_size 1014441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project <= phdr->p_vaddr + phdr->p_memsz)) 1015441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : (shdr->sh_offset >= phdr->p_offset 1016441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (shdr->sh_offset + shdr->sh_size 1017441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project <= phdr->p_offset + phdr->p_filesz)))) 1018441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1019441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (has_relro && !in_relro 1020441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_addr >= relro_from 1021441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_addr + shdr->sh_size <= relro_to) 1022441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1023441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (" [RELRO:", stdout); 1024441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project in_relro = true; 1025441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1026441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (has_relro && in_relro && shdr->sh_addr >= relro_to) 1027441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1028441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked ("]", stdout); 1029441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project in_relro = false; 1030441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1031441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (has_relro && in_relro 1032441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_addr + shdr->sh_size > relro_to) 1033441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked ("] <RELRO:", stdout); 1034cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0) 1035cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 1036cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (!in_ro) 1037cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 1038cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs_unlocked (" [RO:", stdout); 1039cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng in_ro = true; 1040cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 1041cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 1042cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 1043cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 1044cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Determine the segment this section is part of. */ 1045cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t cnt2; 1046cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Phdr *phdr2 = NULL; 1047cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (cnt2 = 0; cnt2 < ehdr->e_phnum; ++cnt2) 1048cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 1049cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Phdr phdr2_mem; 1050cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem); 1051cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 1052cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (phdr2 != NULL && phdr2->p_type == PT_LOAD 1053cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && shdr->sh_addr >= phdr2->p_vaddr 1054cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && (shdr->sh_addr + shdr->sh_size 1055cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng <= phdr2->p_vaddr + phdr2->p_memsz)) 1056cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 1057cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 1058cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 1059cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (cnt2 < ehdr->e_phnum) 1060cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 1061cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if ((phdr2->p_flags & PF_W) == 0 && !in_ro) 1062cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 1063cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs_unlocked (" [RO:", stdout); 1064cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng in_ro = true; 1065cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 1066cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if ((phdr2->p_flags & PF_W) != 0 && in_ro) 1067cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 1068cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs_unlocked ("]", stdout); 1069cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng in_ro = false; 1070cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 1071cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 1072cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 1073441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1074441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %s", 1075441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); 1076441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1077441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Signal that this sectin is only partially covered. */ 1078441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (has_relro && in_relro 1079441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_addr + shdr->sh_size > relro_to) 1080441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1081441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (">", stdout); 1082441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project in_relro = false; 1083441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1084441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1085441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1086cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (in_relro || in_ro) 1087441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked ("]", stdout); 1088441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1089441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Finish the line. */ 1090441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputc_unlocked ('\n', stdout); 1091441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1092441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1093441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1094441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1095441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1096cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1097441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1098441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data of the section. */ 1099cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 1100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1101cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1102cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr symshdr_mem; 1103cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1104cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *symdata = elf_getdata (symscn, NULL); 1105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL 1107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || symdata == NULL) 1108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 1111cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 1112cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 1113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 1114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 1115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1116cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word *grpref = (Elf32_Word *) data->d_buf; 1117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1118cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Sym sym_mem; 1119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ((grpref[0] & GRP_COMDAT) 1120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ngettext ("\ 1121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n", 1122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 1123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n", 1124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data->d_size / sizeof (Elf32_Word) - 1) 1125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : ngettext ("\ 1126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\ 1127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n", 1128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data->d_size / sizeof (Elf32_Word) - 1), 1129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_ndxscn (scn), 1130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, symshdr->sh_link, 1132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name) 1133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ?: gettext ("<INVALID SYMBOL>"), 1134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data->d_size / sizeof (Elf32_Word) - 1); 1135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1136cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr grpshdr_mem; 1139cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]), 1140cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &grpshdr_mem); 1141cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 1142cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *str; 1143cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" [%2u] %s\n", 1144cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng grpref[cnt], 1145cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng grpshdr != NULL 1146cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name)) 1147cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? str : gettext ("<INVALID SECTION>")); 1148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1153cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_scngrp (Ebl *ebl) 1154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find all relocation sections and handle them. */ 1156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = NULL; 1157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Handle the section if it is a symbol table. */ 1161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr != NULL && shdr->sh_type == SHT_GROUP) 1165cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_scngrp (ebl, scn, shdr); 1166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const struct flags 1171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int mask; 1173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *str; 1174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} dt_flags[] = 1175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_ORIGIN, "ORIGIN" }, 1177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_SYMBOLIC, "SYMBOLIC" }, 1178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_TEXTREL, "TEXTREL" }, 1179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_BIND_NOW, "BIND_NOW" }, 1180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_STATIC_TLS, "STATIC_TLS" } 1181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]); 1183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const struct flags dt_flags_1[] = 1185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_NOW, "NOW" }, 1187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_GLOBAL, "GLOBAL" }, 1188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_GROUP, "GROUP" }, 1189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_NODELETE, "NODELETE" }, 1190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_LOADFLTR, "LOADFLTR" }, 1191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_INITFIRST, "INITFIRST" }, 1192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_NOOPEN, "NOOPEN" }, 1193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_ORIGIN, "ORIGIN" }, 1194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_DIRECT, "DIRECT" }, 1195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_TRANS, "TRANS" }, 1196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_INTERPOSE, "INTERPOSE" }, 1197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_NODEFLIB, "NODEFLIB" }, 1198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_NODUMP, "NODUMP" }, 1199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_CONFALT, "CONFALT" }, 1200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_ENDFILTEE, "ENDFILTEE" }, 1201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_DISPRELDNE, "DISPRELDNE" }, 1202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_1_DISPRELPND, "DISPRELPND" }, 1203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]); 1205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const struct flags dt_feature_1[] = 1207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DTF_1_PARINIT, "PARINIT" }, 1209441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DTF_1_CONFEXP, "CONFEXP" } 1210441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1211441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const int ndt_feature_1 = (sizeof (dt_feature_1) 1212441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project / sizeof (dt_feature_1[0])); 1213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1214441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const struct flags dt_posflag_1[] = 1215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_P1_LAZYLOAD, "LAZYLOAD" }, 1217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { DF_P1_GROUPPERM, "GROUPPERM" } 1218441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const int ndt_posflag_1 = (sizeof (dt_posflag_1) 1220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project / sizeof (dt_posflag_1[0])); 1221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_flags (int class, GElf_Xword d_val, const struct flags *flags, 1225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int nflags) 1226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool first = true; 1228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int cnt; 1229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 0; cnt < nflags; ++cnt) 1231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (d_val & flags[cnt].mask) 1232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!first) 1234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project putchar_unlocked (' '); 1235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (flags[cnt].str, stdout); 1236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project d_val &= ~flags[cnt].mask; 1237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project first = false; 1238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (d_val != 0) 1241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!first) 1243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project putchar_unlocked (' '); 1244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val); 1245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project putchar_unlocked ('\n'); 1248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_dt_flags (int class, GElf_Xword d_val) 1253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_flags (class, d_val, dt_flags, ndt_flags); 1255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_dt_flags_1 (int class, GElf_Xword d_val) 1260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_flags (class, d_val, dt_flags_1, ndt_flags_1); 1262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_dt_feature_1 (int class, GElf_Xword d_val) 1267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_flags (class, d_val, dt_feature_1, ndt_feature_1); 1269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1273441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_dt_posflag_1 (int class, GElf_Xword d_val) 1274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_flags (class, d_val, dt_posflag_1, ndt_posflag_1); 1276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1280cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int class = gelf_getclass (ebl->elf); 1283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr glink; 1284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data; 1285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t shstrndx; 1287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data of the section. */ 1289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data = elf_getdata (scn, NULL); 1290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 1294cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 1295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 1296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 1297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 1299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 1300441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 1301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 1302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_size / shdr->sh_entsize), 1303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned long int) (shdr->sh_size / shdr->sh_entsize), 1304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 1305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset, 1306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) shdr->sh_link, 1307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, 1308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 1309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &glink)->sh_name)); 1310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (gettext (" Type Value\n"), stdout); 1311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Dyn dynmem; 1315cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem); 1316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn == NULL) 1317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1319cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char buf[64]; 1320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %-17s ", 1321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf))); 1322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (dyn->d_tag) 1324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_NULL: 1326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_DEBUG: 1327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_BIND_NOW: 1328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_TEXTREL: 1329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* No further output. */ 1330cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputc_unlocked ('\n', stdout); 1331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_NEEDED: 1334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("Shared library: [%s]\n"), 1335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_SONAME: 1339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("Library soname: [%s]\n"), 1340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_RPATH: 1344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("Library rpath: [%s]\n"), 1345441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_RUNPATH: 1349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("Library runpath: [%s]\n"), 1350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_PLTRELSZ: 1354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_RELASZ: 1355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_STRSZ: 1356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_RELSZ: 1357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_RELAENT: 1358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_SYMENT: 1359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_RELENT: 1360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_PLTPADSZ: 1361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_MOVEENT: 1362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_MOVESZ: 1363441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_INIT_ARRAYSZ: 1364441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_FINI_ARRAYSZ: 1365441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_SYMINSZ: 1366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_SYMINENT: 1367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_GNU_CONFLICTSZ: 1368441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_GNU_LIBLISTSZ: 1369441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val); 1370441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1371441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1372441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_VERDEFNUM: 1373441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_VERNEEDNUM: 1374441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_RELACOUNT: 1375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_RELCOUNT: 1376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%" PRId64 "\n", dyn->d_un.d_val); 1377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_PLTREL: 1380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (ebl_dynamic_tag_name (ebl, dyn->d_un.d_val, NULL, 0)); 1381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_FLAGS: 1384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_dt_flags (class, dyn->d_un.d_val); 1385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_FLAGS_1: 1388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_dt_flags_1 (class, dyn->d_un.d_val); 1389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_FEATURE_1: 1392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_dt_feature_1 (class, dyn->d_un.d_val); 1393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DT_POSFLAG_1: 1396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project print_dt_posflag_1 (class, dyn->d_un.d_val); 1397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 1400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%#0*" PRIx64 "\n", 1401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val); 1402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the dynamic segment. */ 1409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_dynamic (Ebl *ebl, GElf_Ehdr *ehdr) 1411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1412cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int i = 0; i < ehdr->e_phnum; ++i) 1413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1414cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Phdr phdr_mem; 1415cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 1416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1417cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 1418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1419cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset); 1420cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr shdr_mem; 1421cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1422cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 1423cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_dynamic (ebl, scn, shdr); 1424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1429441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1430441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print relocations. */ 1431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1432cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_relocs (Ebl *ebl) 1433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1434441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find all relocation sections and handle them. */ 1435441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = NULL; 1436441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1437441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1438441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Handle the section if it is a symbol table. */ 1440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1441441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1443cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (shdr != NULL)) 1444441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1445441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_type == SHT_REL) 1446cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_relocs_rel (ebl, scn, shdr); 1447441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (shdr->sh_type == SHT_RELA) 1448cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_relocs_rela (ebl, scn, shdr); 1449441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1450441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1451441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1452441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1453441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1454441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Handle a relocation section. */ 1455441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1456cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1457441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1458441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int class = gelf_getclass (ebl->elf); 1459441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int nentries = shdr->sh_size / shdr->sh_entsize; 1460441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1461441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data of the section. */ 1462cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 1463441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1464441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1465441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1466441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the symbol table information. */ 1467cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1468cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr symshdr_mem; 1469cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1470cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *symdata = elf_getdata (symscn, NULL); 1471441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1472441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header of the section the relocations are for. */ 1473cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr destshdr_mem; 1474cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1475cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &destshdr_mem); 1476441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1477cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) 1478441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1479441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"), 1480441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset); 1481441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1482441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1483441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1484441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Search for the optional extended section index table. */ 1485cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *xndxdata = NULL; 1486cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int xndxscnidx = elf_scnshndx (scn); 1487cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (xndxscnidx > 0)) 1488cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); 1489441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1490441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 1491cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 1492cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 1493441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 1494441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 1495441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1496441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info != 0) 1497441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 1498441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nRelocation section [%2u] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 1499441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 1500441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nRelocation section [%2u] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 1501441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nentries), 1502441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) elf_ndxscn (scn), 1503441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1504441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) shdr->sh_info, 1505441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), 1506441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset, 1507441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nentries); 1508441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1509441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The .rel.dyn section does not refer to a specific section but 1510441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project instead of section index zero. Do not try to print a section 1511441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project name. */ 1512441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 1513441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 1514441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 1515441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 1516441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nentries), 1517441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) elf_ndxscn (scn), 1518441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1519441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset, 1520441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nentries); 1521441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (class == ELFCLASS32 1522441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? gettext ("\ 1523441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Offset Type Value Name\n") 1524441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("\ 1525441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Offset Type Value Name\n"), 1526441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stdout); 1527441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1528cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int cnt = 0; cnt < nentries; ++cnt) 1529441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1530441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Rel relmem; 1531cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Rel *rel = gelf_getrel (data, cnt, &relmem); 1532cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (rel != NULL)) 1533441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1534441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[128]; 1535441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym symmem; 1536441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word xndx; 1537cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 1538cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GELF_R_SYM (rel->r_info), 1539cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &symmem, &xndx); 1540cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (sym == NULL)) 1541441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", 1542441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1543441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1544441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Avoid the leading R_ which isn't carrying any 1545441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project information. */ 1546441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1547441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf)) + 2 1548441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("<INVALID RELOC>"), 1549441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("INVALID SYMBOL"), 1550441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (long int) GELF_R_SYM (rel->r_info)); 1551441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) 1552441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", 1553441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1554cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng likely (ebl_reloc_type_check (ebl, 1555cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GELF_R_TYPE (rel->r_info))) 1556441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Avoid the leading R_ which isn't carrying any 1557441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project information. */ 1558441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1559441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf)) + 2 1560441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("<INVALID RELOC>"), 1561441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, sym->st_value, 1562441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); 1563441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1564441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1565441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project destshdr = gelf_getshdr (elf_getscn (ebl->elf, 1566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sym->st_shndx == SHN_XINDEX 1567441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? xndx : sym->st_shndx), 1568441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &destshdr_mem); 1569441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1570cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (destshdr == NULL)) 1571441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", 1572441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1573441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1574441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Avoid the leading R_ which isn't carrying any 1575441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project information. */ 1576441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1577441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf)) + 2 1578441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("<INVALID RELOC>"), 1579441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("INVALID SECTION"), 1580441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (long int) (sym->st_shndx == SHN_XINDEX 1581441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? xndx : sym->st_shndx)); 1582441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1583441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", 1584441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1585441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1586441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Avoid the leading R_ which isn't carrying any 1587441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project information. */ 1588441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1589441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf)) + 2 1590441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("<INVALID RELOC>"), 1591441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, sym->st_value, 1592441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 1593441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1594441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1595441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1596441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1597441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1598441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1599441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Handle a relocation section. */ 1600441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1601cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1602441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1603441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int class = gelf_getclass (ebl->elf); 1604441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int nentries = shdr->sh_size / shdr->sh_entsize; 1605441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1606441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data of the section. */ 1607441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data = elf_getdata (scn, NULL); 1608441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1609441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1610441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1611441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the symbol table information. */ 1612441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1613441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr symshdr_mem; 1614441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1615441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *symdata = elf_getdata (symscn, NULL); 1616441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1617441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header of the section the relocations are for. */ 1618441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr destshdr_mem; 1619441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1620441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &destshdr_mem); 1621441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1622cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) 1623441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1624441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"), 1625441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset); 1626441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1627441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1628441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1629441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Search for the optional extended section index table. */ 1630441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *xndxdata = NULL; 1631cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int xndxscnidx = elf_scnshndx (scn); 1632cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (xndxscnidx > 0)) 1633cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); 1634441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1635441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 1636441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t shstrndx; 1637cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 1638441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 1639441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 1640441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1641441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 1642441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 1643441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 1644441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 1645441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nentries), 1646441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_ndxscn (scn), 1647441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1648441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) shdr->sh_info, 1649441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), 1650441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset, 1651441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nentries); 1652441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (class == ELFCLASS32 1653441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? gettext ("\ 1654441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Offset Type Value Addend Name\n") 1655441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("\ 1656441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Offset Type Value Addend Name\n"), 1657441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stdout); 1658441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1659441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (int cnt = 0; cnt < nentries; ++cnt) 1660441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1661441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Rela relmem; 1662441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Rela *rel = gelf_getrela (data, cnt, &relmem); 1663cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (rel != NULL)) 1664441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1665441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[64]; 1666441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym symmem; 1667441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word xndx; 1668cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 1669cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GELF_R_SYM (rel->r_info), 1670cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &symmem, &xndx); 1671441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1672cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (sym == NULL)) 1673441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", 1674441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1675441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1676441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Avoid the leading R_ which isn't carrying any 1677441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project information. */ 1678441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1679441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf)) + 2 1680441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("<INVALID RELOC>"), 1681441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("INVALID SYMBOL"), 1682441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (long int) GELF_R_SYM (rel->r_info)); 1683441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) 1684441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("\ 1685cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", 1686441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1687cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng likely (ebl_reloc_type_check (ebl, 1688cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GELF_R_TYPE (rel->r_info))) 1689441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Avoid the leading R_ which isn't carrying any 1690441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project information. */ 1691441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1692441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf)) + 2 1693441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("<INVALID RELOC>"), 1694441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, sym->st_value, 1695441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project rel->r_addend, 1696441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); 1697441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1698441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1699441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project destshdr = gelf_getshdr (elf_getscn (ebl->elf, 1700441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sym->st_shndx == SHN_XINDEX 1701441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? xndx : sym->st_shndx), 1702441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &destshdr_mem); 1703441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1704cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (shdr == NULL)) 1705441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", 1706441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1707441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1708441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Avoid the leading R_ which isn't carrying any 1709441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project information. */ 1710441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1711441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf)) + 2 1712441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("<INVALID RELOC>"), 1713441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("INVALID SECTION"), 1714441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (long int) (sym->st_shndx == SHN_XINDEX 1715441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? xndx : sym->st_shndx)); 1716441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1717441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("\ 1718cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", 1719441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1720441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1721441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Avoid the leading R_ which isn't carrying any 1722441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project information. */ 1723441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1724441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf)) + 2 1725441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("<INVALID RELOC>"), 1726441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, sym->st_value, 1727441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project rel->r_addend, 1728441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 1729441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1730441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1731441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1732441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1734441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1735441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the program header. */ 1736441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1737cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_symtab (Ebl *ebl, int type) 1738441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1739441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find the symbol table(s). For this we have to search through the 1740441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section table. */ 1741441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = NULL; 1742441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1743441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1744441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1745441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Handle the section if it is a symbol table. */ 1746441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1747441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1748441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1749441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr != NULL && shdr->sh_type == (GElf_Word) type) 1750cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_symtab (ebl, scn, shdr); 1751441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1752441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1753441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1754441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1755441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1756cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1757441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1758441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *versym_data = NULL; 1759441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *verneed_data = NULL; 1760441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *verdef_data = NULL; 1761441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *xndx_data = NULL; 1762441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int class = gelf_getclass (ebl->elf); 1763441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word verneed_stridx = 0; 1764441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word verdef_stridx = 0; 1765441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1766441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data of the section. */ 1767cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 1768441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1769441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1770441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1771441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find out whether we have other sections we might need. */ 1772cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *runscn = NULL; 1773441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL) 1774441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1775441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr runshdr_mem; 1776441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem); 1777441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1778cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (runshdr != NULL)) 1779441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1780441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (runshdr->sh_type == SHT_GNU_versym 1781441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && runshdr->sh_link == elf_ndxscn (scn)) 1782441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Bingo, found the version information. Now get the data. */ 1783441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project versym_data = elf_getdata (runscn, NULL); 1784441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (runshdr->sh_type == SHT_GNU_verneed) 1785441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1786441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This is the information about the needed versions. */ 1787441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project verneed_data = elf_getdata (runscn, NULL); 1788441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project verneed_stridx = runshdr->sh_link; 1789441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1790441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (runshdr->sh_type == SHT_GNU_verdef) 1791441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1792441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This is the information about the defined versions. */ 1793441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project verdef_data = elf_getdata (runscn, NULL); 1794441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project verdef_stridx = runshdr->sh_link; 1795441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1796441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (runshdr->sh_type == SHT_SYMTAB_SHNDX 1797441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && runshdr->sh_link == elf_ndxscn (scn)) 1798441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Extended section index. */ 1799441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndx_data = elf_getdata (runscn, NULL); 1800441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1801441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1802441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1803441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 1804cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 1805cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 1806441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 1807441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 1808441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1809441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Now we can compute the number of entries in the section. */ 1810cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int nsyms = data->d_size / (class == ELFCLASS32 1811cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? sizeof (Elf32_Sym) 1812cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : sizeof (Elf64_Sym)); 1813441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1814441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n", 1815441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\nSymbol table [%2u] '%s' contains %u entries:\n", 1816441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nsyms), 1817441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) elf_ndxscn (scn), 1818441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms); 1819cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr glink; 1820441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n", 1821441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " %lu local symbols String table: [%2u] '%s'\n", 1822441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_info), 1823441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned long int) shdr->sh_info, 1824441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) shdr->sh_link, 1825441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, 1826441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 1827441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &glink)->sh_name)); 1828441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1829441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (class == ELFCLASS32 1830441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? gettext ("\ 1831441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Num: Value Size Type Bind Vis Ndx Name\n") 1832441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gettext ("\ 1833441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Num: Value Size Type Bind Vis Ndx Name\n"), 1834441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stdout); 1835441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1836cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (unsigned int cnt = 0; cnt < nsyms; ++cnt) 1837441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1838441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char typebuf[64]; 1839441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char bindbuf[64]; 1840441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char scnbuf[64]; 1841441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word xndx; 1842441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym sym_mem; 1843441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx); 1844441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1845cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (sym == NULL)) 1846441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 1847441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1848441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Determine the real section index. */ 1849cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (sym->st_shndx != SHN_XINDEX)) 1850441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndx = sym->st_shndx; 1851441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1852441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 1853441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project%5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"), 1854441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, 1855441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 8 : 16, 1856441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sym->st_value, 1857441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sym->st_size, 1858441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 1859441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project typebuf, sizeof (typebuf)), 1860441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), 1861441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bindbuf, sizeof (bindbuf)), 1862441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)), 1863441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf, 1864441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sizeof (scnbuf), NULL, shnum), 1865441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, sym->st_name)); 1866441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1867441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (versym_data != NULL) 1868441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1869441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the version information. */ 1870441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Versym versym_mem; 1871cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem); 1872441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1873441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1)) 1874441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1875441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool is_nobits = false; 1876441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool check_def = xndx != SHN_UNDEF; 1877441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1878441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX) 1879441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1880441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr symshdr_mem; 1881441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *symshdr = 1882441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem); 1883441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1884441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project is_nobits = (symshdr != NULL 1885441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && symshdr->sh_type == SHT_NOBITS); 1886441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1887441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1888441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (is_nobits || ! check_def) 1889441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1890441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We must test both. */ 1891441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Vernaux vernaux_mem; 1892441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Vernaux *vernaux = NULL; 1893441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t vn_offset = 0; 1894441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1895cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verneed verneed_mem; 1896cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0, 1897cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &verneed_mem); 1898441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (verneed != NULL) 1899441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1900441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t vna_offset = vn_offset; 1901441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1902441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vernaux = gelf_getvernaux (verneed_data, 1903441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vna_offset += verneed->vn_aux, 1904441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &vernaux_mem); 1905441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (vernaux != NULL 1906441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && vernaux->vna_other != *versym 1907441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && vernaux->vna_next != 0) 1908441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1909441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Update the offset. */ 1910441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vna_offset += vernaux->vna_next; 1911441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1912441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vernaux = (vernaux->vna_next == 0 1913441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? NULL 1914441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gelf_getvernaux (verneed_data, 1915441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vna_offset, 1916441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &vernaux_mem)); 1917441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1918441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1919441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check whether we found the version. */ 1920441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (vernaux != NULL && vernaux->vna_other == *versym) 1921441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Found it. */ 1922441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1923441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1924441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vn_offset += verneed->vn_next; 1925441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project verneed = (verneed->vn_next == 0 1926441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? NULL 1927441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gelf_getverneed (verneed_data, vn_offset, 1928441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &verneed_mem)); 1929441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1930441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1931441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (vernaux != NULL && vernaux->vna_other == *versym) 1932441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1933441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("@%s (%u)", 1934441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, verneed_stridx, 1935441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vernaux->vna_name), 1936441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) vernaux->vna_other); 1937441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_def = 0; 1938441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1939cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (unlikely (! is_nobits)) 1940441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("bad dynamic symbol")); 1941441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1942441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_def = 1; 1943441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1944441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1945441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (check_def && *versym != 0x8001) 1946441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1947441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We must test both. */ 1948441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t vd_offset = 0; 1949441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1950cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdef verdef_mem; 1951cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0, 1952cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &verdef_mem); 1953441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (verdef != NULL) 1954441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1955441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (verdef->vd_ndx == (*versym & 0x7fff)) 1956441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Found the definition. */ 1957441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1958441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1959441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vd_offset += verdef->vd_next; 1960441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project verdef = (verdef->vd_next == 0 1961441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? NULL 1962441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project : gelf_getverdef (verdef_data, vd_offset, 1963441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &verdef_mem)); 1964441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1965441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1966441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (verdef != NULL) 1967441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1968441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Verdaux verdaux_mem; 1969cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdaux *verdaux 1970cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng = gelf_getverdaux (verdef_data, 1971cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng vd_offset + verdef->vd_aux, 1972cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &verdaux_mem); 1973441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1974441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (verdaux != NULL) 1975441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ((*versym & 0x8000) ? "@%s" : "@@%s", 1976441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, verdef_stridx, 1977441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project verdaux->vda_name)); 1978441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1979441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1980441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1981441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1982441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1983cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng putchar_unlocked ('\n'); 1984441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1985441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1986441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1987441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1988441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print version information. */ 1989441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1990cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_verinfo (Ebl *ebl) 1991441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1992441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find the version information sections. For this we have to 1993441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project search through the section table. */ 1994441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = NULL; 1995441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1996441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1997441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1998441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Handle the section if it is part of the versioning handling. */ 1999441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 2000441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2001441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2002cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (shdr != NULL)) 2003441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2004441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_type == SHT_GNU_verneed) 2005cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_verneed (ebl, scn, shdr); 2006441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (shdr->sh_type == SHT_GNU_verdef) 2007cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_verdef (ebl, scn, shdr); 2008441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (shdr->sh_type == SHT_GNU_versym) 2009cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_versym (ebl, scn, shdr); 2010441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2011441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2012441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2013441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2014441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2015441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char * 2016441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectget_ver_flags (unsigned int flags) 2017441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2018441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static char buf[32]; 2019441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char *endp; 2020441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2021441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (flags == 0) 2022441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return gettext ("none"); 2023441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2024441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (flags & VER_FLG_BASE) 2025441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project endp = stpcpy (buf, "BASE "); 2026441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2027441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project endp = buf; 2028441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2029441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (flags & VER_FLG_WEAK) 2030441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2031441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (endp != buf) 2032441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project endp = stpcpy (endp, "| "); 2033441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2034441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project endp = stpcpy (endp, "WEAK "); 2035441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2036441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2037cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))) 2038441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2039441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp); 2040441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf[sizeof (buf) - 1] = '\0'; 2041441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2042441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2043441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return buf; 2044441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2045441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2046441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2047441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 2048cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2049441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2050441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int class = gelf_getclass (ebl->elf); 2051441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2052441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data of the section. */ 2053cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 2054441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 2055441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2056441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2057441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 2058cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 2059cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 2060441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 2061441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 2062441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2063cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr glink; 2064441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 2065441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2066441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 2067441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2068441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_info), 2069441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) elf_ndxscn (scn), 2070441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info, 2071441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 2072441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset, 2073441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) shdr->sh_link, 2074441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, 2075441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2076441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &glink)->sh_name)); 2077441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2078cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int offset = 0; 2079cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int cnt = shdr->sh_info; --cnt >= 0; ) 2080441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2081441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data at the next offset. */ 2082cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verneed needmem; 2083cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 2084cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (need == NULL)) 2085441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2086441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2087441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"), 2088441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset, (unsigned short int) need->vn_version, 2089441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, need->vn_file), 2090441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned short int) need->vn_cnt); 2091441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2092cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int auxoffset = offset + need->vn_aux; 2093cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2094441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2095441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Vernaux auxmem; 2096cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 2097cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (aux == NULL)) 2098441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2099441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"), 2101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project auxoffset, 2102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name), 2103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_ver_flags (aux->vna_flags), 2104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned short int) aux->vna_other); 2105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project auxoffset += aux->vna_next; 2107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find the next offset. */ 2110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += need->vn_next; 2111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 2116cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data of the section. */ 2119cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 2120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 2121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 2124cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 2125cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 2126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 2127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 2128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2129cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int class = gelf_getclass (ebl->elf); 2130cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr glink; 2131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 2132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 2134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_info), 2136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) elf_ndxscn (scn), 2137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_info, 2139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 2140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset, 2141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) shdr->sh_link, 2142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, 2143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &glink)->sh_name)); 2145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2146cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int offset = 0; 2147cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int cnt = shdr->sh_info; --cnt >= 0; ) 2148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data at the next offset. */ 2150cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdef defmem; 2151cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 2152cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (def == NULL)) 2153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2155cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int auxoffset = offset + def->vd_aux; 2156cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdaux auxmem; 2157cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 2158cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (aux == NULL)) 2159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 2162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"), 2163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset, def->vd_version, 2164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_ver_flags (def->vd_flags), 2165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project def->vd_ndx, 2166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project def->vd_cnt, 2167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); 2168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project auxoffset += aux->vda_next; 2170cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 2171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project aux = gelf_getverdaux (data, auxoffset, &auxmem); 2173cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (aux == NULL)) 2174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" %#06x: Parent %d: %s\n"), 2177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project auxoffset, cnt2, 2178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); 2179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project auxoffset += aux->vda_next; 2181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find the next offset. */ 2184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += def->vd_next; 2185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 2190cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int class = gelf_getclass (ebl->elf); 2193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char **vername; 2194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char **filename; 2195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data of the section. */ 2197cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 2198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 2199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 2202cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 2203cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 2204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 2205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 2206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We have to find the version definition section and extract the 2208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project version names. */ 2209cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *defscn = NULL; 2210cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *needscn = NULL; 2211441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2212cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *verscn = NULL; 2213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL) 2214441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr vershdr_mem; 2216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem); 2217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2218cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (vershdr != NULL)) 2219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (vershdr->sh_type == SHT_GNU_verdef) 2221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project defscn = verscn; 2222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (vershdr->sh_type == SHT_GNU_verneed) 2223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project needscn = verscn; 2224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2227cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t nvername; 2228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (defscn != NULL || needscn != NULL) 2229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We have a version information (better should have). Now get 2231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project the version names. First find the maximum version number. */ 2232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nvername = 0; 2233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (defscn != NULL) 2234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Run through the version definitions and find the highest 2236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project index. */ 2237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int offset = 0; 2238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *defdata; 2239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr defshdrmem; 2240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *defshdr; 2241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project defdata = elf_getdata (defscn, NULL); 2243cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (defdata == NULL)) 2244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project defshdr = gelf_getshdr (defscn, &defshdrmem); 2247cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (defshdr == NULL)) 2248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2250cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) 2251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Verdef defmem; 2253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Verdef *def; 2254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data at the next offset. */ 2256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project def = gelf_getverdef (defdata, offset, &defmem); 2257cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (def == NULL)) 2258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff)); 2261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += def->vd_next; 2263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (needscn != NULL) 2266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int offset = 0; 2268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *needdata; 2269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr needshdrmem; 2270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *needshdr; 2271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project needdata = elf_getdata (needscn, NULL); 2273cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (needdata == NULL)) 2274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project needshdr = gelf_getshdr (needscn, &needshdrmem); 2277cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (needshdr == NULL)) 2278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2280cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) 2281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Verneed needmem; 2283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Verneed *need; 2284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int auxoffset; 2285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int cnt2; 2286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data at the next offset. */ 2288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project need = gelf_getverneed (needdata, offset, &needmem); 2289cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (need == NULL)) 2290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Run through the auxiliary entries. */ 2293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project auxoffset = offset + need->vn_aux; 2294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Vernaux auxmem; 2297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Vernaux *aux; 2298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project aux = gelf_getvernaux (needdata, auxoffset, &auxmem); 2300cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (aux == NULL)) 2301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nvername = MAX (nvername, 2304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (size_t) (aux->vna_other & 0x7fff)); 2305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project auxoffset += aux->vna_next; 2307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += need->vn_next; 2310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This is the number of versions we know about. */ 2314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++nvername; 2315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Allocate the array. */ 2317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vername = (const char **) alloca (nvername * sizeof (const char *)); 2318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project filename = (const char **) alloca (nvername * sizeof (const char *)); 2319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Run through the data structures again and collect the strings. */ 2321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (defscn != NULL) 2322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Run through the version definitions and find the highest 2324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project index. */ 2325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int offset = 0; 2326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *defdata; 2327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr defshdrmem; 2328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *defshdr; 2329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project defdata = elf_getdata (defscn, NULL); 2331cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (defdata == NULL)) 2332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project defshdr = gelf_getshdr (defscn, &defshdrmem); 2335cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (defshdr == NULL)) 2336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2338cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) 2339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data at the next offset. */ 2342cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdef defmem; 2343cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem); 2344cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdaux auxmem; 2345cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verdaux *aux = gelf_getverdaux (defdata, 2346cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng offset + def->vd_aux, 2347cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &auxmem); 2348cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (def == NULL || aux == NULL)) 2349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vername[def->vd_ndx & 0x7fff] 2352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name); 2353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project filename[def->vd_ndx & 0x7fff] = NULL; 2354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += def->vd_next; 2356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (needscn != NULL) 2359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int offset = 0; 2361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2362cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *needdata = elf_getdata (needscn, NULL); 2363cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr needshdrmem; 2364cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem); 2365cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (needdata == NULL || needshdr == NULL)) 2366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2368cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) 2369441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2370441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the data at the next offset. */ 2371cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verneed needmem; 2372cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Verneed *need = gelf_getverneed (needdata, offset, 2373cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &needmem); 2374cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (need == NULL)) 2375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Run through the auxiliary entries. */ 2378cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int auxoffset = offset + need->vn_aux; 2379cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Vernaux auxmem; 2382cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset, 2383cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &auxmem); 2384cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (aux == NULL)) 2385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vername[aux->vna_other & 0x7fff] 2388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name); 2389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project filename[aux->vna_other & 0x7fff] 2390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file); 2391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project auxoffset += aux->vna_next; 2393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += need->vn_next; 2396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project vername = NULL; 2402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nvername = 1; 2403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project filename = NULL; 2404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Print the header. */ 2407cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr glink; 2408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 2409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", 2410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 2411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", 2412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_size / shdr->sh_entsize), 2413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) elf_ndxscn (scn), 2414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) (shdr->sh_size / shdr->sh_entsize), 2416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 2417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset, 2418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) shdr->sh_link, 2419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, 2420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &glink)->sh_name)); 2422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Now we can finally look at the actual contents of this section. */ 2424cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 2425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt % 2 == 0) 2427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("\n %4d:", cnt); 2428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2429cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Versym symmem; 2430cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Versym *sym = gelf_getversym (data, cnt, &symmem); 2431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym == NULL) 2432441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2434441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (*sym) 2435441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2436cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ssize_t n; 2437441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 0: 2438441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (gettext (" 0 *local* "), 2439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stdout); 2440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2441441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 1: 2443441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fputs_unlocked (gettext (" 1 *global* "), 2444441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stdout); 2445441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2446441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2447441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 2448441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project n = printf ("%4d%c%s", 2449441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ', 2450441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) (*sym & 0x7fff) < nvername 2451441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? vername[*sym & 0x7fff] : "???"); 2452441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((unsigned int) (*sym & 0x7fff) < nvername 2453441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && filename[*sym & 0x7fff] != NULL) 2454441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project n += printf ("(%s)", filename[*sym & 0x7fff]); 2455441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%*s", MAX (0, 33 - (int) n), " "); 2456441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2457441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2458441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2459cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng putchar_unlocked ('\n'); 2460441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2461441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2462441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2463441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 2464cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx, 2465cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t maxlength, Elf32_Word nbucket, 2466cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr) 2467441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2468cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t)); 2469441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2470cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 2471cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++counts[lengths[cnt]]; 2472441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2473cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr glink; 2474cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (ngettext ("\ 2475cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben 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", 2476cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng "\ 2477cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben 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", 2478cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng nbucket), 2479cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (unsigned int) elf_ndxscn (scn), 2480cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2481cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) nbucket, 2482cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18, 2483cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng shdr->sh_addr, 2484cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng shdr->sh_offset, 2485cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (unsigned int) shdr->sh_link, 2486cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_strptr (ebl->elf, shstrndx, 2487cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2488cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &glink)->sh_name)); 2489cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2490cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (extrastr != NULL) 2491cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs (extrastr, stdout); 2492cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2493cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (nbucket > 0)) 2494441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2495cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint64_t success = 0; 2496cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2497cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs_unlocked (gettext ("\ 2498cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Length Number % of total Coverage\n"), stdout); 2499cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"), 2500cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng counts[0], (counts[0] * 100.0) / nbucket); 2501441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2502cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint64_t nzero_counts = 0; 2503cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) 2504441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2505cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng nzero_counts += counts[cnt] * cnt; 2506cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\ 2507cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng%7d %6" PRIu32 " %5.1f%% %5.1f%%\n"), 2508cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket, 2509cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (nzero_counts * 100.0) / nsyms); 2510cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2511441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2512cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word acc = 0; 2513cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) 2514cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2515cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng acc += cnt; 2516cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng success += counts[cnt] * acc; 2517cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2518441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2519cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\ 2520cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Average number of tests: successful lookup: %f\n\ 2521cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsuccessful lookup: %f\n"), 2522cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (double) success / (double) nzero_counts, 2523cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (double) nzero_counts / (double) nbucket); 2524cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2525441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2526cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (counts); 2527cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 2528441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2529441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2530cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* This function handles the traditional System V-style hash table format. */ 2531cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 2532cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 2533cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 2534cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 2535cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data == NULL)) 2536cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2537cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot get data for section %d: %s"), 2538cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) elf_ndxscn (scn), elf_errmsg (-1)); 2539cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 2540cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2541441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2542cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 2543cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 2544cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2]; 2545cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket]; 2546441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2547cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 2548441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2549cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t maxlength = 0; 2550cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t nsyms = 0; 2551cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 2552cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2553cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word inner = bucket[cnt]; 2554cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (inner > 0 && inner < nchain) 2555cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2556cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++nsyms; 2557cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (maxlength < ++lengths[cnt]) 2558cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++maxlength; 2559441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2560cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng inner = chain[inner]; 2561cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2562cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2563441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2564cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 2565cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng lengths, NULL); 2566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2567cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (lengths); 2568cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 2569441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2570441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2571cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* This function handles the incorrect, System V-style hash table 2572cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng format some 64-bit architectures use. */ 2573cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 2574cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 2575cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 2576cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 2577cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data == NULL)) 2578cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2579cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot get data for section %d: %s"), 2580cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) elf_ndxscn (scn), elf_errmsg (-1)); 2581cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 2582cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2583441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2584cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; 2585cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; 2586cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2]; 2587cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket]; 2588cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2589cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 2590cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2591cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t maxlength = 0; 2592cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t nsyms = 0; 2593cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) 2594cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2595cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf64_Xword inner = bucket[cnt]; 2596cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (inner > 0 && inner < nchain) 2597cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2598cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++nsyms; 2599cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (maxlength < ++lengths[cnt]) 2600cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++maxlength; 2601cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2602cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng inner = chain[inner]; 2603cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2604cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2605cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2606cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 2607cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng lengths, NULL); 2608cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2609cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (lengths); 2610cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 2611cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2612cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2613cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* This function handles the GNU-style hash table format. */ 2614cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 2615cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 2616cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 2617cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata (scn, NULL); 2618cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data == NULL)) 2619cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2620cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot get data for section %d: %s"), 2621cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) elf_ndxscn (scn), elf_errmsg (-1)); 2622cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 2623cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2624cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2625cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 2626cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; 2627cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2628cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Next comes the size of the bitmap. It's measured in words for 2629cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng the architecture. It's 32 bits for 32 bit archs, and 64 bits for 2630cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 64 bit archs. */ 2631cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; 2632cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (gelf_getclass (ebl->elf) == ELFCLASS64) 2633cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bitmask_words *= 2; 2634cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2635cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; 2636cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2637cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 2638cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2639cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4]; 2640cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words]; 2641cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words 2642cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng + nbucket]; 2643cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2644cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Compute distribution of chain lengths. */ 2645cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t maxlength = 0; 2646cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t nsyms = 0; 2647cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 2648cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (bucket[cnt] != 0) 2649cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2650cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf32_Word inner = bucket[cnt] - symbias; 2651cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng do 2652cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2653cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++nsyms; 2654cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (maxlength < ++lengths[cnt]) 2655cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++maxlength; 2656cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2657cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while ((chain[inner++] & 1) == 0); 2658cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2659cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2660cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Count bits in bitmask. */ 2661cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t nbits = 0; 2662cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt) 2663cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2664cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast32_t word = bitmask[cnt]; 2665cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2666cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng word = (word & 0x55555555) + ((word >> 1) & 0x55555555); 2667cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng word = (word & 0x33333333) + ((word >> 2) & 0x33333333); 2668cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f); 2669cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff); 2670cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff); 2671cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2672cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2673cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *str; 2674cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (asprintf (&str, gettext ("\ 2675cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Symbol Bias: %u\n\ 2676cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"), 2677cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (unsigned int) symbias, 2678cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bitmask_words * sizeof (Elf32_Word), 2679cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ((nbits * 100 + 50) 2680cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng / (uint_fast32_t) (bitmask_words 2681cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng * sizeof (Elf32_Word) * 8)), 2682cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (unsigned int) shift) == -1)) 2683cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, gettext ("memory exhausted")); 2684cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2685cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 2686cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng lengths, str); 2687cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2688cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (str); 2689cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (lengths); 2690cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 2691cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2692cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2693cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Find the symbol table(s). For this we have to search through the 2694cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng section table. */ 2695cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 2696cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_hash (Ebl *ebl) 2697cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 2698cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Get the section header string table index. */ 2699cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 2700cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 2701cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 2702cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot get section header string table index")); 2703441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2704cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn = NULL; 2705cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2706cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2707cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Handle the section if it is a symbol table. */ 2708cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr shdr_mem; 2709cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2710cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2711cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (shdr != NULL)) 2712cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2713cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shdr->sh_type == SHT_HASH) 2714cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2715cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) 2716cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_sysv_hash64 (ebl, scn, shdr, shstrndx); 2717cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 2718cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_sysv_hash (ebl, scn, shdr, shstrndx); 2719cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2720cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (shdr->sh_type == SHT_GNU_HASH) 2721cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_gnu_hash (ebl, scn, shdr, shstrndx); 2722441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2723441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2724441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2725441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2726441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2727441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 2728cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_liblist (Ebl *ebl) 2729441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2730441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find the library list sections. For this we have to search 2731441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project through the section table. */ 2732441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = NULL; 2733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2734441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 2735441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t shstrndx; 2736cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 2737441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 2738441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 2739441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2740441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2741441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2742441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 2743441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2744441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2745441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST) 2746441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2747441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int nentries = shdr->sh_size / shdr->sh_entsize; 2748441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 2749441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 2750441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 2751441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 2752441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nentries), 2753441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_ndxscn (scn), 2754441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2755441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset, 2756441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nentries); 2757441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2758441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data = elf_getdata (scn, NULL); 2759441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 2760441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2761441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2762441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("\ 2763441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Library Time Stamp Checksum Version Flags")); 2764441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2765441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (int cnt = 0; cnt < nentries; ++cnt) 2766441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2767441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Lib lib_mem; 2768441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem); 2769cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (lib == NULL)) 2770441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 2771441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2772441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project time_t t = (time_t) lib->l_time_stamp; 2773441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct tm *tm = gmtime (&t); 2774cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (tm == NULL)) 2775441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 2776441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2777441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n", 2778441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name), 2779441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 2780441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project tm->tm_hour, tm->tm_min, tm->tm_sec, 2781441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) lib->l_checksum, 2782441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) lib->l_version, 2783441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (unsigned int) lib->l_flags); 2784441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2785441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2786441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2787441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2788441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2789cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 2790cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_attributes (Ebl *ebl, const GElf_Ehdr *ehdr) 2791441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2792cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Find the object attributes sections. For this we have to search 2793cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng through the section table. */ 2794cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn = NULL; 2795cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2796cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Get the section header string table index. */ 2797cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 2798cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 2799cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 2800cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot get section header string table index")); 2801cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2802cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2803441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2804cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr shdr_mem; 2805cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2806cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2807cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shdr == NULL || shdr->sh_type != SHT_GNU_ATTRIBUTES) 2808cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 2809cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2810cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\ 2811cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng\nObject attributes section [%2zu] '%s' of %" PRIu64 2812cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng " bytes at offset %#0" PRIx64 ":\n"), 2813cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), 2814cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2815cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng shdr->sh_size, shdr->sh_offset); 2816cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2817cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_rawdata (scn, NULL); 2818cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (data == NULL) 2819cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 2820cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2821cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const unsigned char *p = data->d_buf; 2822cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2823cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (*p++ != 'A')) 2824cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 2825cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2826cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs_unlocked (gettext (" Owner Size\n"), stdout); 2827cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2828cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng inline size_t left (void) 2829cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2830cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return (const unsigned char *) data->d_buf + data->d_size - p; 2831cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2832cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2833cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (left () >= 4) 2834cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2835cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint32_t len; 2836cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng memcpy (&len, p, sizeof len); 2837cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2838cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 2839cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng CONVERT (len); 2840cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2841cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (len > left ())) 2842cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 2843cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2844cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const unsigned char *name = p + sizeof len; 2845cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng p += len; 2846cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2847cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned const char *q = memchr (name, '\0', len); 2848cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (q == NULL)) 2849cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 2850cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++q; 2851cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2852cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %-13s %4" PRIu32 "\n"), name, len); 2853cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2854cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (q - name == sizeof "gnu" 2855cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && !memcmp (name, "gnu", sizeof "gnu")) 2856cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (q < p) 2857cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2858cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const unsigned char *const sub = q; 2859cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2860cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int subsection_tag; 2861cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng get_uleb128 (subsection_tag, q); 2862cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (q >= p)) 2863cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 2864cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2865cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint32_t subsection_len; 2866cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len)) 2867cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 2868cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2869cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng memcpy (&subsection_len, q, sizeof subsection_len); 2870cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2871cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 2872cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng CONVERT (subsection_len); 2873cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2874cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (p - sub < (ptrdiff_t) subsection_len)) 2875cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 2876cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2877cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const unsigned char *r = q + sizeof subsection_len; 2878cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng q = sub + subsection_len; 2879cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2880cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (subsection_tag) 2881cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2882cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 2883cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %-4u %12" PRIu32 "\n"), 2884cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng subsection_tag, subsection_len); 2885cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 2886cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2887cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 1: /* Tag_File */ 2888cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" File: %11" PRIu32 "\n"), 2889cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng subsection_len); 2890cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2891cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (r < q) 2892cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2893cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int tag; 2894cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng get_uleb128 (tag, r); 2895cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (r >= q)) 2896cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 2897cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2898cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint64_t value = 0; 2899cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *string = NULL; 2900cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (tag == 32 || (tag & 1) == 0) 2901cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2902cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng get_uleb128 (value, r); 2903cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (r > q) 2904cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 2905cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2906cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (tag == 32 || (tag & 1) != 0) 2907cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2908cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng r = memchr (r, '\0', q - r); 2909cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (r == NULL) 2910cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 2911cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++r; 2912cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2913cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2914cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *tag_name = NULL; 2915cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *value_name = NULL; 2916cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ebl_check_object_attribute (ebl, (const char *) name, 2917cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng tag, value, 2918cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &tag_name, &value_name); 2919cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2920cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (tag_name != NULL) 2921cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2922cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (tag == 32) 2923cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %s: %" PRId64 ", %s\n"), 2924cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng tag_name, value, string); 2925cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (string == NULL && value_name == NULL) 2926cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %s: %" PRId64 "\n"), 2927cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng tag_name, value); 2928cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 2929cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %s: %s\n"), 2930cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng tag_name, string ?: value_name); 2931cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2932cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 2933cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 2934cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (tag != 32); 2935cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (string == NULL) 2936cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %u: %" PRId64 "\n"), 2937cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng tag, value); 2938cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 2939cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %u: %s\n"), 2940cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng tag, string); 2941cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2942cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2943cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2944cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2945cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2946cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 2947cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 2948cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2949cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2950cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic char * 2951cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengformat_dwarf_addr (Dwfl_Module *dwflmod, 2952cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int address_size, Dwarf_Addr address) 2953cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 2954cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* See if there is a name we can give for this address. */ 2955cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Sym sym; 2956cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *name = dwfl_module_addrsym (dwflmod, address, &sym, NULL); 2957cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (name != NULL) 2958cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng sym.st_value = address - sym.st_value; 2959cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2960cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Relativize the address. */ 2961cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int n = dwfl_module_relocations (dwflmod); 2962cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address); 2963cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2964cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* In an ET_REL file there is a section name to refer to. */ 2965cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *scn = (i < 0 ? NULL 2966cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : dwfl_module_relocation_info (dwflmod, i, NULL)); 2967cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2968cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *result; 2969cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if ((name != NULL 2970cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? (sym.st_value != 0 2971cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? (scn != NULL 2972cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? (address_size == 0 2973cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? asprintf (&result, 2974cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"), 2975cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn, address, name, sym.st_value) 2976cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : asprintf (&result, 2977cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"), 2978cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn, 2 + address_size * 2, address, 2979cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng name, sym.st_value)) 2980cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : (address_size == 0 2981cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? asprintf (&result, 2982cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"), 2983cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng address, name, sym.st_value) 2984cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : asprintf (&result, 2985cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"), 2986cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2 + address_size * 2, address, 2987cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng name, sym.st_value))) 2988cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : (scn != NULL 2989cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? (address_size == 0 2990cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? asprintf (&result, 2991cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%s+%#" PRIx64 " <%s>"), 2992cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn, address, name) 2993cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : asprintf (&result, 2994cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%s+%#0*" PRIx64 " <%s>"), 2995cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn, 2 + address_size * 2, address, name)) 2996cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : (address_size == 0 2997cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? asprintf (&result, 2998cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%#" PRIx64 " <%s>"), 2999cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng address, name) 3000cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : asprintf (&result, 3001cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%#0*" PRIx64 " <%s>"), 3002cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2 + address_size * 2, address, name)))) 3003cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : (scn != NULL 3004cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? (address_size == 0 3005cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? asprintf (&result, 3006cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%s+%#" PRIx64), 3007cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn, address) 3008cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : asprintf (&result, 3009cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("%s+%#0*" PRIx64), 3010cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn, 2 + address_size * 2, address)) 3011cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : (address_size == 0 3012cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? asprintf (&result, 3013cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng "%#" PRIx64, 3014cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng address) 3015cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : asprintf (&result, 3016cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng "%#0*" PRIx64, 3017cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2 + address_size * 2, address)))) < 0) 3018cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, _("memory exhausted")); 3019cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3020cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return result; 3021cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3022cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3023cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3024cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_tag_string (unsigned int tag) 3025cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3026cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known_tags[] = 3027cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3028cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_array_type] = "array_type", 3029cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_class_type] = "class_type", 3030cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_entry_point] = "entry_point", 3031cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_enumeration_type] = "enumeration_type", 3032cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_formal_parameter] = "formal_parameter", 3033cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_imported_declaration] = "imported_declaration", 3034cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_label] = "label", 3035cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_lexical_block] = "lexical_block", 3036cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_member] = "member", 3037cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_pointer_type] = "pointer_type", 3038cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_reference_type] = "reference_type", 3039cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_compile_unit] = "compile_unit", 3040cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_string_type] = "string_type", 3041cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_structure_type] = "structure_type", 3042cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_subroutine_type] = "subroutine_type", 3043cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_typedef] = "typedef", 3044cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_union_type] = "union_type", 3045cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_unspecified_parameters] = "unspecified_parameters", 3046cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_variant] = "variant", 3047cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_common_block] = "common_block", 3048cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_common_inclusion] = "common_inclusion", 3049cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_inheritance] = "inheritance", 3050cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_inlined_subroutine] = "inlined_subroutine", 3051cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_module] = "module", 3052cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_ptr_to_member_type] = "ptr_to_member_type", 3053cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_set_type] = "set_type", 3054cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_subrange_type] = "subrange_type", 3055cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_with_stmt] = "with_stmt", 3056cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_access_declaration] = "access_declaration", 3057cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_base_type] = "base_type", 3058cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_catch_block] = "catch_block", 3059cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_const_type] = "const_type", 3060cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_constant] = "constant", 3061cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_enumerator] = "enumerator", 3062cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_file_type] = "file_type", 3063cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_friend] = "friend", 3064cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_namelist] = "namelist", 3065cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_namelist_item] = "namelist_item", 3066cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_packed_type] = "packed_type", 3067cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_subprogram] = "subprogram", 3068cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_template_type_parameter] = "template_type_parameter", 3069cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_template_value_parameter] = "template_value_parameter", 3070441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_TAG_thrown_type] = "thrown_type", 3071441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_TAG_try_block] = "try_block", 3072441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_TAG_variant_part] = "variant_part", 3073441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_TAG_variable] = "variable", 3074441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_TAG_volatile_type] = "volatile_type", 3075cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_dwarf_procedure] = "dwarf_procedure", 3076cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_restrict_type] = "restrict_type", 3077cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_interface_type] = "interface_type", 3078cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_namespace] = "namespace", 3079cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_imported_module] = "imported_module", 3080cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_unspecified_type] = "unspecified_type", 3081cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_partial_unit] = "partial_unit", 3082cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_imported_unit] = "imported_unit", 3083cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_mutable_type] = "mutable_type", 3084cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_condition] = "condition", 3085cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_TAG_shared_type] = "shared_type", 3086441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 3087441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const unsigned int nknown_tags = (sizeof (known_tags) 3088441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project / sizeof (known_tags[0])); 3089441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static char buf[40]; 3090441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *result = NULL; 3091441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3092cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (tag < nknown_tags)) 3093441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = known_tags[tag]; 3094441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3095cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (result == NULL)) 3096441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* There are a few known extensions. */ 3097441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (tag) 3098441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3099441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_TAG_MIPS_loop: 3100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_loop"; 3101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_TAG_format_label: 3104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "format_label"; 3105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_TAG_function_template: 3108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "function_template"; 3109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_TAG_class_template: 3112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "class_template"; 3113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 3116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (tag < DW_TAG_lo_user) 3117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project snprintf (buf, sizeof buf, gettext ("unknown tag %hx"), tag); 3118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 3119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project snprintf (buf, sizeof buf, gettext ("unknown user tag %hx"), tag); 3120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = buf; 3121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 3123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return result; 3125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 3126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char * 3129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectdwarf_attr_string (unsigned int attrnum) 3130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 3131cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known_attrs[] = 3132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_sibling] = "sibling", 3134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_location] = "location", 3135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_name] = "name", 3136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_ordering] = "ordering", 3137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_subscr_data] = "subscr_data", 3138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_byte_size] = "byte_size", 3139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_bit_offset] = "bit_offset", 3140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_bit_size] = "bit_size", 3141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_element_list] = "element_list", 3142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_stmt_list] = "stmt_list", 3143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_low_pc] = "low_pc", 3144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_high_pc] = "high_pc", 3145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_language] = "language", 3146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_member] = "member", 3147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_discr] = "discr", 3148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_discr_value] = "discr_value", 3149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_visibility] = "visibility", 3150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_import] = "import", 3151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_string_length] = "string_length", 3152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_common_reference] = "common_reference", 3153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_comp_dir] = "comp_dir", 3154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_const_value] = "const_value", 3155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_containing_type] = "containing_type", 3156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_default_value] = "default_value", 3157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_inline] = "inline", 3158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_is_optional] = "is_optional", 3159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_lower_bound] = "lower_bound", 3160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_producer] = "producer", 3161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_prototyped] = "prototyped", 3162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_return_addr] = "return_addr", 3163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_start_scope] = "start_scope", 3164cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_bit_stride] = "bit_stride", 3165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_upper_bound] = "upper_bound", 3166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_abstract_origin] = "abstract_origin", 3167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_accessibility] = "accessibility", 3168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_address_class] = "address_class", 3169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_artificial] = "artificial", 3170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_base_types] = "base_types", 3171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_calling_convention] = "calling_convention", 3172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_count] = "count", 3173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_data_member_location] = "data_member_location", 3174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_decl_column] = "decl_column", 3175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_decl_file] = "decl_file", 3176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_decl_line] = "decl_line", 3177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_declaration] = "declaration", 3178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_discr_list] = "discr_list", 3179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_encoding] = "encoding", 3180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_external] = "external", 3181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_frame_base] = "frame_base", 3182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_friend] = "friend", 3183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_identifier_case] = "identifier_case", 3184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_macro_info] = "macro_info", 3185cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_namelist_item] = "namelist_item", 3186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_priority] = "priority", 3187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_segment] = "segment", 3188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_specification] = "specification", 3189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_static_link] = "static_link", 3190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_type] = "type", 3191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_use_location] = "use_location", 3192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_variable_parameter] = "variable_parameter", 3193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_AT_virtuality] = "virtuality", 3194cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_vtable_elem_location] = "vtable_elem_location", 3195cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_allocated] = "allocated", 3196cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_associated] = "associated", 3197cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_data_location] = "data_location", 3198cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_byte_stride] = "byte_stride", 3199cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_entry_pc] = "entry_pc", 3200cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_use_UTF8] = "use_UTF8", 3201cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_extension] = "extension", 3202cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_ranges] = "ranges", 3203cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_trampoline] = "trampoline", 3204cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_call_column] = "call_column", 3205cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_call_file] = "call_file", 3206cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_call_line] = "call_line", 3207cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_description] = "description", 3208cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_binary_scale] = "binary_scale", 3209cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_decimal_scale] = "decimal_scale", 3210cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_small] = "small", 3211cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_decimal_sign] = "decimal_sign", 3212cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_digit_count] = "digit_count", 3213cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_picture_string] = "picture_string", 3214cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_mutable] = "mutable", 3215cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_threads_scaled] = "threads_scaled", 3216cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_explicit] = "explicit", 3217cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_object_pointer] = "object_pointer", 3218cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_endianity] = "endianity", 3219cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_elemental] = "elemental", 3220cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_pure] = "pure", 3221cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_AT_recursive] = "recursive", 3222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 3223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const unsigned int nknown_attrs = (sizeof (known_attrs) 3224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project / sizeof (known_attrs[0])); 3225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static char buf[40]; 3226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *result = NULL; 3227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3228cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (attrnum < nknown_attrs)) 3229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = known_attrs[attrnum]; 3230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3231cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (result == NULL)) 3232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* There are a few known extensions. */ 3233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (attrnum) 3234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_fde: 3236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_fde"; 3237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_loop_begin: 3240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_loop_begin"; 3241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_tail_loop_begin: 3244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_tail_loop_begin"; 3245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_epilog_begin: 3248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_epilog_begin"; 3249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_loop_unroll_factor: 3252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_loop_unroll_factor"; 3253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_software_pipeline_depth: 3256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_software_pipeline_depth"; 3257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_linkage_name: 3260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_linkage_name"; 3261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_stride: 3264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_stride"; 3265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_abstract_name: 3268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_abstract_name"; 3269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_clone_origin: 3272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_clone_origin"; 3273441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_has_inlines: 3276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_has_inlines"; 3277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_stride_byte: 3280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_stride_byte"; 3281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_stride_elem: 3284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_stride_elem"; 3285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_ptr_dopetype: 3288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_ptr_dopetype"; 3289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_allocatable_dopetype: 3292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_allocatable_dopetype"; 3293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_assumed_shape_dopetype: 3296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_assumed_shape_dopetype"; 3297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_MIPS_assumed_size: 3300441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "MIPS_assumed_size"; 3301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_sf_names: 3304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "sf_names"; 3305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_src_info: 3308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "src_info"; 3309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_mac_info: 3312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "mac_info"; 3313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_src_coords: 3316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "src_coords"; 3317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_body_begin: 3320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "body_begin"; 3321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_AT_body_end: 3324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = "body_end"; 3325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 3328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (attrnum < DW_AT_lo_user) 3329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project snprintf (buf, sizeof buf, gettext ("unknown attribute %hx"), 3330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project attrnum); 3331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 3332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project snprintf (buf, sizeof buf, gettext ("unknown user attribute %hx"), 3333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project attrnum); 3334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = buf; 3335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 3337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return result; 3339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 3340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char * 3343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectdwarf_form_string (unsigned int form) 3344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 3345cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known_forms[] = 3346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_addr] = "addr", 3348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_block2] = "block2", 3349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_block4] = "block4", 3350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_data2] = "data2", 3351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_data4] = "data4", 3352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_data8] = "data8", 3353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_string] = "string", 3354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_block] = "block", 3355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_block1] = "block1", 3356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_data1] = "data1", 3357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_flag] = "flag", 3358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_sdata] = "sdata", 3359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_strp] = "strp", 3360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_udata] = "udata", 3361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_ref_addr] = "ref_addr", 3362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_ref1] = "ref1", 3363441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_ref2] = "ref2", 3364441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_ref4] = "ref4", 3365441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_ref8] = "ref8", 3366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_ref_udata] = "ref_udata", 3367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_FORM_indirect] = "indirect" 3368441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 3369441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const unsigned int nknown_forms = (sizeof (known_forms) 3370441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project / sizeof (known_forms[0])); 3371441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static char buf[40]; 3372441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *result = NULL; 3373441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3374cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (form < nknown_forms)) 3375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project result = known_forms[form]; 3376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3377cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (result == NULL)) 3378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project snprintf (buf, sizeof buf, gettext ("unknown form %" PRIx64), 3379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) form); 3380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return result; 3382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 3383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char * 3386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectdwarf_lang_string (unsigned int lang) 3387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 3388cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_C89] = "ISO C89", 3391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_C] = "C", 3392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Ada83] = "Ada83", 3393cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_LANG_C_plus_plus] = "C++", 3394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Cobol74] = "Cobol74", 3395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Cobol85] = "Cobol85", 3396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Fortran77] = "Fortran77", 3397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Fortran90] = "Fortran90", 3398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Pascal83] = "Pascal83", 3399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Modula2] = "Modula2", 3400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Java] = "Java", 3401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_C99] = "ISO C99", 3402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Ada95] = "Ada95", 3403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_LANG_Fortran95] = "Fortran95", 3404cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_LANG_PL1] = "PL1", 3405cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_LANG_Objc] = "Objective C", 3406cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_LANG_ObjC_plus_plus] = "Objective C++", 3407cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_LANG_UPC] = "UPC", 3408cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_LANG_D] = "D", 3409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 3410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3411cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (lang < sizeof (known) / sizeof (known[0]))) 3412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return known[lang]; 3413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (lang == DW_LANG_Mips_Assembler) 3414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This language tag is used for assembler in general. */ 3415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return "Assembler"; 3416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (lang >= DW_LANG_lo_user && lang <= DW_LANG_hi_user) 3418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3419cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static char buf[30]; 3420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project snprintf (buf, sizeof (buf), "lo_user+%u", lang - DW_LANG_lo_user); 3421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return buf; 3422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 3423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return "???"; 3425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 3426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3428cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3429cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_inline_string (unsigned int code) 3430cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3431cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3432cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3433cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_INL_not_inlined] = "not_inlined", 3434cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_INL_inlined] = "inlined", 3435cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_INL_declared_not_inlined] = "declared_not_inlined", 3436cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_INL_declared_inlined] = "declared_inlined" 3437cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3438cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3439cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3440cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3441cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3442cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3443cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3444cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3445cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3446cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3447cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_encoding_string (unsigned int code) 3448cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3449cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3450cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3451cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_void] = "void", 3452cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_address] = "address", 3453cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_boolean] = "boolean", 3454cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_complex_float] = "complex_float", 3455cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_float] = "float", 3456cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_signed] = "signed", 3457cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_signed_char] = "signed_char", 3458cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_unsigned] = "unsigned", 3459cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_unsigned_char] = "unsigned_char", 3460cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_imaginary_float] = "imaginary_float", 3461cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_packed_decimal] = "packed_decimal", 3462cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_numeric_string] = "numeric_string", 3463cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_edited] = "edited", 3464cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_signed_fixed] = "signed_fixed", 3465cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_unsigned_fixed] = "unsigned_fixed", 3466cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ATE_decimal_float] = "decimal_float", 3467cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3468cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3469cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3470cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3471cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3472cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user) 3473cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3474cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static char buf[30]; 3475cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_ATE_lo_user); 3476cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return buf; 3477cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 3478cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3479cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3480cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3481cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3482cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3483cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3484cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_access_string (unsigned int code) 3485cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3486cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3487cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3488cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ACCESS_public] = "public", 3489cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ACCESS_protected] = "protected", 3490cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ACCESS_private] = "private" 3491cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3492cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3493cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3494cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3495cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3496cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3497cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3498cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3499cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3500cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3501cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_visibility_string (unsigned int code) 3502cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3503cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3504cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3505cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_VIS_local] = "local", 3506cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_VIS_exported] = "exported", 3507cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_VIS_qualified] = "qualified" 3508cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3509cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3510cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3511cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3512cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3513cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3514cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3515cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3516cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3517cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3518cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_virtuality_string (unsigned int code) 3519cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3520cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3521cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3522cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_VIRTUALITY_none] = "none", 3523cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_VIRTUALITY_virtual] = "virtual", 3524cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_VIRTUALITY_pure_virtual] = "pure_virtual" 3525cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3526cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3527cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3528cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3529cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3530cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3531cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3532cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3533cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3534cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3535cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_identifier_case_string (unsigned int code) 3536cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3537cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3538cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3539cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ID_case_sensitive] = "sensitive", 3540cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ID_up_case] = "up_case", 3541cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ID_down_case] = "down_case", 3542cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ID_case_insensitive] = "insensitive" 3543cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3544cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3545cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3546cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3547cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3548cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3549cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3550cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3551cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3552cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3553cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_calling_convention_string (unsigned int code) 3554cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3555cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3556cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3557cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_CC_normal] = "normal", 3558cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_CC_program] = "program", 3559cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_CC_nocall] = "nocall", 3560cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3561cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3562cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3563cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3564cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3565cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (code >= DW_CC_lo_user && code <= DW_CC_hi_user) 3566cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3567cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static char buf[30]; 3568cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_CC_lo_user); 3569cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return buf; 3570cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 3571cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3572cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3573cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3574cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3575cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3576cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3577cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_ordering_string (unsigned int code) 3578cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3579cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3580cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3581cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ORD_row_major] = "row_major", 3582cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_ORD_col_major] = "col_major" 3583cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3584cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3585cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3586cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3587cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3588cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3589cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3590cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3591cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3592cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char * 3593cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdwarf_discr_list_string (unsigned int code) 3594cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 3595cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3596cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3597cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_DSC_label] = "label", 3598cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_DSC_range] = "range" 3599cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 3600cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3601cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (code < sizeof (known) / sizeof (known[0]))) 3602cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return known[code]; 3603cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3604cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return "???"; 3605cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 3606cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3607cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3608441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 3609cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, 3610cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int addrsize, Dwarf_Word len, const unsigned char *data) 3611441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 3612cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng static const char *const known[] = 3613441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3614441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_addr] = "addr", 3615441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_deref] = "deref", 3616441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_const1u] = "const1u", 3617441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_const1s] = "const1s", 3618441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_const2u] = "const2u", 3619441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_const2s] = "const2s", 3620441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_const4u] = "const4u", 3621441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_const4s] = "const4s", 3622441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_const8u] = "const8u", 3623441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_const8s] = "const8s", 3624441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_constu] = "constu", 3625441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_consts] = "consts", 3626441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_dup] = "dup", 3627441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_drop] = "drop", 3628441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_over] = "over", 3629441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_pick] = "pick", 3630441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_swap] = "swap", 3631441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_rot] = "rot", 3632441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_xderef] = "xderef", 3633441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_abs] = "abs", 3634441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_and] = "and", 3635441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_div] = "div", 3636441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_minus] = "minus", 3637441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_mod] = "mod", 3638441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_mul] = "mul", 3639441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_neg] = "neg", 3640441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_not] = "not", 3641441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_or] = "or", 3642441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_plus] = "plus", 3643441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_plus_uconst] = "plus_uconst", 3644441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_shl] = "shl", 3645441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_shr] = "shr", 3646441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_shra] = "shra", 3647441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_xor] = "xor", 3648441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_bra] = "bra", 3649441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_eq] = "eq", 3650441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_ge] = "ge", 3651441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_gt] = "gt", 3652441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_le] = "le", 3653441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lt] = "lt", 3654441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_ne] = "ne", 3655441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_skip] = "skip", 3656441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit0] = "lit0", 3657441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit1] = "lit1", 3658441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit2] = "lit2", 3659441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit3] = "lit3", 3660441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit4] = "lit4", 3661441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit5] = "lit5", 3662441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit6] = "lit6", 3663441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit7] = "lit7", 3664441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit8] = "lit8", 3665441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit9] = "lit9", 3666441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit10] = "lit10", 3667441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit11] = "lit11", 3668441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit12] = "lit12", 3669441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit13] = "lit13", 3670441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit14] = "lit14", 3671441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit15] = "lit15", 3672441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit16] = "lit16", 3673441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit17] = "lit17", 3674441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit18] = "lit18", 3675441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit19] = "lit19", 3676441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit20] = "lit20", 3677441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit21] = "lit21", 3678441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit22] = "lit22", 3679441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit23] = "lit23", 3680441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit24] = "lit24", 3681441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit25] = "lit25", 3682441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit26] = "lit26", 3683441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit27] = "lit27", 3684441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit28] = "lit28", 3685441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit29] = "lit29", 3686441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit30] = "lit30", 3687441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_lit31] = "lit31", 3688441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg0] = "reg0", 3689441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg1] = "reg1", 3690441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg2] = "reg2", 3691441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg3] = "reg3", 3692441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg4] = "reg4", 3693441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg5] = "reg5", 3694441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg6] = "reg6", 3695441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg7] = "reg7", 3696441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg8] = "reg8", 3697441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg9] = "reg9", 3698441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg10] = "reg10", 3699441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg11] = "reg11", 3700441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg12] = "reg12", 3701441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg13] = "reg13", 3702441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg14] = "reg14", 3703441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg15] = "reg15", 3704441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg16] = "reg16", 3705441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg17] = "reg17", 3706441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg18] = "reg18", 3707441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg19] = "reg19", 3708441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg20] = "reg20", 3709441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg21] = "reg21", 3710441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg22] = "reg22", 3711441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg23] = "reg23", 3712441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg24] = "reg24", 3713441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg25] = "reg25", 3714441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg26] = "reg26", 3715441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg27] = "reg27", 3716441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg28] = "reg28", 3717441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg29] = "reg29", 3718441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg30] = "reg30", 3719441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_reg31] = "reg31", 3720441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg0] = "breg0", 3721441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg1] = "breg1", 3722441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg2] = "breg2", 3723441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg3] = "breg3", 3724441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg4] = "breg4", 3725441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg5] = "breg5", 3726441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg6] = "breg6", 3727441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg7] = "breg7", 3728441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg8] = "breg8", 3729441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg9] = "breg9", 3730441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg10] = "breg10", 3731441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg11] = "breg11", 3732441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg12] = "breg12", 3733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg13] = "breg13", 3734441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg14] = "breg14", 3735441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg15] = "breg15", 3736441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg16] = "breg16", 3737441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg17] = "breg17", 3738441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg18] = "breg18", 3739441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg19] = "breg19", 3740441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg20] = "breg20", 3741441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg21] = "breg21", 3742441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg22] = "breg22", 3743441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg23] = "breg23", 3744441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg24] = "breg24", 3745441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg25] = "breg25", 3746441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg26] = "breg26", 3747441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg27] = "breg27", 3748441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg28] = "breg28", 3749441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg29] = "breg29", 3750441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg30] = "breg30", 3751441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_breg31] = "breg31", 3752441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_regx] = "regx", 3753441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_fbreg] = "fbreg", 3754441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_bregx] = "bregx", 3755441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_piece] = "piece", 3756441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_deref_size] = "deref_size", 3757441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_xderef_size] = "xderef_size", 3758441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_nop] = "nop", 3759441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_push_object_address] = "push_object_address", 3760441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_call2] = "call2", 3761441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_call4] = "call4", 3762441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DW_OP_call_ref] = "call_ref", 3763cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_OP_form_tls_address] = "form_tls_address", 3764cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_OP_call_frame_cfa] = "call_frame_cfa", 3765cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng [DW_OP_bit_piece] = "bit_piece", 3766441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 3767441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3768441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word offset = 0; 3769441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (len-- > 0) 3770441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3771cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast8_t op = *data++; 3772441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3773441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (op) 3774441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3775441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_call_ref: 3776441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_addr:; 3777441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Address operand. */ 3778441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word addr; 3779441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (addrsize == 4) 3780441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project addr = read_4ubyte_unaligned (dbg, data); 3781441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 3782441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3783441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (addrsize == 8); 3784441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project addr = read_8ubyte_unaligned (dbg, data); 3785441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 3786441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data += addrsize; 3787441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= addrsize; 3788441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3789cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (op == DW_OP_addr) 3790cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3791cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *a = format_dwarf_addr (dwflmod, 0, addr); 3792cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %s\n", 3793cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3794cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng known[op] ?: "???", a); 3795cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (a); 3796cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 3797cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 3798cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n", 3799cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3800cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng known[op] ?: "???", (uintmax_t) addr); 3801441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 1 + addrsize; 3802441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3803441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3804cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_OP_deref_size: 3805cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_OP_xderef_size: 3806441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_pick: 3807441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_const1u: 3808cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n", 3809cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3810441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", *((uint8_t *) data)); 3811441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++data; 3812441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project --len; 3813441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 2; 3814441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3815441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3816441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_const2u: 3817cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", 3818cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3819441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", read_2ubyte_unaligned (dbg, data)); 3820441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= 2; 3821441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data += 2; 3822441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 3; 3823441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3824441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3825441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_const4u: 3826cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", 3827cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3828441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", read_4ubyte_unaligned (dbg, data)); 3829441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= 4; 3830441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data += 4; 3831441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 5; 3832441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3833441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3834441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_const8u: 3835cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", 3836cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3837441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", read_8ubyte_unaligned (dbg, data)); 3838441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= 8; 3839441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data += 8; 3840441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 9; 3841441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3842441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3843441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_const1s: 3844cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n", 3845cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3846441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", *((int8_t *) data)); 3847441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++data; 3848441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project --len; 3849441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 2; 3850441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3851441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3852441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_const2s: 3853cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n", 3854cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3855441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", read_2sbyte_unaligned (dbg, data)); 3856441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= 2; 3857441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data += 2; 3858441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 3; 3859441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3860441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3861441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_const4s: 3862cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n", 3863cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3864441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", read_4sbyte_unaligned (dbg, data)); 3865441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= 4; 3866441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data += 4; 3867441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 5; 3868441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3869441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3870441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_const8s: 3871cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", 3872cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3873441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", read_8sbyte_unaligned (dbg, data)); 3874441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= 8; 3875441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data += 8; 3876441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 9; 3877441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3878441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3879cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_OP_piece: 3880441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_regx: 3881441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_plus_uconst: 3882441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_constu:; 3883cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const unsigned char *start = data; 3884441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int uleb; 3885441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (uleb, data); 3886cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %u\n", 3887cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3888441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", uleb); 3889441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= data - start; 3890441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 1 + (data - start); 3891441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3892441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3893cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_OP_bit_piece: 3894cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng start = data; 3895cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int uleb2; 3896cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng get_uleb128 (uleb, data); 3897cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng get_uleb128 (uleb2, data); 3898cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %u, %u\n", 3899cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3900cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng known[op] ?: "???", uleb, uleb2); 3901cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng len -= data - start; 3902cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng offset += 1 + (data - start); 3903cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 3904cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3905441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_fbreg: 3906441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_breg0 ... DW_OP_breg31: 3907441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_consts: 3908441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project start = data; 3909441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int sleb; 3910441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_sleb128 (sleb, data); 3911cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %d\n", 3912cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3913441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", sleb); 3914441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= data - start; 3915441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 1 + (data - start); 3916441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3917441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3918441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_bregx: 3919441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project start = data; 3920441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (uleb, data); 3921441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_sleb128 (sleb, data); 3922cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %u %d\n", 3923cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3924441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", uleb, sleb); 3925441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= data - start; 3926441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 1 + (data - start); 3927441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3928441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3929441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_call2: 3930441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_call4: 3931441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_skip: 3932441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_OP_bra: 3933cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n", 3934cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, 3935441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project known[op] ?: "???", 3936441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data))); 3937441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= 2; 3938441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data += 2; 3939441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += 3; 3940441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3941441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3942441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 3943441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* No Operand. */ 3944cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (op < sizeof known / sizeof known[0] && known[op] != NULL) 3945cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %s\n", 3946cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, known[op]); 3947cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 3948cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s[%4" PRIuMAX "] %#x\n", 3949cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent, "", (uintmax_t) offset, op); 3950441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++offset; 3951441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 3952441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 3953cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 3954cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng indent = indentrest; 3955441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 3956441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 3957441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3958441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3959441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 3960cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 3961cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 3962cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 3963cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn __attribute__ ((unused)), 3964441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr, Dwarf *dbg) 3965441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 3966441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\nDWARF section '%s' at offset %#" PRIx64 ":\n" 3967441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " [ Code]\n"), 3968441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ".debug_abbrev", (uint64_t) shdr->sh_offset); 3969441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3970441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off offset = 0; 3971cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (offset < shdr->sh_size) 3972441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3973cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"), 3974cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng offset); 3975441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3976cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (1) 3977441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 3978cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t length; 3979cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Abbrev abbrev; 3980441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3981cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int res = dwarf_offabbrev (dbg, offset, &length, &abbrev); 3982cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (res != 0) 3983cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3984cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (res < 0)) 3985cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 3986cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\ 3987cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng *** error while reading abbreviation: %s\n"), 3988cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwarf_errmsg (-1)); 3989cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 3990cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 3991441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3992cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* This is the NUL byte at the end of the section. */ 3993cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++offset; 3994cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 3995cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 3996441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3997cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* We know these calls can never fail. */ 3998cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int code = dwarf_getabbrevcode (&abbrev); 3999cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int tag = dwarf_getabbrevtag (&abbrev); 4000cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int has_children = dwarf_abbrevhaschildren (&abbrev); 4001cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4002cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" [%5u] offset: %" PRId64 4003cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ", children: %s, tag: %s\n"), 4004cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng code, (int64_t) offset, 4005cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng has_children ? gettext ("yes") : gettext ("no"), 4006cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwarf_tag_string (tag)); 4007cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4008cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t cnt = 0; 4009cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int name; 4010cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int form; 4011cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Off enoffset; 4012cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (dwarf_getabbrevattr (&abbrev, cnt, 4013cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &name, &form, &enoffset) == 0) 4014cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4015cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n", 4016cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwarf_attr_string (name), dwarf_form_string (form), 4017cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (uint64_t) enoffset); 4018441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4019cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++cnt; 4020cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4021441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4022cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng offset += length; 4023441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4024441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4025441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 4026441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4027441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4028441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print content of DWARF .debug_aranges section. We fortunately do 4029441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project not have to know a bit about the structure of the section, libdwarf 4030441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project takes care of it. */ 4031441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 4032cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 4033cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 4034cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 4035cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn __attribute__ ((unused)), 4036441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr, Dwarf *dbg) 4037441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 4038441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Aranges *aranges; 4039441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 4040cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0)) 4041441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4042441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get .debug_aranges content: %s"), 4043441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dwarf_errmsg (-1)); 4044441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 4045441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4046441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4047441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext ("\ 4048441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nDWARF section '%s' at offset %#" PRIx64 " contains %zu entry:\n", 4049441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\ 4050441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nDWARF section '%s' at offset %#" PRIx64 " contains %zu entries:\n", 4051441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt), 4052441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ".debug_aranges", (uint64_t) shdr->sh_offset, cnt); 4053441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4054441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Compute floor(log16(cnt)). */ 4055441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t tmp = cnt; 4056441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int digits = 1; 4057441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (tmp >= 16) 4058441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4059441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++digits; 4060441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project tmp >>= 4; 4061441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4062441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4063441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (size_t n = 0; n < cnt; ++n) 4064441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4065441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Arange *runp = dwarf_onearange (aranges, n); 4066cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (runp == NULL)) 4067441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4068441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1)); 4069441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 4070441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4071441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4072441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Addr start; 4073441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word length; 4074441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off offset; 4075441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4076cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0)) 4077441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" [%*zu] ???\n"), digits, n); 4078441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 4079441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" [%*zu] start: %0#*" PRIx64 4080441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ", length: %5" PRIu64 ", CU DIE offset: %6" 4081441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project PRId64 "\n"), 4082441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18, 4083441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) start, (uint64_t) length, (int64_t) offset); 4084441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4085441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 4086441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4087cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Print content of DWARF .debug_ranges section. */ 4088cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 4089cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_ranges_section (Dwfl_Module *dwflmod, 4090cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 4091cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr, 4092cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf *dbg) 4093cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 4094cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_rawdata (scn, NULL); 4095cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4096cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data == NULL)) 4097cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4098cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot get .debug_ranges content: %s"), 4099cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_errmsg (-1)); 4100cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 4101cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4102cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4103cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\ 4104cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng\nDWARF section '%s' at offset %#" PRIx64 ":\n"), 4105cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ".debug_ranges", (uint64_t) shdr->sh_offset); 4106cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4107cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 4108cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4109cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bool first = true; 4110cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned char *readp = data->d_buf; 4111cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (readp < (unsigned char *) data->d_buf + data->d_size) 4112cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4113cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ptrdiff_t offset = readp - (unsigned char *) data->d_buf; 4114cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4115cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data->d_size - offset < address_size * 2)) 4116cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4117cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" [%6tx] <INVALID DATA>\n"), offset); 4118cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4119cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4120cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4121cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr begin; 4122cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr end; 4123cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (address_size == 8) 4124cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4125cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng begin = read_8ubyte_unaligned_inc (dbg, readp); 4126cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng end = read_8ubyte_unaligned_inc (dbg, readp); 4127cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4128cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 4129cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4130cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng begin = read_4ubyte_unaligned_inc (dbg, readp); 4131cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng end = read_4ubyte_unaligned_inc (dbg, readp); 4132cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (begin == (Dwarf_Addr) (uint32_t) -1) 4133cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng begin = (Dwarf_Addr) -1l; 4134cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4135cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4136cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ 4137cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4138cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *b = format_dwarf_addr (dwflmod, address_size, end); 4139cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" [%6tx] base address %s\n"), offset, b); 4140cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (b); 4141cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4142cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (begin == 0 && end == 0) /* End of list entry. */ 4143cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng first = true; 4144cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 4145cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4146cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *b = format_dwarf_addr (dwflmod, address_size, begin); 4147cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *e = format_dwarf_addr (dwflmod, address_size, end); 4148cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* We have an address range entry. */ 4149cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (first) /* First address range entry in a list. */ 4150cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" [%6tx] %s..%s\n"), offset, b, e); 4151cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 4152cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %s..%s\n"), b, e); 4153cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (b); 4154cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (e); 4155cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4156cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng first = false; 4157cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4158cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4159cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 4160cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 4163cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_frame_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 4164cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 4165cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 4166cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn __attribute__ ((unused)), 4167cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr __attribute__ ((unused)), 4168cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf *dbg __attribute__ ((unused))) 4169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 4170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 4171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstruct attrcb_args 4174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 4175cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwfl_Module *dwflmod; 4176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf *dbg; 4177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int level; 4178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int addrsize; 4179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off cu_offset; 4180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}; 4181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int 4184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectattr_callback (Dwarf_Attribute *attrp, void *arg) 4185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 4186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct attrcb_args *cbargs = (struct attrcb_args *) arg; 4187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const int level = cbargs->level; 4188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int attr = dwarf_whatattr (attrp); 4190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (attr == 0)) 4191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get attribute code: %s"), 4193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dwarf_errmsg (-1)); 4194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return DWARF_CB_ABORT; 4195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int form = dwarf_whatform (attrp); 4198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (form == 0)) 4199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get attribute form: %s"), 4201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dwarf_errmsg (-1)); 4202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return DWARF_CB_ABORT; 4203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (form) 4206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4207cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_FORM_addr: 4208cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4209cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr addr; 4210cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (dwarf_formaddr (attrp, &addr) != 0)) 4211cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4212cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng attrval_out: 4213cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot get attribute value: %s"), 4214cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwarf_errmsg (-1)); 4215cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return DWARF_CB_ABORT; 4216cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4217cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr); 4218cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %*s%-20s %s\n", 4219cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) (level * 2), "", dwarf_attr_string (attr), a); 4220cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (a); 4221cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_indirect: 4225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_strp: 4226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_string:; 4227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *str = dwarf_formstring (attrp); 4228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (str == NULL)) 4229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto attrval_out; 4230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %*s%-20s \"%s\"\n", 4231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) (level * 2), "", dwarf_attr_string (attr), str); 4232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_ref_addr: 4235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_ref_udata: 4236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_ref8: 4237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_ref4: 4238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_ref2: 4239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_ref1:; 4240cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Die ref; 4241cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (dwarf_formref_die (attrp, &ref) == NULL)) 4242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto attrval_out; 4243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %*s%-20s [%6" PRIxMAX "]\n", 4245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) (level * 2), "", dwarf_attr_string (attr), 4246cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (uintmax_t) dwarf_dieoffset (&ref)); 4247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_udata: 4250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_sdata: 4251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_data8: 4252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_data4: 4253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_data2: 4254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_data1:; 4255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word num; 4256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (dwarf_formudata (attrp, &num) != 0)) 4257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto attrval_out; 4258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4259cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *valuestr = NULL; 4260cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (attr) 4261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4262cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_location: 4263cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_data_location: 4264cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_data_member_location: 4265cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_vtable_elem_location: 4266cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_string_length: 4267cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_use_location: 4268cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_frame_base: 4269cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_return_addr: 4270cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_static_link: 4271cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %*s%-20s location list [%6" PRIxMAX "]\n", 4272cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) (level * 2), "", dwarf_attr_string (attr), 4273cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (uintmax_t) num); 4274cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return DWARF_CB_OK; 4275cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4276cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_ranges: 4277cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %*s%-20s range list [%6" PRIxMAX "]\n", 4278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) (level * 2), "", dwarf_attr_string (attr), 4279cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (uintmax_t) num); 4280cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return DWARF_CB_OK; 4281cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4282cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_language: 4283cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_lang_string (num); 4284cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4285cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_encoding: 4286cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_encoding_string (num); 4287cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4288cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_accessibility: 4289cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_access_string (num); 4290cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4291cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_visibility: 4292cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_visibility_string (num); 4293cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4294cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_virtuality: 4295cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_virtuality_string (num); 4296cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4297cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_identifier_case: 4298cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_identifier_case_string (num); 4299cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4300cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_calling_convention: 4301cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_calling_convention_string (num); 4302cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4303cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_inline: 4304cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_inline_string (num); 4305cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4306cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_ordering: 4307cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_ordering_string (num); 4308cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4309cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_discr_list: 4310cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr = dwarf_discr_list_string (num); 4311cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4312cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 4313cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Nothing. */ 4314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4317cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (valuestr == NULL) 4318cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %*s%-20s %" PRIuMAX "\n", 4319cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) (level * 2), "", dwarf_attr_string (attr), 4320cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (uintmax_t) num); 4321cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 4322cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %*s%-20s %s (%" PRIuMAX ")\n", 4323cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) (level * 2), "", dwarf_attr_string (attr), 4324cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng valuestr, (uintmax_t) num); 4325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_flag:; 4328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool flag; 4329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (dwarf_formflag (attrp, &flag) != 0)) 4330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto attrval_out; 4331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %*s%-20s %s\n", 4333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) (level * 2), "", dwarf_attr_string (attr), 4334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nl_langinfo (flag ? YESSTR : NOSTR)); 4335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_block4: 4338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_block2: 4339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_block1: 4340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_FORM_block:; 4341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Block block; 4342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (dwarf_formblock (attrp, &block) != 0)) 4343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto attrval_out; 4344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4345441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %*s%-20s %" PRIxMAX " byte block\n", 4346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) (level * 2), "", dwarf_attr_string (attr), 4347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uintmax_t) block.length); 4348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4349cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (attr) 4350cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4351cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_location: 4352cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_data_location: 4353cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_data_member_location: 4354cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_vtable_elem_location: 4355cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_string_length: 4356cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_use_location: 4357cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_frame_base: 4358cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_return_addr: 4359cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_static_link: 4360cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_allocated: 4361cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_associated: 4362cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_bit_size: 4363cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_bit_offset: 4364cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_bit_stride: 4365cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_byte_size: 4366cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_byte_stride: 4367cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_count: 4368cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_lower_bound: 4369cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_AT_upper_bound: 4370cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_ops (cbargs->dwflmod, cbargs->dbg, 4371cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 12 + level * 2, 12 + level * 2, 4372cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng cbargs->addrsize, block.length, block.data); 4373cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4374cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 4378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %*s%-20s [form: %d] ???\n", 4379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) (level * 2), "", dwarf_attr_string (attr), 4380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) form); 4381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return DWARF_CB_OK; 4385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 4386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 4389cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_info_section (Dwfl_Module *dwflmod, 4390cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 4391cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 4392cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn __attribute__ ((unused)), 4393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr, Dwarf *dbg) 4394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 4395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 4396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nDWARF section '%s' at offset %#" PRIx64 ":\n [Offset]\n"), 4397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ".debug_info", (uint64_t) shdr->sh_offset); 4398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* If the section is empty we don't have to do anything. */ 4400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_size == 0) 4401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 4402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4403cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int maxdies = 20; 4404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die)); 4405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off offset = 0; 4407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* New compilation unit. */ 4409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cuhl; 4410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project //Dwarf_Half version; 4411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off abbroffset; 4412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint8_t addrsize; 4413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint8_t offsize; 4414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off nextcu; 4415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project next_cu: 4416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dwarf_nextcu (dbg, offset, &nextcu, &cuhl, &abbroffset, &addrsize, 4417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &offsize) != 0) 4418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto do_return; 4419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" Compilation unit at offset %" PRIu64 ":\n" 4421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Version: %" PRIu16 ", Abbreviation section offset: %" 4422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project PRIu64 ", Address size: %" PRIu8 ", Offset size: %" PRIu8 "\n"), 4423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) offset, /*version*/2, abbroffset, addrsize, offsize); 4424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct attrcb_args args; 4427cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng args.dwflmod = dwflmod; 4428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project args.dbg = dbg; 4429441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project args.addrsize = addrsize; 4430441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project args.cu_offset = offset; 4431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4432441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += cuhl; 4433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4434441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int level = 0; 4435441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4436441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (dwarf_offdie (dbg, offset, &dies[level]) == NULL)) 4437441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4438441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get DIE at offset %" PRIu64 4439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " in section '%s': %s"), 4440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) offset, ".debug_info", dwarf_errmsg (-1)); 4441441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto do_return; 4442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4443441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4444441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project do 4445441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4446441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset = dwarf_dieoffset (&dies[level]); 4447cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (offset == ~0ul)) 4448441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4449441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get DIE offset: %s"), 4450441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dwarf_errmsg (-1)); 4451441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto do_return; 4452441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4453441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4454441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int tag = dwarf_tag (&dies[level]); 4455cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (tag == DW_TAG_invalid)) 4456441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4457441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64 4458441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " in section '%s': %s"), 4459441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) offset, ".debug_info", dwarf_errmsg (-1)); 4460441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto do_return; 4461441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4462441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4463441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" [%6" PRIx64 "] %*s%s\n", 4464cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (uint64_t) offset, (int) (level * 2), "", 4465cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwarf_tag_string (tag)); 4466441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4467441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Print the attribute values. */ 4468441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project args.level = level; 4469441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0); 4470441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4471441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Make room for the next level's DIE. */ 4472441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (level + 1 == maxdies) 4473441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dies = (Dwarf_Die *) xrealloc (dies, 4474441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (maxdies += 10) 4475441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project * sizeof (Dwarf_Die)); 4476441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4477441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int res = dwarf_child (&dies[level], &dies[level + 1]); 4478441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (res > 0) 4479441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4480441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1) 4481441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (level-- == 0) 4482441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4483441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4484cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (res == -1)) 4485441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4486441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get next DIE: %s\n"), 4487441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dwarf_errmsg (-1)); 4488441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto do_return; 4489441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4490441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4491441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (unlikely (res < 0)) 4492441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4493441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get next DIE: %s"), 4494441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dwarf_errmsg (-1)); 4495441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto do_return; 4496441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4497441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 4498441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++level; 4499441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4500441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (level >= 0); 4501441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4502441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset = nextcu; 4503441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (offset != 0) 4504441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto next_cu; 4505441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4506441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project do_return: 4507441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project free (dies); 4508441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 4509441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4510441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4511441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 4512cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, 4513cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 4514cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 4515441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 4516441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 4517441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nDWARF section '%s' at offset %#" PRIx64 ":\n"), 4518441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ".debug_line", (uint64_t) shdr->sh_offset); 4519441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4520441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_size == 0) 4521441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 4522441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4523441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* There is no functionality in libdw to read the information in the 4524441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project way it is represented here. Hardcode the decoder. */ 4525441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data = elf_getdata (scn, NULL); 4526cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data == NULL || data->d_buf == NULL)) 4527441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4528441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get line data section data: %s"), 4529441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 4530441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 4531441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4532441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4533441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const unsigned char *linep = (const unsigned char *) data->d_buf; 4534441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const unsigned char *lineendp; 4535441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4536441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (linep 4537441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project < (lineendp = (const unsigned char *) data->d_buf + data->d_size)) 4538441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4539441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t start_offset = linep - (const unsigned char *) data->d_buf; 4540441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4541cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\nTable at offset %Zu:\n"), start_offset); 4542cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4543441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); 4544441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int length = 4; 4545441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (unit_length == 0xffffffff)) 4546441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4547441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (linep + 8 > lineendp)) 4548441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4549441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project invalid_data: 4550441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("invalid data in section [%zu] '%s'"), 4551441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_ndxscn (scn), ".debug_line"); 4552441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 4553441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4554441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unit_length = read_8ubyte_unaligned_inc (dbg, linep); 4555441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project length = 8; 4556441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4557441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4558441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check whether we have enough room in the section. */ 4559441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unit_length < 2 + length + 5 * 1 4560441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || unlikely (linep + unit_length > lineendp)) 4561441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto invalid_data; 4562441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project lineendp = linep + unit_length; 4563441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4564441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The next element of the header is the version identifier. */ 4565441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); 4566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4567441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Next comes the header length. */ 4568441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word header_length; 4569441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (length == 4) 4570441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project header_length = read_4ubyte_unaligned_inc (dbg, linep); 4571441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 4572441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project header_length = read_8ubyte_unaligned_inc (dbg, linep); 4573441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project //const unsigned char *header_start = linep; 4574441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4575441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Next the minimum instruction length. */ 4576441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint_fast8_t minimum_instr_len = *linep++; 4577441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4578441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Then the flag determining the default value of the is_stmt 4579441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project register. */ 4580441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint_fast8_t default_is_stmt = *linep++; 4581441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4582441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Now the line base. */ 4583441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int_fast8_t line_base = *((const int_fast8_t *) linep); 4584441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++linep; 4585441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4586441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* And the line range. */ 4587441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint_fast8_t line_range = *linep++; 4588441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4589441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The opcode base. */ 4590441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint_fast8_t opcode_base = *linep++; 4591441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4592441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Print what we got so far. */ 4593441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\n" 4594441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Length: %" PRIu64 "\n" 4595441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " DWARF version: %" PRIuFAST16 "\n" 4596441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Prologue length: %" PRIu64 "\n" 4597441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Minimum instruction length: %" PRIuFAST8 "\n" 4598441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Initial value if '%s': %" PRIuFAST8 "\n" 4599441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Line base: %" PRIdFAST8 "\n" 4600441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Line range: %" PRIuFAST8 "\n" 4601441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Opcode base: %" PRIuFAST8 "\n" 4602441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "\n" 4603441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "Opcodes:\n"), 4604441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) unit_length, version, (uint64_t) header_length, 4605441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project minimum_instr_len, "is_stmt", default_is_stmt, line_base, 4606441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project line_range, opcode_base); 4607441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4608441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (linep + opcode_base - 1 >= lineendp)) 4609cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4610cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng invalid_unit: 4611cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, 4612cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("invalid data at offset %tu in section [%zu] '%s'"), 4613cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng linep - (const unsigned char *) data->d_buf, 4614cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), ".debug_line"); 4615cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng linep = lineendp; 4616cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 4617cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4618441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int opcode_base_l10 = 1; 4619441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int tmp = opcode_base; 4620441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (tmp > 10) 4621441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4622441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project tmp /= 10; 4623441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++opcode_base_l10; 4624441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4625441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const uint8_t *standard_opcode_lengths = linep - 1; 4626441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt) 4627441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n", 4628441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " [%*" PRIuFAST8 "] %hhu arguments\n", 4629441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) linep[cnt - 1]), 4630441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project opcode_base_l10, cnt, linep[cnt - 1]); 4631441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project linep += opcode_base - 1; 4632441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (linep >= lineendp)) 4633cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4634441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4635441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("\nDirectory table:")); 4636441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (*linep != 0) 4637441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4638441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned char *endp = memchr (linep, '\0', lineendp - linep); 4639cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (endp == NULL)) 4640cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4641441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4642441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %s\n", (char *) linep); 4643441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4644441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project linep = endp + 1; 4645441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4646441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Skip the final NUL byte. */ 4647441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++linep; 4648441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4649441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (linep >= lineendp)) 4650cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4651441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("\nFile name table:\n" 4652441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " Entry Dir Time Size Name")); 4653441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (unsigned int cnt = 1; *linep != 0; ++cnt) 4654441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4655441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* First comes the file name. */ 4656441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char *fname = (char *) linep; 4657441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned char *endp = memchr (fname, '\0', lineendp - linep); 4658cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (endp == NULL)) 4659cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4660441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project linep = endp + 1; 4661441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4662441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Then the index. */ 4663441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int diridx; 4664441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (diridx, linep); 4665441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4666441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Next comes the modification time. */ 4667441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int mtime; 4668441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (mtime, linep); 4669441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4670441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Finally the length of the file. */ 4671441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int fsize; 4672441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (fsize, linep); 4673441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4674441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %-5u %-5u %-9u %-9u %s\n", 4675441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, diridx, mtime, fsize, fname); 4676441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4677441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Skip the final NUL byte. */ 4678441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++linep; 4679441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4680441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("\nLine number statements:")); 4681441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word address = 0; 4682441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t line = 1; 4683441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint_fast8_t is_stmt = default_is_stmt; 4684441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4685441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Default address value, in case we do not find the CU. */ 4686441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t address_size 4687441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8; 4688441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4689441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Determine the CU this block is for. */ 4690441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off cuoffset; 4691441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off ncuoffset = 0; 4692441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t hsize; 4693441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize, 4694441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NULL, NULL, NULL) == 0) 4695441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4696441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Die cudie; 4697441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL) 4698441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 4699441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Attribute stmt_list; 4700441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL) 4701441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 4702441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word lineoff; 4703441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dwarf_formudata (&stmt_list, &lineoff) != 0) 4704441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 4705441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (lineoff == start_offset) 4706441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4707441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Found the CU. */ 4708441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address_size = cudie.cu->address_size; 4709441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4710441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4711441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4712441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4713441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (linep < lineendp) 4714441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4715441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int u128; 4716441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int s128; 4717441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4718441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Read the opcode. */ 4719441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int opcode = *linep++; 4720441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4721441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Is this a special opcode? */ 4722441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (likely (opcode >= opcode_base)) 4723441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4724441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Yes. Handling this is quite easy since the opcode value 4725441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project is computed with 4726441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4727441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project opcode = (desired line increment - line_base) 4728441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project + (line_range * address advance) + opcode_base 4729441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project */ 4730441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int line_increment = (line_base 4731441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project + (opcode - opcode_base) % line_range); 4732441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int address_increment = (minimum_instr_len 4733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project * ((opcode - opcode_base) 4734441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project / line_range)); 4735441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4736441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Perform the increments. */ 4737441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project line += line_increment; 4738441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address += address_increment; 4739441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4740cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 4741441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 4742cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng special opcode %u: address+%u = %s, line%+d = %zu\n"), 4743cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng opcode, address_increment, a, line_increment, line); 4744cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (a); 4745441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4746441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (opcode == 0) 4747441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4748441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This an extended opcode. */ 4749441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (linep + 2 > lineendp)) 4750cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4751441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4752441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The length. */ 4753441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int len = *linep++; 4754441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4755441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (linep + len > lineendp)) 4756cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4757441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4758441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The sub-opcode. */ 4759441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project opcode = *linep++; 4760441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4761441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" extended opcode %u: "), opcode); 4762441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4763441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (opcode) 4764441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4765441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNE_end_sequence: 4766441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("end of sequence")); 4767441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4768441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Reset the registers we care about. */ 4769441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address = 0; 4770441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project line = 1; 4771441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project is_stmt = default_is_stmt; 4772441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4773441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4774441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNE_set_address: 4775441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (address_size == 4) 4776441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address = read_4ubyte_unaligned_inc (dbg, linep); 4777441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 4778441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address = read_8ubyte_unaligned_inc (dbg, linep); 4779cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4780cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 4781cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("set address to %s\n"), a); 4782cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (a); 4783cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4784441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4785441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4786441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNE_define_file: 4787441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4788441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char *fname = (char *) linep; 4789441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned char *endp = memchr (linep, '\0', 4790441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project lineendp - linep); 4791cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (endp == NULL)) 4792cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4793441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project linep = endp + 1; 4794441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4795441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int diridx; 4796441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (diridx, linep); 4797441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word mtime; 4798441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (mtime, linep); 4799441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word filelength; 4800441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (filelength, linep); 4801441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4802441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 4803441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectdefine new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"), 4804441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project diridx, (uint64_t) mtime, (uint64_t) filelength, 4805441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fname); 4806441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4807441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4808441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4809441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 4810441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Unknown, ignore it. */ 4811441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("unknown opcode")); 4812441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project linep += len - 1; 4813441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4814441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4815441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4816cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (opcode <= DW_LNS_set_epilogue_begin) 4817441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4818441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This is a known standard opcode. */ 4819441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (opcode) 4820441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4821441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_copy: 4822441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes no argument. */ 4823441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext (" copy")); 4824441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4825441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4826441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_advance_pc: 4827441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes one uleb128 parameter which is added to the 4828441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address. */ 4829441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (u128, linep); 4830441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address += minimum_instr_len * u128; 4831cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4832cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 4833cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("advance address by %u to %s\n"), 4834cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng u128, a); 4835cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (a); 4836cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4837441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4838441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4839441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_advance_line: 4840441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes one sleb128 parameter which is added to the 4841441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project line. */ 4842441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_sleb128 (s128, linep); 4843441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project line += s128; 4844441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 4845441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project advance line by constant %d to %" PRId64 "\n"), 4846441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project s128, (int64_t) line); 4847441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4848441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4849441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_set_file: 4850441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes one uleb128 parameter which is stored in file. */ 4851441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (u128, linep); 4852441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" set file to %" PRIu64 "\n"), 4853441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) u128); 4854441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4855441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4856441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_set_column: 4857441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes one uleb128 parameter which is stored in column. */ 4858441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (standard_opcode_lengths[opcode] != 1)) 4859cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4860441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4861441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (u128, linep); 4862441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" set column to %" PRIu64 "\n"), 4863441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) u128); 4864441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4865441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4866441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_negate_stmt: 4867441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes no argument. */ 4868441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project is_stmt = 1 - is_stmt; 4869441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" set '%s' to %" PRIuFAST8 "\n"), 4870441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "is_stmt", is_stmt); 4871441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4872441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4873441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_set_basic_block: 4874441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes no argument. */ 4875441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext (" set basic block flag")); 4876441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4877441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4878441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_const_add_pc: 4879441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes no argument. */ 4880441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project u128 = (minimum_instr_len 4881441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project * ((255 - opcode_base) / line_range)); 4882441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address += u128; 4883cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4884cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 4885cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("advance address by constant %u to %s\n"), 4886cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng u128, a); 4887cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (a); 4888cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4889441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4890441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4891441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_fixed_advance_pc: 4892441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes one 16 bit parameter which is added to the 4893441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address. */ 4894441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (standard_opcode_lengths[opcode] != 1)) 4895cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto invalid_unit; 4896441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4897441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project u128 = read_2ubyte_unaligned_inc (dbg, linep); 4898441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project address += u128; 4899cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4900cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *a = format_dwarf_addr (dwflmod, 0, address); 4901cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\ 4902cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengadvance address by fixed value %u to %s\n"), 4903cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng u128, a); 4904cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (a); 4905cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4906441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4907441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4908441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_LNS_set_prologue_end: 4909441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes no argument. */ 4910441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext (" set prologue end flag")); 4911441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4912441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4913cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_LNS_set_epilogue_begin: 4914441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Takes no argument. */ 4915441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext (" set epilogue begin flag")); 4916441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 4917441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4918441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4919441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 4920441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4921441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This is a new opcode the generator but not we know about. 4922441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Read the parameters associated with it but then discard 4923441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project everything. Read all the parameters for this opcode. */ 4924441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (ngettext (" unknown opcode with %" PRIu8 " parameter:", 4925441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " unknown opcode with %" PRIu8 " parameters:", 4926441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project standard_opcode_lengths[opcode]), 4927441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project standard_opcode_lengths[opcode]); 4928441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (int n = standard_opcode_lengths[opcode]; n > 0; --n) 4929441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 4930441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (u128, linep); 4931441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (n != standard_opcode_lengths[opcode]) 4932441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project putc_unlocked (',', stdout); 4933441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" %u", u128); 4934441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4935441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4936441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Next round, ignore this opcode. */ 4937441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 4938441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4939441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4940441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 4941441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4942441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* There must only be one data block. */ 4943441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (elf_getdata (scn, data) == NULL); 4944441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 4945441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4946441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4947441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 4948cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_loc_section (Dwfl_Module *dwflmod, 4949cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 4950cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 4951cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn __attribute__ ((unused)), 4952cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr, 4953cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf *dbg __attribute__ ((unused))) 4954441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 4955cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_rawdata (scn, NULL); 4956cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4957cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data == NULL)) 4958cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4959cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot get .debug_loc content: %s"), 4960cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_errmsg (-1)); 4961cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 4962cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4963cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4964441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 4965441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nDWARF section '%s' at offset %#" PRIx64 ":\n"), 4966441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ".debug_loc", (uint64_t) shdr->sh_offset); 4967441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 4968cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 4969cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4970cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bool first = true; 4971cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned char *readp = data->d_buf; 4972cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (readp < (unsigned char *) data->d_buf + data->d_size) 4973cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4974cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ptrdiff_t offset = readp - (unsigned char *) data->d_buf; 4975cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4976cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data->d_size - offset < address_size * 2)) 4977cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4978cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" [%6tx] <INVALID DATA>\n"), offset); 4979cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 4980cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4981cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4982cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr begin; 4983cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr end; 4984cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (address_size == 8) 4985cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4986cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng begin = read_8ubyte_unaligned_inc (dbg, readp); 4987cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng end = read_8ubyte_unaligned_inc (dbg, readp); 4988cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4989cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 4990cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4991cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng begin = read_4ubyte_unaligned_inc (dbg, readp); 4992cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng end = read_4ubyte_unaligned_inc (dbg, readp); 4993cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (begin == (Dwarf_Addr) (uint32_t) -1) 4994cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng begin = (Dwarf_Addr) -1l; 4995cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 4996cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4997cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ 4998cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 4999cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *b = format_dwarf_addr (dwflmod, address_size, end); 5000cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" [%6tx] base address %s\n"), offset, b); 5001cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (b); 5002cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5003cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (begin == 0 && end == 0) /* End of list entry. */ 5004cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng first = true; 5005cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 5006cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5007cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* We have a location expression entry. */ 5008cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp); 5009cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5010cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *b = format_dwarf_addr (dwflmod, address_size, begin); 5011cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *e = format_dwarf_addr (dwflmod, address_size, end); 5012441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5013cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (first) /* First entry in a list. */ 5014cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" [%6tx] %s..%s"), offset, b, e); 5015cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 5016cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %s..%s"), b, e); 5017cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5018cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (b); 5019cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng free (e); 5020cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5021cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_ops (dwflmod, dbg, 1, 18 + (address_size * 4), 5022cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng address_size, len, readp); 5023cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5024cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng first = false; 5025cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng readp += len; 5026cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5027cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5028cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5029441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5030441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstruct mac_culist 5031441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 5032441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Die die; 5033441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off offset; 5034441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Files *files; 5035441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct mac_culist *next; 5036441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}; 5037441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5038441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5039441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int 5040441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmac_compare (const void *p1, const void *p2) 5041441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 5042441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct mac_culist *m1 = (struct mac_culist *) p1; 5043441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct mac_culist *m2 = (struct mac_culist *) p2; 5044441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5045441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (m1->offset < m2->offset) 5046441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 5047441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (m1->offset > m2->offset) 5048441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return 1; 5049441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return 0; 5050441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 5051441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5052441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5053441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 5054cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 5055cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 5056cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 5057cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 5058441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 5059441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 5060441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project\nDWARF section '%s' at offset %#" PRIx64 ":\n"), 5061441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ".debug_macinfo", (uint64_t) shdr->sh_offset); 5062441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project putc_unlocked ('\n', stdout); 5063441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5064441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* There is no function in libdw to iterate over the raw content of 5065441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project the section but it is easy enough to do. */ 5066441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data = elf_getdata (scn, NULL); 5067cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data == NULL || data->d_buf == NULL)) 5068441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5069441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get macro information section data: %s"), 5070441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 5071441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 5072441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5073441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5074441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the source file information for all CUs. */ 5075441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off offset; 5076441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off ncu = 0; 5077441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t hsize; 5078441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct mac_culist *culist = NULL; 5079441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t nculist = 0; 5080441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0) 5081441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5082441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Die cudie; 5083441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL) 5084441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 5085441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5086441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Attribute attr; 5087441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL) 5088441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 5089441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5090441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Word macoff; 5091441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dwarf_formudata (&attr, &macoff) != 0) 5092441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 5093441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5094441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp)); 5095441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project newp->die = cudie; 5096441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project newp->offset = macoff; 5097441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project newp->files = NULL; 5098441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project newp->next = culist; 5099441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project culist = newp; 5100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++nculist; 5101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Convert the list into an array for easier consumption. */ 5104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1) 5105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project * sizeof (*cus)); 5106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Add sentinel. */ 5107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cus[nculist].offset = data->d_size; 5108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (nculist > 0) 5109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (size_t cnt = nculist - 1; culist != NULL; --cnt) 5111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (cnt < nculist); 5113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cus[cnt] = *culist; 5114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project culist = culist->next; 5115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Sort the array according to the offset in the .debug_macinfo 5118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section. Note we keep the sentinel at the end. */ 5119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project qsort (cus, nculist, sizeof (*cus), mac_compare); 5120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const unsigned char *readp = (const unsigned char *) data->d_buf; 5123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const unsigned char *readendp = readp + data->d_size; 5124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int level = 1; 5125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (readp < readendp) 5127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int opcode = *readp++; 5129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int u128; 5130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int u128_2; 5131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const unsigned char *endp; 5132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (opcode) 5134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_MACINFO_define: 5136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_MACINFO_undef: 5137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_MACINFO_vendor_ext: 5138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* For the first two opcodes the parameters are 5139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project line, string 5140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project For the latter 5141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project number, string. 5142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project We can treat these cases together. */ 5143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (u128, readp); 5144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project endp = memchr (readp, '\0', readendp - readp); 5146cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (endp == NULL)) 5147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 5149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project%*s*** non-terminated string at end of section"), 5150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project level, ""); 5151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 5152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (opcode == DW_MACINFO_define) 5155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%*s#define %s, line %u\n", 5156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project level, "", (char *) readp, u128); 5157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (opcode == DW_MACINFO_undef) 5158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%*s#undef %s, line %u\n", 5159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project level, "", (char *) readp, u128); 5160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 5161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" #vendor-ext %s, number %u\n", (char *) readp, u128); 5162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project readp = endp + 1; 5164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 5165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_MACINFO_start_file: 5167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The two parameters are line and file index, in this order. */ 5168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (u128, readp); 5169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project get_uleb128 (u128_2, readp); 5170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Find the CU DIE for this file. */ 5172cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t macoff = readp - (const unsigned char *) data->d_buf; 5173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *fname = "???"; 5174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (macoff >= cus[0].offset) 5175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (macoff >= cus[1].offset) 5177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++cus; 5178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cus[0].files == NULL 5180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0) 5181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cus[0].files = (Dwarf_Files *) -1l; 5182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cus[0].files != (Dwarf_Files *) -1l) 5184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL) 5185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ?: "???"); 5186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%*sstart_file %u, [%u] %s\n", 5189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project level, "", u128, u128_2, fname); 5190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++level; 5191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 5192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case DW_MACINFO_end_file: 5194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project --level; 5195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%*send_file\n", level, ""); 5196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Nothing more to do. */ 5197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 5198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 5200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // XXX gcc seems to generate files with a trailing zero. 5201cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (opcode != 0 || readp != readendp)) 5202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("%*s*** invalid opcode %u\n", level, "", opcode); 5203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 5204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 5207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5209441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Callback for printing global names. */ 5210441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int 5211cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global, 5212cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void *arg) 5213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 5214441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int *np = (int *) arg; 5215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" [%5d] DIE offset: %6" PRId64 5217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ", CU DIE offset: %6" PRId64 ", name: %s\n"), 5218441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (*np)++, global->die_offset, global->cu_offset, global->name); 5219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return 0; 5221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 5222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the known exported symbols in the DWARF section '.debug_pubnames'. */ 5225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 5226cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 5227cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 5228cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 5229cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn __attribute__ ((unused)), 5230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr, Dwarf *dbg) 5231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 5232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\nDWARF section '%s' at offset %#" PRIx64 ":\n"), 5233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ".debug_pubnames", (uint64_t) shdr->sh_offset); 5234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int n = 0; 5236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0); 5237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 5238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the content of the DWARF string section '.debug_str'. */ 5240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 5241cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 5242cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Ebl *ebl __attribute__ ((unused)), 5243cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr __attribute__ ((unused)), 5244cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn __attribute__ ((unused)), 5245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr, Dwarf *dbg) 5246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 5247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Compute floor(log16(shdr->sh_size)). */ 5248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Addr tmp = shdr->sh_size; 5249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int digits = 1; 5250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (tmp >= 16) 5251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++digits; 5253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project tmp >>= 4; 5254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project digits = MAX (4, digits); 5256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\nDWARF section '%s' at offset %#" PRIx64 ":\n" 5258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project " %*s String\n"), 5259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ".debug_str", (uint64_t) shdr->sh_offset, 5260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* TRANS: the debugstr| prefix makes the string unique. */ 5261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project digits + 2, sgettext ("debugstr|Offset")); 5262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Dwarf_Off offset = 0; 5264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (offset < shdr->sh_size) 5265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t len; 5267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *str = dwarf_getstring (dbg, offset, &len); 5268cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (str == NULL)) 5269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext (" *** error while reading strings: %s\n"), 5271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dwarf_errmsg (-1)); 5272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 5273441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str); 5276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project offset += len + 1; 5278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 5280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 5282cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr) 5283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 5284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Before we start the real work get a debug context descriptor. */ 5285cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Addr dwbias; 5286cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias); 5287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dbg == NULL) 5288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, 0, gettext ("cannot get debug context descriptor: %s"), 5290cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng dwfl_errmsg (-1)); 5291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 5292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the section header string table index. */ 5295cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 5296cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 5297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (EXIT_FAILURE, 0, 5298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gettext ("cannot get section header string table index")); 5299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5300cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Look through all the sections for the debugging sections to print. */ 5301cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn = NULL; 5302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 5303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 5305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 5306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5307cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shdr != NULL && shdr->sh_type == SHT_PROGBITS) 5308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static const struct 5310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *name; 5312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project enum section_e bitmask; 5313cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void (*fp) (Dwfl_Module *, Ebl *, 5314cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *); 5315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } debug_sections[] = 5316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define NEW_SECTION(name) \ 5318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".debug_" #name, section_##name, print_debug_##name##_section } 5319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (abbrev), 5320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (aranges), 5321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (frame), 5322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (info), 5323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (line), 5324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (loc), 5325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (pubnames), 5326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (str), 5327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEW_SECTION (macinfo), 5328cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng NEW_SECTION (ranges), 5329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".eh_frame", section_frame, print_debug_frame_section } 5330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 5331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const int ndebug_sections = (sizeof (debug_sections) 5332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project / sizeof (debug_sections[0])); 5333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *name = elf_strptr (ebl->elf, shstrndx, 5334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_name); 5335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int n; 5336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (n = 0; n < ndebug_sections; ++n) 5338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (strcmp (name, debug_sections[n].name) == 0) 5339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 5340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (print_debug_sections & debug_sections[n].bitmask) 5341cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg); 5342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 5343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5345441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 5346cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5347cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5348cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5349cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define ITEM_INDENT 4 5350cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define ITEM_WRAP_COLUMN 150 5351cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define REGISTER_WRAP_COLUMN 75 5352cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5353cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Print "NAME: FORMAT", wrapping when FORMAT_MAX chars of FORMAT would 5354cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng make the line exceed ITEM_WRAP_COLUMN. Unpadded numbers look better 5355cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for the core items. But we do not want the line breaks to depend on 5356cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng the particular values. */ 5357cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic unsigned int 5358cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng__attribute__ ((format (printf, 7, 8))) 5359cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_core_item (unsigned int colno, char sep, unsigned int wrap, 5360cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t name_width, const char *name, 5361cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t format_max, const char *format, ...) 5362cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5363cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t len = strlen (name); 5364cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (name_width < len) 5365cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng name_width = len; 5366cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5367cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t n = name_width + sizeof ": " - 1 + format_max; 5368cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5369cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (colno == 0) 5370cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5371cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s", ITEM_INDENT, ""); 5372cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = ITEM_INDENT + n; 5373cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5374cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (colno + 2 + n < wrap) 5375cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5376cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%c ", sep); 5377cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno += 2 + n; 5378cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5379cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 5380cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5381cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("\n%*s", ITEM_INDENT, ""); 5382cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = ITEM_INDENT + n; 5383cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5384cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5385cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%s: %*s", name, (int) (name_width - len), ""); 5386cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5387cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng va_list ap; 5388cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng va_start (ap, format); 5389cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng vprintf (format, ap); 5390cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng va_end (ap); 5391cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5392cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return colno; 5393cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5394cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5395cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const void * 5396cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengconvert (Elf *core, Elf_Type type, uint_fast16_t count, 5397cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void *value, const void *data, size_t size) 5398cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5399cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data valuedata = 5400cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5401cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .d_type = type, 5402cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .d_buf = value, 5403cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT), 5404cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .d_version = EV_CURRENT, 5405cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 5406cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data indata = 5407cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5408cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .d_type = type, 5409cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .d_buf = (void *) data, 5410cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .d_size = valuedata.d_size, 5411cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng .d_version = EV_CURRENT, 5412cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng }; 5413cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5414cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *d = (gelf_getclass (core) == ELFCLASS32 5415cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? elf32_xlatetom : elf64_xlatetom) 5416cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]); 5417cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (d == NULL) 5418cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 5419cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot convert core note data: %s"), elf_errmsg (-1)); 5420cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5421cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return data + indata.d_size; 5422cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5423cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5424cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengtypedef uint8_t GElf_Byte; 5425cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5426cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic unsigned int 5427cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, 5428cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int colno, size_t *repeated_size) 5429cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5430cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint_fast16_t count = item->count ?: 1; 5431cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5432cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define TYPES \ 5433cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8, 4); \ 5434cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16, 6); \ 5435cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32, 11); \ 5436cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32, 11); \ 5437cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64, 20); \ 5438cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64, 20) 5439cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5440cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define DO_TYPE(NAME, Name, hex, dec, max) GElf_##Name Name[count] 5441cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng union { TYPES; } value; 5442cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#undef DO_TYPE 5443cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5444cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void *data = &value; 5445cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t size = gelf_fsize (core, item->type, count, EV_CURRENT); 5446cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t convsize = size; 5447cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (repeated_size != NULL) 5448cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5449cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (*repeated_size > size && (item->format == 'b' || item->format == 'B')) 5450cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5451cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng data = alloca (*repeated_size); 5452cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng count *= *repeated_size / size; 5453cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng convsize = count * size; 5454cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng *repeated_size -= convsize; 5455cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5456cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 5457cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng *repeated_size -= size; 5458cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5459cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5460cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc = convert (core, item->type, count, data, desc + item->offset, convsize); 5461cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5462cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Type type = item->type; 5463cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (type == ELF_T_ADDR) 5464cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD; 5465cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5466cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (item->format) 5467cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5468cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'd': 5469cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (count == 1); 5470cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (type) 5471cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5472cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define DO_TYPE(NAME, Name, hex, dec, max) \ 5473cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case ELF_T_##NAME: \ 5474cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, \ 5475cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 0, item->name, max, dec, value.Name[0]); \ 5476cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break 5477cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng TYPES; 5478cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#undef DO_TYPE 5479cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 5480cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng abort (); 5481cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5482cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5483cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5484cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'x': 5485cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (count == 1); 5486cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (type) 5487cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5488cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define DO_TYPE(NAME, Name, hex, dec, max) \ 5489cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case ELF_T_##NAME: \ 5490cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, \ 5491cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 0, item->name, max, hex, value.Name[0]); \ 5492cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break 5493cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng TYPES; 5494cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#undef DO_TYPE 5495cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 5496cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng abort (); 5497cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5498cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5499cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5500cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'b': 5501cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'B': 5502cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (size % sizeof (unsigned int) == 0); 5503cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int nbits = count * size * 8; 5504cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int pop = 0; 5505cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (const unsigned int *i = data; (void *) i < data + count * size; ++i) 5506cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng pop += __builtin_popcount (*i); 5507cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bool negate = pop > nbits / 2; 5508cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const unsigned int bias = item->format == 'b'; 5509cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5510cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5511cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char printed[(negate ? nbits - pop : pop) * 16]; 5512cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *p = printed; 5513cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng *p = '\0'; 5514cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5515cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int)) 5516cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5517cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (size == sizeof (unsigned int) * 2); 5518cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (unsigned int *i = data; 5519cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (void *) i < data + count * size; i += 2) 5520cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5521cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int w = i[1]; 5522cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng i[1] = i[0]; 5523cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng i[0] = w; 5524cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5525cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5526cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5527cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int lastbit = 0; 5528cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (const unsigned int *i = data; 5529cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (void *) i < data + count * size; ++i) 5530cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5531cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int bit = ((void *) i - data) * 8; 5532cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int w = negate ? ~*i : *i; 5533cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (w != 0) 5534cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5535cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int n = ffs (w); 5536cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng w >>= n; 5537cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bit += n; 5538cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5539cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (lastbit + 1 != bit) 5540cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias); 5541cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (lastbit == 0) 5542cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng p += sprintf (p, "%u", bit - bias); 5543cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5544cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng lastbit = bit; 5545cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5546cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5547cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (lastbit > 0 && lastbit + 1 != nbits) 5548cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng p += sprintf (p, "-%u", nbits - bias); 5549cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5550cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name, 5551cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 4 + nbits * 4, 5552cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng negate ? "~<%s>" : "<%s>", printed); 5553cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5554cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5555cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5556cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'T': 5557cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case (char) ('T'|0x80): 5558cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (count == 2); 5559cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Word sec; 5560cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Word usec; 5561cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t maxfmt = 7; 5562cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (type) 5563cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5564cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define DO_TYPE(NAME, Name, hex, dec, max) \ 5565cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case ELF_T_##NAME: \ 5566cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng sec = value.Name[0]; \ 5567cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng usec = value.Name[1]; \ 5568cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng maxfmt += max; \ 5569cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break 5570cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng TYPES; 5571cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#undef DO_TYPE 5572cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 5573cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng abort (); 5574cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5575cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (item->format == (char) ('T'|0x80))) 5576cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5577cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* This is a hack for an ill-considered 64-bit ABI where 5578cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng tv_usec is actually a 32-bit field with 32 bits of padding 5579cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng rounding out struct timeval. We've already converted it as 5580cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng a 64-bit field. For little-endian, this just means the 5581cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng high half is the padding; it's presumably zero, but should 5582cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng be ignored anyway. For big-endian, it means the 32-bit 5583cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng field went into the high half of USEC. */ 5584cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr ehdr_mem; 5585cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem); 5586cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)) 5587cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng usec >>= 32; 5588cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 5589cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng usec &= UINT32_MAX; 5590cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5591cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name, 5592cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng maxfmt, "%" PRIu64 ".%.6" PRIu64, sec, usec); 5593cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5594cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5595cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'c': 5596cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (count == 1); 5597cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name, 5598cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 1, "%c", value.Byte[0]); 5599cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5600cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5601cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 's': 5602cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ',', ITEM_WRAP_COLUMN, 0, item->name, 5603cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng count, "%.*s", (int) count, value.Byte); 5604cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5605cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5606cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 5607cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, "XXX not handling format '%c' for %s", 5608cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng item->format, item->name); 5609cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5610cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5611cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5612cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#undef TYPES 5613cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5614cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return colno; 5615cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5616cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5617cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5618cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Sort items by group, and by layout offset within each group. */ 5619cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 5620cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengcompare_core_items (const void *a, const void *b) 5621cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5622cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *const *p1 = a; 5623cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *const *p2 = b; 5624cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *item1 = *p1; 5625cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *item2 = *p2; 5626cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5627cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return ((item1->group == item2->group ? 0 5628cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : strcmp (item1->group, item2->group)) 5629cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ?: (int) item1->offset - (int) item2->offset); 5630cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5631cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5632cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Sort item groups by layout offset of the first item in the group. */ 5633cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 5634cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengcompare_core_item_groups (const void *a, const void *b) 5635cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5636cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *const *const *p1 = a; 5637cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *const *const *p2 = b; 5638cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *const *group1 = *p1; 5639cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *const *group2 = *p2; 5640cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *item1 = *group1; 5641cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *item2 = *group2; 5642cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5643cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return (int) item1->offset - (int) item2->offset; 5644cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5645cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5646cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic unsigned int 5647cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_core_items (Elf *core, const void *desc, size_t descsz, 5648cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *items, size_t nitems) 5649cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5650cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (nitems == 0) 5651cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return 0; 5652cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5653cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Sort to collect the groups together. */ 5654cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *sorted_items[nitems]; 5655cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t i = 0; i < nitems; ++i) 5656cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng sorted_items[i] = &items[i]; 5657cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items); 5658cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5659cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Collect the unique groups and sort them. */ 5660cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item **groups[nitems]; 5661cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng groups[0] = &sorted_items[0]; 5662cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t ngroups = 1; 5663cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t i = 1; i < nitems; ++i) 5664cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (sorted_items[i]->group != sorted_items[i - 1]->group 5665cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group)) 5666cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng groups[ngroups++] = &sorted_items[i]; 5667cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups); 5668cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5669cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Write out all the groups. */ 5670cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int colno = 0; 5671cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5672cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const void *last = desc; 5673cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (nitems == 1) 5674cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5675cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t size = descsz; 5676cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = handle_core_item (core, sorted_items[0], desc, colno, &size); 5677cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (size == 0) 5678cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return colno; 5679cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc += descsz - size; 5680cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng descsz = size; 5681cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5682cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5683cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng do 5684cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5685cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t i = 0; i < ngroups; ++i) 5686cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5687cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (const Ebl_Core_Item **item = groups[i]; 5688cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (item < &sorted_items[nitems] 5689cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && ((*item)->group == groups[i][0]->group 5690cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || !strcmp ((*item)->group, groups[i][0]->group))); 5691cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++item) 5692cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = handle_core_item (core, *item, desc, colno, NULL); 5693cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5694cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Force a line break at the end of the group. */ 5695cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = ITEM_WRAP_COLUMN; 5696cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5697cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5698cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (descsz == 0) 5699cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5700cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5701cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* This set of items consumed a certain amount of the note's data. 5702cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng If there is more data there, we have another unit of the same size. 5703cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Loop to print that out too. */ 5704cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *item = &items[nitems - 1]; 5705cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t eltsz = item->offset + gelf_fsize (core, item->type, 5706cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng item->count ?: 1, EV_CURRENT); 5707cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5708cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int reps = -1; 5709cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng do 5710cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5711cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++reps; 5712cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc += eltsz; 5713cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng descsz -= eltsz; 5714cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5715cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (descsz >= eltsz && !memcmp (desc, last, eltsz)); 5716cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5717cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (reps == 1) 5718cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5719cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* For just one repeat, print it unabridged twice. */ 5720cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc -= eltsz; 5721cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng descsz += eltsz; 5722cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5723cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else if (reps > 1) 5724cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\n%*s... <repeats %u more times> ..."), 5725cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ITEM_INDENT, "", reps); 5726cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5727cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng last = desc; 5728cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5729cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (descsz > 0); 5730cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5731cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return colno; 5732cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5734cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic unsigned int 5735cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_bit_registers (const Ebl_Register_Location *regloc, const void *desc, 5736cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int colno) 5737cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5738cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc += regloc->offset; 5739cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5740cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng abort (); /* XXX */ 5741cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return colno; 5742441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 5743441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5744441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5745cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic unsigned int 5746cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_core_register (Ebl *ebl, Elf *core, int maxregname, 5747cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Register_Location *regloc, const void *desc, 5748cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int colno) 5749cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5750cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (regloc->bits % 8 != 0) 5751cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return handle_bit_registers (regloc, desc, colno); 5752cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5753cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc += regloc->offset; 5754cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5755cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg) 5756cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5757cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *pfx; 5758cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *set; 5759cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char name[16]; 5760cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int bits; 5761cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int type; 5762cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ssize_t n = ebl_register_info (ebl, reg, name, sizeof name, 5763cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &pfx, &set, &bits, &type); 5764cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (n <= 0) 5765cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 5766cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("unable to handle register number %d"), 5767cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng regloc->regno); 5768cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5769cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define TYPES \ 5770cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8, 4); \ 5771cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16, 6); \ 5772cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32, 11); \ 5773cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64, 20) 5774cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5775cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define BITS(bits, xtype, sfmt, ufmt, max) \ 5776cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint##bits##_t b##bits; int##bits##_t b##bits##s 5777cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng union { TYPES; uint64_t b128[2]; } value; 5778cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#undef BITS 5779cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5780cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (type) 5781cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5782cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_ATE_unsigned: 5783cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_ATE_signed: 5784cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case DW_ATE_address: 5785cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (bits) 5786cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5787cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define BITS(bits, xtype, sfmt, ufmt, max) \ 5788cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case bits: \ 5789cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \ 5790cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (type == DW_ATE_signed) \ 5791cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, \ 5792cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng maxregname, name, \ 5793cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng max, sfmt, value.b##bits##s); \ 5794cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else \ 5795cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, \ 5796cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng maxregname, name, \ 5797cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng max, ufmt, value.b##bits); \ 5798cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break 5799cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5800cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng TYPES; 5801cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5802cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 128: 5803cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (type == DW_ATE_unsigned); 5804cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0); 5805cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB; 5806cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, 5807cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng maxregname, name, 5808cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 34, "0x%.16" PRIx64 "%.16" PRIx64, 5809cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng value.b128[!be], value.b128[be]); 5810cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5811cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5812cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 5813cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng abort (); 5814cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#undef BITS 5815cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5816cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5817cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5818cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 5819cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Print each byte in hex, the whole thing in native byte order. */ 5820cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (bits % 8 == 0); 5821cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const uint8_t *bytes = desc; 5822cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc += bits / 8; 5823cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char hex[bits / 4 + 1]; 5824cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng hex[bits / 4] = '\0'; 5825cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int incr = 1; 5826cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB) 5827cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5828cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bytes += bits / 8 - 1; 5829cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng incr = -1; 5830cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5831cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t idx = 0; 5832cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (char *h = hex; bits > 0; bits -= 8, idx += incr) 5833cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5834cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng *h++ = "0123456789abcdef"[bytes[idx] >> 4]; 5835cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng *h++ = "0123456789abcdef"[bytes[idx] & 0xf]; 5836cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5837cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = print_core_item (colno, ' ', REGISTER_WRAP_COLUMN, 5838cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng maxregname, name, 5839cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 2 + sizeof hex - 1, "0x%s", hex); 5840cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 5841cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5842cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng desc += regloc->pad; 5843cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5844cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#undef TYPES 5845cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5846cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5847cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return colno; 5848cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5849cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5850cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5851cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstruct register_info 5852cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5853cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Register_Location *regloc; 5854cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *set; 5855cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char name[16]; 5856cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Dwarf_Half regno; 5857cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint8_t bits; 5858cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng uint8_t type; 5859cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}; 5860cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5861cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 5862cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengregister_bitpos (const struct register_info *r) 5863cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5864cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return (r->regloc->offset * 8 5865cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng + ((r->regno - r->regloc->regno) 5866cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng * (r->regloc->bits + r->regloc->pad * 8))); 5867cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5868cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5869cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 5870cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengcompare_sets_by_info (const struct register_info *r1, 5871cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const struct register_info *r2) 5872cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5873cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return ((int) r2->bits - (int) r1->bits 5874cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ?: register_bitpos (r1) - register_bitpos (r2)); 5875cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5876cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5877cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Sort registers by set, and by size and layout offset within each set. */ 5878cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 5879cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengcompare_registers (const void *a, const void *b) 5880cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5881cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const struct register_info *r1 = a; 5882cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const struct register_info *r2 = b; 5883cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5884cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Unused elements sort last. */ 5885cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (r1->regloc == NULL) 5886cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return r2->regloc == NULL ? 0 : 1; 5887cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (r2->regloc == NULL) 5888cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return -1; 5889cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5890cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set)) 5891cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ?: compare_sets_by_info (r1, r2)); 5892cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5893cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5894cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Sort register sets by layout offset of the first register in the set. */ 5895cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int 5896cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengcompare_register_sets (const void *a, const void *b) 5897cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5898cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const struct register_info *const *p1 = a; 5899cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const struct register_info *const *p2 = b; 5900cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return compare_sets_by_info (*p1, *p2); 5901cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5902cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5903cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic unsigned int 5904cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_core_registers (Ebl *ebl, Elf *core, const void *desc, 5905cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Register_Location *reglocs, size_t nregloc) 5906cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5907cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (nregloc == 0) 5908cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return 0; 5909cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5910cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL); 5911cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (maxnreg <= 0) 5912cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 5913cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot register info: %s"), elf_errmsg (-1)); 5914cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5915cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct register_info regs[maxnreg]; 5916cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng memset (regs, 0, sizeof regs); 5917cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5918cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Sort to collect the sets together. */ 5919cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int maxreg = 0; 5920cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t i = 0; i < nregloc; ++i) 5921cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int reg = reglocs[i].regno; 5922cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng reg < reglocs[i].regno + reglocs[i].count; 5923cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ++reg) 5924cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5925cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng assert (reg < maxnreg); 5926cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (reg > maxreg) 5927cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng maxreg = reg; 5928cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct register_info *info = ®s[reg]; 5929cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5930cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *pfx; 5931cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int bits; 5932cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int type; 5933cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ssize_t n = ebl_register_info (ebl, reg, info->name, sizeof info->name, 5934cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &pfx, &info->set, &bits, &type); 5935cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (n <= 0) 5936cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 5937cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot register info: %s"), elf_errmsg (-1)); 5938cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5939cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng info->regloc = ®locs[i]; 5940cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng info->regno = reg; 5941cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng info->bits = bits; 5942cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng info->type = type; 5943cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5944cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers); 5945cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5946cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Collect the unique sets and sort them. */ 5947cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng inline bool same_set (const struct register_info *a, 5948cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const struct register_info *b) 5949cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5950cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return (a < ®s[maxnreg] && a->regloc != NULL 5951cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && b < ®s[maxnreg] && b->regloc != NULL 5952cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && a->bits == b->bits 5953cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && (a->set == b->set || !strcmp (a->set, b->set))); 5954cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5955cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng struct register_info *sets[maxreg + 1]; 5956cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng sets[0] = ®s[0]; 5957cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t nsets = 1; 5958cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (int i = 1; i <= maxreg; ++i) 5959cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1])) 5960cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng sets[nsets++] = ®s[i]; 5961cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng qsort (sets, nsets, sizeof sets[0], &compare_register_sets); 5962cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5963cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Write out all the sets. */ 5964cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int colno = 0; 5965cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t i = 0; i < nsets; ++i) 5966cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5967cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Find the longest name of a register in this set. */ 5968cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t maxname = 0; 5969cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const struct register_info *end; 5970cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (end = sets[i]; same_set (sets[i], end); ++end) 5971cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 5972cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t len = strlen (end->name); 5973cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (len > maxname) 5974cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng maxname = len; 5975cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5976cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5977cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (const struct register_info *reg = sets[i]; 5978cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng reg < end; 5979cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng reg += reg->regloc->count ?: 1) 5980cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = handle_core_register (ebl, core, maxname, 5981cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng reg->regloc, desc, colno); 5982cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5983cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Force a line break at the end of the group. */ 5984cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = REGISTER_WRAP_COLUMN; 5985cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 5986cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5987cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return colno; 5988cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 5989cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5990cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 5991cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos) 5992cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 5993cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV); 5994cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (data == NULL) 5995cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_error: 5996cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 5997cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot convert core note data: %s"), elf_errmsg (-1)); 5998cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 5999cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT); 6000cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t i = 0; i < nauxv; ++i) 6001cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6002cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_auxv_t av_mem; 6003cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem); 6004cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (av == NULL) 6005cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto elf_error; 6006cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6007cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *name; 6008cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *fmt; 6009cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0) 6010cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6011cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Unknown type. */ 6012cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (av->a_un.a_val == 0) 6013cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %" PRIu64 "\n", av->a_type); 6014cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6015cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %" PRIu64 ": %#" PRIx64 "\n", 6016cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng av->a_type, av->a_un.a_val); 6017cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6018cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6019cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng switch (fmt[0]) 6020cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6021cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case '\0': /* Normally zero. */ 6022cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (av->a_un.a_val == 0) 6023cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6024cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %s\n", name); 6025cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 6026cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6027cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Fall through */ 6028cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'x': /* hex */ 6029cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'p': /* address */ 6030cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 's': /* address of string */ 6031cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val); 6032cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 6033cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'u': 6034cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val); 6035cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 6036cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'd': 6037cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %s: %" PRId64 "\n", name, av->a_un.a_val); 6038cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 6039cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6040cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng case 'b': 6041cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val); 6042cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Xword bit = 1; 6043cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *pfx = "<"; 6044cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1) 6045cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6046cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (av->a_un.a_val & bit) 6047cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6048cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%s%s", pfx, p); 6049cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng pfx = " "; 6050cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6051cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bit <<= 1; 6052cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6053cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (">\n"); 6054cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 6055cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6056cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng default: 6057cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng abort (); 6058cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6059cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6060cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6061cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6062cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6063cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const void *desc) 6064cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6065cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Word regs_offset; 6066cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t nregloc; 6067cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Register_Location *reglocs; 6068cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t nitems; 6069cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Ebl_Core_Item *items; 6070cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6071cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (! ebl_core_note (ebl, nhdr->n_type, nhdr->n_descsz, 6072cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ®s_offset, &nregloc, ®locs, &nitems, &items)) 6073cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 6074cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6075cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Pass 0 for DESCSZ when there are registers in the note, 6076cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng so that the ITEMS array does not describe the whole thing. 6077cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng For non-register notes, the actual descsz might be a multiple 6078cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng of the unit size, not just exactly the unit size. */ 6079cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned int colno = handle_core_items (ebl->elf, desc, 6080cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng nregloc == 0 ? nhdr->n_descsz : 0, 6081cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng items, nitems); 6082cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (colno != 0) 6083cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng putchar_unlocked ('\n'); 6084cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6085cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset, 6086cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng reglocs, nregloc); 6087cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (colno != 0) 6088cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng putchar_unlocked ('\n'); 6089cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6090cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6091cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6092cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr, 6093cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Off start, Elf_Data *data) 6094cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6095cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fputs_unlocked (gettext (" Owner Data size Type\n"), stdout); 6096cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6097cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (data == NULL) 6098cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng goto bad_note; 6099cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6100cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t offset = 0; 6101cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Nhdr nhdr; 6102cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t name_offset; 6103cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t desc_offset; 6104cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (offset < data->d_size 6105cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && (offset = gelf_getnote (data, offset, 6106cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng &nhdr, &name_offset, &desc_offset)) > 0) 6107cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6108cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *name = data->d_buf + name_offset; 6109cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *desc = data->d_buf + desc_offset; 6110cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6111cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char buf[100]; 6112cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char buf2[100]; 6113cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext (" %-13.*s %9" PRId32 " %s\n"), 6114cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (int) nhdr.n_namesz, name, nhdr.n_descsz, 6115cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ehdr->e_type == ET_CORE 6116cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ? ebl_core_note_type_name (ebl, nhdr.n_type, 6117cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng buf, sizeof (buf)) 6118cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng : ebl_object_note_type_name (ebl, nhdr.n_type, 6119cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng buf2, sizeof (buf2))); 6120cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6121cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Filter out invalid entries. */ 6122cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (memchr (name, '\0', nhdr.n_namesz) != NULL 6123cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* XXX For now help broken Linux kernels. */ 6124cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || 1) 6125cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6126cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (ehdr->e_type == ET_CORE) 6127cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6128cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (nhdr.n_type == NT_AUXV) 6129cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz, 6130cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng start + desc_offset); 6131cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6132cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_core_note (ebl, &nhdr, desc); 6133cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6134cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6135cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc); 6136cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6137cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6138cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6139cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (offset == data->d_size) 6140cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 6141cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6142cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng bad_note: 6143cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 6144cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot get content of note section: %s"), 6145cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_errmsg (-1)); 6146cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6147cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 6149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projecthandle_notes (Ebl *ebl, GElf_Ehdr *ehdr) 6150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 6151cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* If we have section headers, just look for SHT_NOTE sections. 6152cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng In a debuginfo file, the program headers are not reliable. */ 6153cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shnum != 0) 6154cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6155cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Get the section header string table index. */ 6156cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 6157cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (elf_getshstrndx (ebl->elf, &shstrndx) < 0) 6158cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 6159cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot get section header string table index")); 6160cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6161cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn = NULL; 6162cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 6163cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6164cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr shdr_mem; 6165cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 6166cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6167cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shdr == NULL || shdr->sh_type != SHT_NOTE) 6168cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Not what we are looking for. */ 6169cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 6170cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6171cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\ 6172cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng\nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"), 6173cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), 6174cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 6175cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng shdr->sh_size, shdr->sh_offset); 6176cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6177cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_notes_data (ebl, ehdr, shdr->sh_offset, 6178cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_getdata (scn, NULL)); 6179cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6180cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 6181cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We have to look through the program header to find the note 6184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sections. There can be more than one. */ 6185cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t cnt = 0; cnt < ehdr->e_phnum; ++cnt) 6186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 6187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr mem; 6188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem); 6189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr == NULL || phdr->p_type != PT_NOTE) 6191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Not what we are looking for. */ 6192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 6193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (gettext ("\ 6195cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng\nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"), 6196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr->p_filesz, phdr->p_offset); 6197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6198cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng handle_notes_data (ebl, ehdr, phdr->p_offset, 6199cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_getdata_rawchunk (ebl->elf, 6200cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng phdr->p_offset, phdr->p_filesz, 6201cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ELF_T_NHDR)); 6202cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6203cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6206cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6207cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghex_dump (const uint8_t *data, size_t len) 6208cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6209cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t pos = 0; 6210cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (pos < len) 6211cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6212cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" 0x%08Zx ", pos); 6213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6214cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const size_t chunk = MIN (len - pos, 16); 6215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6216cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t i = 0; i < chunk; ++i) 6217cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (i % 4 == 3) 6218cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%02x ", data[pos + i]); 6219cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6220cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%02x", data[pos + i]); 6221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6222cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (chunk < 16) 6223cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), ""); 6224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6225cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t i = 0; i < chunk; ++i) 6226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 6227cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned char b = data[pos + i]; 6228cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("%c", isprint (b) ? b : '.'); 6229cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6230cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6231cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng putchar ('\n'); 6232cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng pos += chunk; 6233cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6234cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6235cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6236cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6237cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) 6238cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6239cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS) 6240cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"), 6241cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), name); 6242cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6243cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6244cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_rawdata (scn, NULL); 6245cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (data == NULL) 6246cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"), 6247cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), name, elf_errmsg (-1)); 6248cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6249cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6250cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64 6251cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng " bytes at offset %#0" PRIx64 ":\n"), 6252cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), name, 6253cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng shdr->sh_size, shdr->sh_offset); 6254cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng hex_dump (data->d_buf, data->d_size); 6255cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6256cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6257cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6259cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6260cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name) 6261cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6262cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shdr->sh_size == 0) 6263cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\nSection [%Zu] '%s' is empty.\n"), 6264cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), name); 6265cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6266cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = elf_rawdata (scn, NULL); 6267cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (data == NULL) 6268cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"), 6269cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), name, elf_errmsg (-1)); 6270cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6271cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6272cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64 6273cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng " bytes at offset %#0" PRIx64 ":\n"), 6274cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_ndxscn (scn), name, 6275cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng shdr->sh_size, shdr->sh_offset); 6276cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6277cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *start = data->d_buf; 6278cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *const limit = start + data->d_size; 6279cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng do 6280cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6281cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *end = memchr (start, '\0', limit - start); 6282cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const size_t pos = start - (const char *) data->d_buf; 6283cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (end == NULL)) 6284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 6285cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" [%6Zx]- %.*s\n", 6286cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng pos, (int) (limit - start), start); 6287cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 6288cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6289cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (" [%6Zx] %s\n", pos, start); 6290cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng start = end + 1; 6291cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } while (start < limit); 6292cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6293cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6294cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6295cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6296cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengfor_each_section_argument (Elf *elf, const struct section_argument *list, 6297cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr, 6298cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *name)) 6299cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6300cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Get the section header string table index. */ 6301cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 6302cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (elf_getshstrndx (elf, &shstrndx) < 0) 6303cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 6304cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot get section header string table index")); 6305cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6306cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (const struct section_argument *a = list; a != NULL; a = a->next) 6307cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6308cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn; 6309cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr shdr_mem; 6310cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *name = NULL; 6311cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6312cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng char *endp = NULL; 6313cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng unsigned long int shndx = strtoul (a->arg, &endp, 0); 6314cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (endp != a->arg && *endp == '\0') 6315cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6316cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn = elf_getscn (elf, shndx); 6317cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (scn == NULL) 6318cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6319cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx); 6320cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 6321cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6322cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6323cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (gelf_getshdr (scn, &shdr_mem) == NULL) 6324cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"), 6325cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_errmsg (-1)); 6326cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng name = elf_strptr (elf, shstrndx, shdr_mem.sh_name); 6327cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6328cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6329cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6330cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Need to look up the section by name. */ 6331cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn = NULL; 6332cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while ((scn = elf_nextscn (elf, scn)) != NULL) 6333cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6334cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (gelf_getshdr (scn, &shdr_mem) == NULL) 6335cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 6336cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng name = elf_strptr (elf, shstrndx, shdr_mem.sh_name); 6337cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (name == NULL) 6338cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 6339cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (!strcmp (name, a->arg)) 6340cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng break; 6341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 6342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6343cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (scn == NULL)) 6344cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6345cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg); 6346cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 6347cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6348cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6349cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6350cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (*dump) (scn, &shdr_mem, name); 6351cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6352cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6353cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6354cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6355cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdump_data (Ebl *ebl) 6356cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6357cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section); 6358cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6359cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6360cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6361cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdump_strings (Ebl *ebl) 6362cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6363cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for_each_section_argument (ebl->elf, string_sections, &print_string_section); 6364cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6365cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6366cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6367cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_strings (Ebl *ebl) 6368cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6369cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Get the section header string table index. */ 6370cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t shstrndx; 6371cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0)) 6372cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 6373cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot get section header string table index")); 6374cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6375cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn; 6376cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng GElf_Shdr shdr_mem; 6377cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const char *name; 6378cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng scn = NULL; 6379cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 6380cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6381cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (gelf_getshdr (scn, &shdr_mem) == NULL) 6382cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 6383cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6384cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (shdr_mem.sh_type != SHT_PROGBITS 6385cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || !(shdr_mem.sh_flags & SHF_STRINGS)) 6386cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 6387cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6388cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name); 6389cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (name == NULL) 6390cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng continue; 6391cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6392cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng print_string_section (scn, &shdr_mem, name); 6393cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6394cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} 6395cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6396cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void 6397cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdump_archive_index (Elf *elf, const char *fname) 6398cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{ 6399cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t narsym; 6400cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Elf_Arsym *arsym = elf_getarsym (elf, &narsym); 6401cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (arsym == NULL) 6402cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6403cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int result = elf_errno (); 6404cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (result != ELF_E_NO_INDEX)) 6405cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 6406cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot get symbol index of archive '%s': %s"), 6407cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fname, elf_errmsg (result)); 6408cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 6409cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\nArchive '%s' has no symbol index\n"), fname); 6410cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return; 6411cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 6412cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6413cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("\nIndex of archive '%s' has %Zu entries:\n"), 6414cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng fname, narsym); 6415cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6416cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng size_t as_off = 0; 6417cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s) 6418cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6419cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (s->as_off != as_off) 6420cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 6421cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng as_off = s->as_off; 6422cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6423cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf *subelf; 6424cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (elf_rand (elf, as_off) == 0) 6425cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf)) 6426cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng == NULL)) 6427cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7) 6428cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng while (1) 6429cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#endif 6430cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng error (EXIT_FAILURE, 0, 6431cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng gettext ("cannot extract member at offset %Zu in '%s': %s"), 6432cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng as_off, fname, elf_errmsg (-1)); 6433cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6434cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng const Elf_Arhdr *h = elf_getarhdr (subelf); 6435cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6436cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf (gettext ("Archive member '%s' contains:\n"), h->ar_name); 6437cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6438cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng elf_end (subelf); 6439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 6440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6441cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng printf ("\t%s\n", s->as_name); 6442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 6443441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 6444cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 6445cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include "debugpred.h" 6446