elflint.c revision 441f72d43a9b550baa779fc82f70816da5f74f0e
1441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Pedantic checking of ELF files compliance with gABI/psABI spec. 2441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc. 3441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Written by Ulrich Drepper <drepper@redhat.com>, 2001. 4441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 5441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project This program is Open Source software; you can redistribute it and/or 6441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project modify it under the terms of the Open Software License version 1.0 as 7441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project published by the Open Source Initiative. 8441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 9441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project You should have received a copy of the Open Software License along 10441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project with this program; if not, you may obtain a copy of the Open Software 11441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project License version 1.0 from http://www.opensource.org/licenses/osl.php or 12441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 13441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 3001 King Ranch Road, Ukiah, CA 95482. */ 14441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 15441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifdef HAVE_CONFIG_H 16441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project# include <config.h> 17441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif 18441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 19441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <argp.h> 20441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <assert.h> 21441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <byteswap.h> 22441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <endian.h> 23441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <error.h> 24441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <fcntl.h> 25441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <gelf.h> 26441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <inttypes.h> 27441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libebl.h> 28441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libintl.h> 29441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <locale.h> 30441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdbool.h> 31441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdlib.h> 32441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <string.h> 33441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <unistd.h> 34441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <sys/param.h> 35441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 36441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <elf-knowledge.h> 37441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <system.h> 38441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 39441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 40441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Name and version of program. */ 41441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_version (FILE *stream, struct argp_state *state); 42441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectvoid (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; 43441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 44441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 45441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define ARGP_strict 300 46441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define ARGP_gnuld 301 47441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 48441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Definitions of arguments for argp functions. */ 49441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const struct argp_option options[] = 50441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 51441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 52441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { "strict", ARGP_strict, NULL, 0, 53441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project N_("Be extremely strict, flag level 2 features.") }, 54441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { "quiet", 'q', NULL, 0, N_("Do not print anything if successful") }, 55441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { "gnu-ld", ARGP_gnuld, NULL, 0, 56441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project N_("Binary has been created with GNU ld and is therefore known to be \ 57441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectbroken in certain ways") }, 58441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { NULL, 0, NULL, 0, NULL } 59441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}; 60441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 61441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Short description of program. */ 62441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char doc[] = N_("\ 63441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectPedantic checking of ELF files compliance with gABI/psABI spec."); 64441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 65441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Strings for arguments in help texts. */ 66441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char args_doc[] = N_("FILE..."); 67441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 68441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Prototype for option handler. */ 69441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 70441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 71441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Function to print some extra text in the help message. */ 72441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic char *more_help (int key, const char *text, void *input); 73441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 74441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Data structure to communicate with argp functions. */ 75441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic struct argp argp = 76441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 77441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project options, parse_opt, args_doc, doc, NULL, more_help 78441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}; 79441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 80441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 81441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Declarations of local functions. */ 82441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void process_file (int fd, Elf *elf, const char *prefix, 83441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *suffix, const char *fname, size_t size, 84441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool only_one); 85441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void process_elf_file (Elf *elf, const char *prefix, const char *suffix, 86441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *fname, size_t size, bool only_one); 87441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 88441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Report an error. */ 89441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define ERROR(str, args...) \ 90441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project do { \ 91441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf (str, ##args); \ 92441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++error_count; \ 93441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } while (0) 94441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int error_count; 95441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 96441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if we should perform very strict testing. */ 97441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool be_strict; 98441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 99441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if no message is to be printed if the run is succesful. */ 100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool be_quiet; 101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* True if binary is assumed to be generated with GNU ld. */ 103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool gnuld; 104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Index of section header string table. */ 106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic uint32_t shstrndx; 107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Array to count references in section groups. */ 109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int *scnref; 110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectint 113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmain (int argc, char *argv[]) 114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int remaining; 116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool only_one; 117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Set locale. */ 119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project setlocale (LC_ALL, ""); 120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Initialize the message catalog. */ 122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project textdomain (PACKAGE); 123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Parse and process arguments. */ 125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project argp_parse (&argp, argc, argv, 0, &remaining, NULL); 126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* If no ELF file is given punt. */ 128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (remaining >= argc) 129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, 131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project program_invocation_short_name); 132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project exit (1); 133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Before we start tell the ELF library which version we are using. */ 136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_version (EV_CURRENT); 137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Now process all the files given at the command line. */ 139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project only_one = remaining + 1 == argc; 140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project do 141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int fd; 143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf *elf; 144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Open the file. */ 146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fd = open (argv[remaining], O_RDONLY); 147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (fd == -1) 148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project error (0, errno, gettext ("cannot open input file")); 150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Create an `Elf' descriptor. */ 154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf == NULL) 156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("cannot generate Elf descriptor: %s\n"), 157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project unsigned int prev_error_count = error_count; 161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project struct stat64 st; 162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (fstat64 (fd, &st) != 0) 164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("cannot stat '%s': %m\n", argv[remaining]); 166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project close (fd); 167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size, 171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project only_one); 172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Now we can close the descriptor. */ 174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf_end (elf) != 0) 175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("error while closing Elf descriptor: %s\n"), 176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (prev_error_count == error_count && !be_quiet) 179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project puts (gettext ("No errors")); 180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project close (fd); 183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (++remaining < argc); 185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return error_count != 0; 187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Handle program arguments. */ 191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic error_t 192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectparse_opt (int key, char *arg, struct argp_state *state) 193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (key) 195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case ARGP_strict: 197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project be_strict = true; 198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case 'q': 201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project be_quiet = true; 202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case ARGP_gnuld: 205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gnuld = true; 206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 209441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return ARGP_ERR_UNKNOWN; 210441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 211441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return 0; 212441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 214441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic char * 216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmore_help (int key, const char *text, void *input) 217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 218441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char *buf; 219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (key) 221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case ARGP_KEY_HELP_EXTRA: 223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We print some extra information. */ 224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (asprintf (&buf, gettext ("Please report bugs to %s.\n"), 225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project PACKAGE_BUGREPORT) < 0) 226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf = NULL; 227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return buf; 228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return (char *) text; 233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the version information. */ 237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_version (FILE *stream, struct argp_state *state) 239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, VERSION); 241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fprintf (stream, gettext ("\ 242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectCopyright (C) %s Red Hat, Inc.\n\ 243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectThis is free software; see the source for copying conditions. There is NO\n\ 244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project"), "2004"); 246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Process one file. */ 251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprocess_file (int fd, Elf *elf, const char *prefix, const char *suffix, 253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *fname, size_t size, bool only_one) 254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We can handle two types of files: ELF files and archives. */ 256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Kind kind = elf_kind (elf); 257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (kind) 259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case ELF_K_ELF: 261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Yes! It's an ELF file. */ 262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project process_elf_file (elf, prefix, suffix, fname, size, only_one); 263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case ELF_K_AR: 266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf *subelf; 268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Cmd cmd = ELF_C_READ_MMAP; 269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t fname_len = strlen (fname) + 1; 271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char new_prefix[prefix_len + 1 + fname_len]; 272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2]; 273441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char *cp = new_prefix; 274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Create the full name of the file. */ 276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (prefix != NULL) 277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cp = mempcpy (cp, prefix, prefix_len); 279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = '('; 280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project strcpy (stpcpy (new_suffix, suffix), ")"); 281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project new_suffix[0] = '\0'; 284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project memcpy (cp, fname, fname_len); 285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* It's an archive. We process each file in it. */ 287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project kind = elf_kind (subelf); 290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Call this function recursively. */ 292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (kind == ELF_K_ELF || kind == ELF_K_AR) 293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Arhdr *arhdr = elf_getarhdr (subelf); 295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (arhdr != NULL); 296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project process_file (fd, subelf, new_prefix, new_suffix, 298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project arhdr->ar_name, arhdr->ar_size, false); 299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 300441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get next archive element. */ 302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cmd = elf_next (subelf); 303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf_end (subelf) != 0) 304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"), 305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We cannot do anything. */ 312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectNot an ELF file - it has the wrong magic bytes at the start")); 314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char * 320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection_name (Ebl *ebl, GElf_Ehdr *ehdr, int idx) 321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem); 326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const int valid_e_machine[] = 332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370, 334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC, 335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM, 336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300, 337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE, 338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16, 339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7, 340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX, 341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM, 342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300, 343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA 344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 345441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define nvalid_e_machine \ 346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) 347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Number of sections. */ 350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic unsigned int shnum; 351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size) 355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[512]; 357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check e_ident field. */ 360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_MAG0] != ELFMAG0) 361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0); 362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_MAG1] != ELFMAG1) 363441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1); 364441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_MAG2] != ELFMAG2) 365441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2); 366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_MAG3] != ELFMAG3) 367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3); 368441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 369441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_CLASS] != ELFCLASS32 370441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_ident[EI_CLASS] != ELFCLASS64) 371441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("e_ident[%d] == %d is no known class\n"), 372441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EI_CLASS, ehdr->e_ident[EI_CLASS]); 373441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 374441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB 375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_ident[EI_DATA] != ELFDATA2MSB) 376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"), 377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EI_DATA, ehdr->e_ident[EI_DATA]); 378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) 380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"), 381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EI_VERSION, ehdr->e_ident[EI_VERSION]); 382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We currently don't handle any OS ABIs. */ 384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE) 385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("unsupported OS ABI e_ident[%d] == \"%s\"\n"), 386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EI_OSABI, 387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* No ABI versions other than zero supported either. */ 390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_ABIVERSION] != 0) 391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("unsupport ABI version e_ident[%d] == %d\n"), 392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]); 393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt) 395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[cnt] != 0) 396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt); 397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the e_type field. */ 399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC 400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE) 401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type); 402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the e_machine field. */ 404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 0; cnt < nvalid_e_machine; ++cnt) 405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (valid_e_machine[cnt] == ehdr->e_machine) 406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt == nvalid_e_machine) 408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine); 409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the e_version field. */ 411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_version != EV_CURRENT) 412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("unknown object file version\n")); 413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the e_phoff and e_phnum fields. */ 415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_phoff == 0) 416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_phnum != 0) 418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid program header offset\n")); 419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) 420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectexecutables and DSOs cannot have zero program header offset\n")); 422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (ehdr->e_phnum == 0) 424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid number of program header entries\n")); 425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the e_shoff field. */ 427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shnum = ehdr->e_shnum; 428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shstrndx = ehdr->e_shstrndx; 429441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_shoff == 0) 430441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_shnum != 0) 432441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid section header table offset\n")); 433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 434441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_type != ET_CORE) 435441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section header table must be present\n")); 436441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 437441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 438441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_shnum == 0) 440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 441441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the header of the zeroth section. The sh_size field 442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project might contain the section number. */ 443441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 444441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 445441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 446441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 447441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr != NULL) 448441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 449441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The error will be reported later. */ 450441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_size == 0) 451441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 452441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectinvalid number of section header table entries\n")); 453441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 454441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shnum = shdr->sh_size; 455441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 456441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 457441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 458441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_shstrndx == SHN_XINDEX) 459441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 460441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the header of the zeroth section. The sh_size field 461441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project might contain the section number. */ 462441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 463441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 464441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 465441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 466441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr != NULL) 467441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 468441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The error will be reported later. */ 469441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_link >= shnum) 470441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid section header index\n")); 471441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 472441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shstrndx = shdr->sh_link; 473441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 474441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 475441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (shstrndx >= shnum) 476441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid section header index\n")); 477441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 478441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 479441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the e_flags field. */ 480441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!ebl_machine_flag_check (ebl, ehdr->e_flags)) 481441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid machine flags: %s\n"), 482441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 483441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 484441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check e_ehsize, e_phentsize, and e_shentsize fields. */ 485441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (gelf_getclass (ebl->elf) == ELFCLASS32) 486441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 487441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr)) 488441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 489441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 490441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr)) 491441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid program header size: %hd\n"), 492441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_phentsize); 493441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size) 494441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid program header position or size\n")); 495441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 496441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr)) 497441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid section header size: %hd\n"), 498441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_shentsize); 499441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 500441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid section header position or size\n")); 501441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 502441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (gelf_getclass (ebl->elf) == ELFCLASS64) 503441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 504441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr)) 505441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 506441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 507441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr)) 508441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid program header size: %hd\n"), 509441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_phentsize); 510441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size) 511441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid program header position or size\n")); 512441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 513441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr)) 514441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid section header size: %hd\n"), 515441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_shentsize); 516441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 517441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("invalid section header position or size\n")); 518441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 519441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 520441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 521441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 522441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Check that there is a section group section with index < IDX which 523441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project contains section IDX and that there is exactly one. */ 524441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 525441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_scn_group (Ebl *ebl, GElf_Ehdr *ehdr, int idx) 526441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 527441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (scnref[idx] == 0) 528441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 529441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* No reference so far. Search following sections, maybe the 530441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project order is wrong. */ 531441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 532441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 533441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = idx + 1; cnt < shnum; ++cnt) 534441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 535441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn; 536441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 537441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 538441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data; 539441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word *grpdata; 540441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t inner; 541441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 542441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn = elf_getscn (ebl->elf, cnt); 543441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (scn, &shdr_mem); 544441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL) 545441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We cannot get the section header so we cannot check it. 546441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project The error to get the section header will be shown 547441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project somewhere else. */ 548441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 549441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 550441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_type != SHT_GROUP) 551441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 552441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 553441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data = elf_getdata (scn, NULL); 554441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL || data->d_size < sizeof (Elf32_Word)) 555441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Cannot check the section. */ 556441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 557441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 558441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project grpdata = (Elf32_Word *) data->d_buf; 559441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (inner = 1; inner < data->d_size / sizeof (Elf32_Word); ++inner) 560441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (grpdata[inner] == (Elf32_Word) idx) 561441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project goto out; 562441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 563441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 564441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project out: 565441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt == shnum) 566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 567441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"), 568441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 569441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 570441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 571441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section group [%2zu] '%s' does not preceed group member\n"), 572441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 573441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 574441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 575441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 576441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 577441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 578441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 579441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_symtab (Ebl *ebl, GElf_Ehdr *ehdr, int idx) 580441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 581441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool no_xndx_warned = false; 582441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int no_pt_tls = 0; 583441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 584441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = elf_getscn (ebl->elf, idx); 585441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 586441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 587441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr strshdr_mem; 588441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 589441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &strshdr_mem); 590441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL || strshdr == NULL) 591441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 592441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data = elf_getdata (scn, NULL); 593441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 594441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 595441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 596441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 597441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 598441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 599441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 600441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (strshdr->sh_type != SHT_STRTAB) 601441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 602441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_link, section_name (ebl, ehdr, shdr->sh_link), 603441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 604441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 605441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Search for an extended section index table section. */ 606441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 607441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr xndxshdr_mem; 608441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *xndxshdr = NULL; 609441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *xndxdata = NULL; 610441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word xndxscnidx = 0; 611441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 1; cnt < shnum; ++cnt) 612441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt != (size_t) idx) 613441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 614441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt); 615441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); 616441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndxdata = elf_getdata (xndxscn, NULL); 617441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndxscnidx = elf_ndxscn (xndxscn); 618441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 619441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (xndxshdr == NULL || xndxdata == NULL) 620441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 621441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 622441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX 623441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && xndxshdr->sh_link == (GElf_Word) idx) 624441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 625441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 626441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt == shnum) 627441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 628441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndxshdr = NULL; 629441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndxdata = NULL; 630441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 631441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 632441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)) 633441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 634441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': entry size is does not match ElfXX_Sym\n"), 635441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 636441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 637441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Test the zeroth entry. */ 638441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym sym_mem; 639441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word xndx; 640441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx); 641441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym == NULL) 642441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"), 643441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 0, elf_errmsg (-1)); 644441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 645441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 646441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_name != 0) 647441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 648441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), "st_name"); 649441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_value != 0) 650441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 651441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), "st_value"); 652441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_size != 0) 653441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 654441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), "st_size"); 655441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_info != 0) 656441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 657441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), "st_info"); 658441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_other != 0) 659441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 660441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), "st_other"); 661441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_shndx != 0) 662441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 663441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), "st_shndx"); 664441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (xndxdata != NULL && xndx != 0) 665441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 666441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': XINDEX for zeroth entry not zero\n"), 667441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndxscnidx, section_name (ebl, ehdr, xndxscnidx)); 668441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 669441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 670441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 671441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 672441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx); 673441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym == NULL) 674441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 675441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"), 676441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, elf_errmsg (-1)); 677441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 678441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 679441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 680441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *name = NULL; 681441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_name >= strshdr->sh_size) 682441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 683441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: invalid name value\n"), 684441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 685441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 686441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 687441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name); 688441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (name != NULL); 689441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 690441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 691441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_shndx == SHN_XINDEX) 692441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 693441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (xndxdata == NULL) 694441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 695441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 696441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"), 697441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 698441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project no_xndx_warned = true; 699441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 700441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (xndx < SHN_LORESERVE) 701441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 702441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"), 703441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndxscnidx, section_name (ebl, ehdr, xndxscnidx), cnt, 704441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndx); 705441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 706441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if ((sym->st_shndx >= SHN_LORESERVE 707441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // && sym->st_shndx <= SHN_HIRESERVE always true 708441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && sym->st_shndx != SHN_ABS 709441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && sym->st_shndx != SHN_COMMON) 710441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || (sym->st_shndx >= shnum 711441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (sym->st_shndx < SHN_LORESERVE 712441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* || sym->st_shndx > SHN_HIRESERVE always false */))) 713441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 714441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: invalid section index\n"), 715441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 716441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 717441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project xndx = sym->st_shndx; 718441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 719441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (GELF_ST_TYPE (sym->st_info) >= STT_NUM) 720441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"), 721441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 722441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 723441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (GELF_ST_BIND (sym->st_info) >= STB_NUM) 724441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 725441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: unknown symbol binding\n"), 726441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 727441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 728441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (xndx == SHN_COMMON) 729441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 730441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Common symbols can only appear in relocatable files. */ 731441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type != ET_REL) 732441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"), 734441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 735441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt < shdr->sh_info) 736441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 737441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"), 738441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 739441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (GELF_R_TYPE (sym->st_info) == STT_FUNC) 740441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 741441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"), 742441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 743441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 744441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (xndx > 0 && xndx < shnum) 745441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 746441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr destshdr_mem; 747441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *destshdr; 748441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 749441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem); 750441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (destshdr != NULL) 751441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 752441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (GELF_ST_TYPE (sym->st_info) != STT_TLS) 753441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 754441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((sym->st_value - destshdr->sh_addr) > destshdr->sh_size) 755441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 756441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: st_value out of bounds\n"), 757441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 758441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if ((sym->st_value - destshdr->sh_addr + sym->st_size) 759441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project > destshdr->sh_size) 760441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 761441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 762441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 763441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) xndx, section_name (ebl, ehdr, xndx)); 764441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 765441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 766441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 767441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((destshdr->sh_flags & SHF_TLS) == 0) 768441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 769441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"), 770441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 771441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) xndx, section_name (ebl, ehdr, xndx)); 772441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 773441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type == ET_REL) 774441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 775441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* For object files the symbol value must fall 776441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project into the section. */ 777441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_value > destshdr->sh_size) 778441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 779441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 780441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 781441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) xndx, section_name (ebl, ehdr, xndx)); 782441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (sym->st_value + sym->st_size 783441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project > destshdr->sh_size) 784441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 785441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 786441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 787441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) xndx, section_name (ebl, ehdr, xndx)); 788441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 789441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 790441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 791441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr phdr_mem; 792441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr *phdr = NULL; 793441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int pcnt; 794441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 795441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 796441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 797441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 798441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr != NULL && phdr->p_type == PT_TLS) 799441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 800441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 801441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 802441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (pcnt == ehdr->e_phnum) 803441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 804441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (no_pt_tls++ == 0) 805441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 806441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"), 807441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 808441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 809441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 810441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 811441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_value 812441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project < destshdr->sh_offset - phdr->p_offset) 813441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 814441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"), 815441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 816441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) xndx, section_name (ebl, ehdr, xndx)); 817441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (sym->st_value 818441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project > (destshdr->sh_offset - phdr->p_offset 819441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project + destshdr->sh_size)) 820441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 821441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 822441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 823441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) xndx, section_name (ebl, ehdr, xndx)); 824441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (sym->st_value + sym->st_size 825441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project > (destshdr->sh_offset - phdr->p_offset 826441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project + destshdr->sh_size)) 827441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 828441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 829441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 830441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) xndx, section_name (ebl, ehdr, xndx)); 831441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 832441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 833441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 834441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 835441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 836441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 837441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 838441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 839441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt >= shdr->sh_info) 840441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 841441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"), 842441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 843441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 844441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 845441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 846441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt < shdr->sh_info) 847441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 848441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"), 849441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 850441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 851441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 852441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (GELF_ST_TYPE (sym->st_info) == STT_SECTION 853441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 854441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 855441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': symbol %zu: non-local section symbol\n"), 856441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 857441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 858441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (name != NULL) 859441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 860441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 861441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 862441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check that address and size match the global offset 863441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project table. We have to locate the GOT by searching for a 864441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section named ".got". */ 865441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *gscn = NULL; 866441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 867441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL) 868441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 869441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr gshdr_mem; 870441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *gshdr = gelf_getshdr (gscn, &gshdr_mem); 871441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (gshdr != NULL); 872441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 873441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *sname = elf_strptr (ebl->elf, ehdr->e_shstrndx, 874441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gshdr->sh_name); 875441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sname != NULL && strcmp (sname, ".got") == 0) 876441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 877441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Found it. */ 878441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_value != gshdr->sh_addr) 879441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* This test is more strict than the psABIs 880441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project which usually allow the symbol to be in the 881441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project middle of the .got section, allowing 882441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project negative offsets. */ 883441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 884441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match .got section address %#" PRIx64 "\n"), 885441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 886441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) sym->st_value, 887441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) gshdr->sh_addr); 888441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 889441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_size != gshdr->sh_size) 890441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 891441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match .got section size %" PRIu64 "\n"), 892441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 893441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) sym->st_size, 894441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) gshdr->sh_size); 895441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 896441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 897441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 898441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 899441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 900441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (gscn == NULL) 901441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 902441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"), 903441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 904441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 905441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (strcmp (name, "_DYNAMIC") == 0) 906441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 907441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check that address and size match the dynamic 908441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section. We locate the dynamic section via the 909441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project program header entry. */ 910441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int pcnt; 911441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 912441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 913441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 914441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr phdr_mem; 915441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 916441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 917441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 918441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 919441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_value != phdr->p_vaddr) 920441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 921441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"), 922441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 923441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) sym->st_value, 924441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) phdr->p_vaddr); 925441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 926441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_size != phdr->p_memsz) 927441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 928441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"), 929441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 930441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) sym->st_size, 931441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint64_t) phdr->p_memsz); 932441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 933441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 934441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 935441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 936441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 937441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 938441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 939441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 940441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 941441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 942441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool 943441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectis_rel_dyn (Ebl *ebl, GElf_Ehdr *ehdr, int idx, GElf_Shdr *shdr, bool rela) 944441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 945441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* If this is no executable or DSO it cannot be a .rel.dyn section. */ 946441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 947441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return false; 948441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 949441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the section name. Unfortunately necessary. */ 950441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (strcmp (section_name (ebl, ehdr, idx), rela ? ".rela.dyn" : ".rel.dyn")) 951441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return false; 952441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 953441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section 954441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project entry can be present as well. */ 955441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = NULL; 956441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 957441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 958441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr rcshdr_mem; 959441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem); 960441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (rcshdr != NULL); 961441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 962441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (rcshdr->sh_type == SHT_DYNAMIC) 963441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 964441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Found the dynamic section. Look through it. */ 965441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *d = elf_getdata (scn, NULL); 966441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int cnt; 967441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 968441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt) 969441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 970441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Dyn dyn_mem; 971441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem); 972441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (dyn != NULL); 973441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 974441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn->d_tag == DT_RELCOUNT) 975441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 976441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Found it. One last check: does the number 977441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project specified number of relative relocations exceed 978441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project the total number of relocations? */ 979441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 980441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 981441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 982441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 983441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) dyn->d_un.d_val); 984441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 985441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 986441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 987441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 988441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 989441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 990441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 991441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return true; 992441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 993441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 994441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 995441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 996441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_rela (Ebl *ebl, GElf_Ehdr *ehdr, int idx) 997441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 998441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn; 999441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1000441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 1001441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data; 1002441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr destshdr_mem; 1003441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *destshdr = NULL; 1004441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1005441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool reldyn = false; 1006441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool known_broken = gnuld; 1007441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1008441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn = elf_getscn (ebl->elf, idx); 1009441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (scn, &shdr_mem); 1010441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL) 1011441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1012441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data = elf_getdata (scn, NULL); 1013441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1014441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1015441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1016441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1017441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1018441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1019441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1020441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check whether the link to the section we relocate is reasonable. */ 1021441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info >= shnum) 1022441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), 1023441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1024441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1025441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1026441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1027441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &destshdr_mem); 1028441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (destshdr != NULL) 1029441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1030441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if(destshdr->sh_type != SHT_PROGBITS 1031441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && destshdr->sh_type != SHT_NOBITS) 1032441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1033441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); 1034441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!reldyn) 1035441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1036441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': invalid destination section type\n"), 1037441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1038441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1039441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1040441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* There is no standard, but we require that .rela.dyn 1041441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sections have a sh_info value of zero. */ 1042441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info != 0) 1043441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1044441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': sh_info should be zero\n"), 1045441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1046441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1047441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1048441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1049441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((destshdr->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) 1050441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1051441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': no relocations for merge-able sections possible\n"), 1052441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1053441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1054441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1055441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1056441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT)) 1057441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1058441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section entry size does not match ElfXX_Rela\n"), 1059441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1060441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1061441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1062441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr symshdr_mem; 1063441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1064441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *symdata = elf_getdata (symscn, NULL); 1065441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1066441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1067441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1068441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Rela rela_mem; 1069441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Rela *rela; 1070441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1071441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project rela = gelf_getrela (data, cnt, &rela_mem); 1072441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (rela == NULL) 1073441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1074441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1075441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': cannot get relocation %zu: %s\n"), 1076441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, elf_errmsg (-1)); 1077441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 1078441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1079441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1080441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (rela->r_info))) 1081441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), 1082441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1083441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (rela->r_info))) 1084441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1085441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), 1086441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1087441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1088441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr != NULL 1089441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ((GELF_R_SYM (rela->r_info) + 1) 1090441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) 1091441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project > symshdr->sh_size)) 1092441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1093441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': relocation %zu: invalid symbol index\n"), 1094441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1095441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1096441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (rela->r_info))) 1097441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1098441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *name; 1099441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[64]; 1100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym sym_mem; 1101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rela->r_info), 1102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &sym_mem); 1103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym != NULL 1104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the name for the symbol. */ 1105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) 1106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) 1107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), 1109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 1110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_reloc_type_name (ebl, GELF_R_SYM (rela->r_info), 1111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf))); 1112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (reldyn) 1115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // XXX TODO Check .rel.dyn section addresses. 1117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (!known_broken) 1119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (destshdr != NULL 1121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (rela->r_offset - destshdr->sh_addr) >= destshdr->sh_size) 1122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': relocation %zu: offset out of bounds\n"), 1124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_rel (Ebl *ebl, GElf_Ehdr *ehdr, int idx) 1132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn; 1134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 1136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data; 1137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr destshdr_mem; 1138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *destshdr = NULL; 1139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool reldyn = false; 1141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool known_broken = gnuld; 1142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn = elf_getscn (ebl->elf, idx); 1144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (scn, &shdr_mem); 1145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL) 1146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data = elf_getdata (scn, NULL); 1148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check whether the link to the section we relocate is reasonable. */ 1156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info >= shnum) 1157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), 1158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &destshdr_mem); 1163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (destshdr != NULL) 1164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (destshdr->sh_type != SHT_PROGBITS 1166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && destshdr->sh_type != SHT_NOBITS) 1167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, false); 1169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!reldyn) 1170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': invalid destination section type\n"), 1172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* There is no standard, but we require that .rela.dyn 1176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sections have a sh_info value of zero. */ 1177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info != 0) 1178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': sh_info should be zero\n"), 1180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((destshdr->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) 1185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': no relocations for merge-able sections possible\n"), 1187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT)) 1192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section entry size does not match ElfXX_Rel\n"), 1194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr symshdr_mem; 1198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *symdata = elf_getdata (symscn, NULL); 1200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Rel rel_mem; 1204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Rel *rel; 1205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project rel = gelf_getrel (data, cnt, &rel_mem); 1207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (rel == NULL) 1208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1209441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1210441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': cannot get relocation %zu: %s\n"), 1211441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, elf_errmsg (-1)); 1212441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 1213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1214441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))) 1216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), 1217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1218441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (!ebl_reloc_valid_use (ebl, GELF_R_TYPE (rel->r_info))) 1219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), 1221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr != NULL 1224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ((GELF_R_SYM (rel->r_info) + 1) 1225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) 1226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project > symshdr->sh_size)) 1227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': relocation %zu: invalid symbol index\n"), 1229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (rel->r_info))) 1232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *name; 1234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[64]; 1235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym sym_mem; 1236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (rel->r_info), 1237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &sym_mem); 1238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym != NULL 1239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Get the name for the symbol. */ 1240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) 1241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) 1242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), 1244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 1245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_reloc_type_name (ebl, GELF_R_SYM (rel->r_info), 1246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf))); 1247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (reldyn) 1250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // XXX TODO Check .rel.dyn section addresses. 1252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (!known_broken) 1254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (destshdr != NULL 1256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && GELF_R_TYPE (rel->r_info) != 0 1257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (rel->r_offset - destshdr->sh_addr) >= destshdr->sh_size) 1258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': relocation %zu: offset out of bounds\n"), 1260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Number of dynamic sections. */ 1267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int ndynamic; 1268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, int idx) 1272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1273441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn; 1274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 1276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data; 1277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr strshdr_mem; 1278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *strshdr; 1279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static const bool dependencies[DT_NUM][DT_NUM] = 1281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_NEEDED] = { [DT_STRTAB] = true }, 1283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_PLTRELSZ] = { [DT_JMPREL] = true }, 1284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_HASH] = { [DT_SYMTAB] = true }, 1285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_STRTAB] = { [DT_STRSZ] = true }, 1286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_HASH] = true, 1287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_SYMENT] = true }, 1288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true }, 1289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_RELASZ] = { [DT_RELA] = true }, 1290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_RELAENT] = { [DT_RELA] = true }, 1291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_STRSZ] = { [DT_STRTAB] = true }, 1292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_SYMENT] = { [DT_SYMTAB] = true }, 1293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_SONAME] = { [DT_STRTAB] = true }, 1294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_RPATH] = { [DT_STRTAB] = true }, 1295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true }, 1296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_RELSZ] = { [DT_REL] = true }, 1297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_RELENT] = { [DT_REL] = true }, 1298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true }, 1299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_RUNPATH] = { [DT_STRTAB] = true }, 1300441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_PLTREL] = { [DT_JMPREL] = true }, 1301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_PLTRELSZ] = { [DT_JMPREL] = true } 1302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool has_dt[DT_NUM]; 1304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static const bool level2[DT_NUM] = 1305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_RPATH] = true, 1307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_SYMBOLIC] = true, 1308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_TEXTREL] = true, 1309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_BIND_NOW] = true 1310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static const bool mandatory[DT_NUM] = 1312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_NULL] = true, 1314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_HASH] = true, 1315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_STRTAB] = true, 1316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_SYMTAB] = true, 1317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_STRSZ] = true, 1318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project [DT_SYMENT] = true 1319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Addr reladdr = 0; 1321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Word relsz = 0; 1322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Addr pltreladdr = 0; 1323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Word pltrelsz = 0; 1324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project memset (has_dt, '\0', sizeof (has_dt)); 1326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (++ndynamic == 2) 1328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("more than one dynamic section present\n")); 1329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn = elf_getscn (ebl->elf, idx); 1331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (scn, &shdr_mem); 1332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL) 1333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data = elf_getdata (scn, NULL); 1335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem); 1343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB) 1344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1345441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 1346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_link, section_name (ebl, ehdr, shdr->sh_link), 1347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT)) 1350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section entry size does not match ElfXX_Dyn\n"), 1352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info != 0) 1355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool non_null_warned = false; 1359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Dyn dyn_mem; 1362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Dyn *dyn; 1363441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1364441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dyn = gelf_getdyn (data, cnt, &dyn_mem); 1365441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn == NULL) 1366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1368441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': cannot get dynamic section entry %zu: %s\n"), 1369441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, elf_errmsg (-1)); 1370441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 1371441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1372441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1373441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned) 1374441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"), 1377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project non_null_warned = true; 1379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!ebl_dynamic_tag_check (ebl, dyn->d_tag)) 1382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"), 1383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn->d_tag < DT_NUM) 1386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (has_dt[dyn->d_tag] 1388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && dyn->d_tag != DT_NEEDED 1389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && dyn->d_tag != DT_NULL 1390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && dyn->d_tag != DT_POSFLAG_1) 1391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[50]; 1393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': entry %zu: more than one entry with tag %s\n"), 1395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 1396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_dynamic_tag_name (ebl, dyn->d_tag, 1397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf))); 1398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (be_strict && level2[dyn->d_tag]) 1401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[50]; 1403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': entry %zu: level 2 tag %s used\n"), 1405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt, 1406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_dynamic_tag_name (ebl, dyn->d_tag, 1407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project buf, sizeof (buf))); 1408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project has_dt[dyn->d_tag] = true; 1411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL 1414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && dyn->d_un.d_val != DT_RELA) 1415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"), 1417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt); 1418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn->d_tag == DT_REL) 1420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project reladdr = dyn->d_un.d_ptr; 1421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn->d_tag == DT_RELSZ) 1422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project relsz = dyn->d_un.d_val; 1423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn->d_tag == DT_JMPREL) 1424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project pltreladdr = dyn->d_un.d_ptr; 1425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dyn->d_tag == DT_PLTRELSZ) 1426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project pltrelsz = dyn->d_un.d_val; 1427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1429441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 1; cnt < DT_NUM; ++cnt) 1430441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (has_dt[cnt]) 1431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1432441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int inner; 1433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1434441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (inner = 0; inner < DT_NUM; ++inner) 1435441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (dependencies[cnt][inner] && ! has_dt[inner]) 1436441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1437441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf1[50]; 1438441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf2[50]; 1439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1441441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': contains %s entry but not %s\n"), 1442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 1443441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)), 1444441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2))); 1445441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1446441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1447441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1448441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1449441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (mandatory[cnt]) 1450441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1451441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char buf[50]; 1452441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1453441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': mandatory tag %s not present\n"), 1454441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 1455441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf))); 1456441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1457441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1458441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1459441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the rel/rela tags. At least one group must be available. */ 1460441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT]) 1461441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT])) 1462441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1463441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1464441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 1465441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "DT_RELA", "DT_RELASZ", "DT_RELAENT"); 1466441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1467441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT]) 1468441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT])) 1469441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1470441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1471441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 1472441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project "DT_REL", "DT_RELSZ", "DT_RELENT"); 1473441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1474441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1475441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1476441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1477441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, int idx) 1478441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1479441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn; 1480441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1481441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 1482441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr symshdr_mem; 1483441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *symshdr; 1484441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *symscn; 1485441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1486441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data; 1487441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *symdata; 1488441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1489441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn = elf_getscn (ebl->elf, idx); 1490441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (scn, &shdr_mem); 1491441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL) 1492441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1493441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1494441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project symscn = elf_getscn (ebl->elf, shdr->sh_link); 1495441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project symshdr = gelf_getshdr (symscn, &symshdr_mem); 1496441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB) 1497441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1498441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': extended section index section not for symbol table\n"), 1499441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1500441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project symdata = elf_getdata (symscn, NULL); 1501441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symdata == NULL) 1502441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("cannot get data for symbol section\n")); 1503441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1504441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != sizeof (Elf32_Word)) 1505441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1506441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': entry size does not match Elf32_Word\n"), 1507441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1508441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1509441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr != NULL 1510441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (shdr->sh_size / shdr->sh_entsize 1511441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project < symshdr->sh_size / symshdr->sh_entsize)) 1512441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1513441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': extended index table too small for symbol table\n"), 1514441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1515441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1516441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info != 0) 1517441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1518441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1519441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1520441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = idx + 1; cnt < shnum; ++cnt) 1521441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1522441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr rshdr_mem; 1523441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *rshdr; 1524441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1525441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem); 1526441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX 1527441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && rshdr->sh_link == shdr->sh_link) 1528441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1529441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1530441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"), 1531441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 1532441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 1533441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 1534441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1535441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1536441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1537441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data = elf_getdata (scn, NULL); 1538441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1539441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (*((Elf32_Word *) data->d_buf) != 0) 1540441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("symbol 0 should have zero extended section index\n")); 1541441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1542441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1543441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1544441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt]; 1545441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1546441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (xndx != 0) 1547441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1548441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym sym_data; 1549441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data); 1550441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym == NULL) 1551441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1552441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("cannot get data for symbol %zu\n"), cnt); 1553441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 1554441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1555441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1556441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (sym->st_shndx != SHN_XINDEX) 1557441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1558441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectextended section index is %" PRIu32 " but symbol index is not XINDEX\n"), 1559441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (uint32_t) xndx); 1560441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1561441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1562441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1563441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1564441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1565441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_hash (Ebl *ebl, GElf_Ehdr *ehdr, int idx) 1567441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1568441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn; 1569441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1570441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 1571441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data; 1572441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word nbucket; 1573441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word nchain; 1574441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr symshdr_mem; 1575441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *symshdr; 1576441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1577441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn = elf_getscn (ebl->elf, idx); 1578441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (scn, &shdr_mem); 1579441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL) 1580441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1581441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project data = elf_getdata (scn, NULL); 1582441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1583441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1584441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1585441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1586441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1587441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1588441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1589441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &symshdr_mem); 1590441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM) 1591441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1592441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': hash table not for dynamic symbol table\n"), 1593441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1594441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1595441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != sizeof (Elf32_Word)) 1596441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1597441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': entry size does not match Elf32_Word\n"), 1598441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1599441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1600441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((shdr->sh_flags & SHF_ALLOC) == 0) 1601441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"), 1602441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1603441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1604441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_size < 2 * shdr->sh_entsize) 1605441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1606441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1607441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': hash table has not even room for nbucket and nchain\n"), 1608441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1609441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1610441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1611441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1612441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nbucket = ((Elf32_Word *) data->d_buf)[0]; 1613441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project nchain = ((Elf32_Word *) data->d_buf)[1]; 1614441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1615441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 1616441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1617441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 1618441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), (long int) shdr->sh_size, 1619441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 1620441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1621441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr != NULL) 1622441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1623441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 1624441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1625441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1626441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (nchain < symshdr->sh_size / symshdr->sh_entsize) 1627441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': chain array not large enough\n"), 1628441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1629441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1630441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 2; cnt < 2 + nbucket; ++cnt) 1631441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (((Elf32_Word *) data->d_buf)[cnt] >= symsize) 1632441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1633441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': hash bucket reference %zu out of bounds\n"), 1634441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt - 2); 1635441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1636441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (; cnt < 2 + nbucket + nchain; ++cnt) 1637441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (((Elf32_Word *) data->d_buf)[cnt] >= symsize) 1638441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1639441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': hash chain reference %zu out of bounds\n"), 1640441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt - 2 - nbucket); 1641441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1642441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1643441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1644441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1645441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1646441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_null (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1647441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1648441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define TEST(name, extra) \ 1649441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (extra && shdr->sh_##name != 0) \ 1650441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"), \ 1651441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), #name) 1652441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1653441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (name, 1); 1654441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (flags, 1); 1655441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (addr, 1); 1656441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (offset, 1); 1657441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (size, idx != 0); 1658441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (link, idx != 0); 1659441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (info, 1); 1660441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (addralign, 1); 1661441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project TEST (entsize, 1); 1662441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1663441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1664441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1665441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1666441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1667441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1668441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type != ET_REL) 1669441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1670441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1671441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section groups only allowed in relocatable object files\n"), 1672441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1673441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1674441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1675441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1676441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check that sh_link is an index of a symbol table. */ 1677441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr symshdr_mem; 1678441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 1679441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &symshdr_mem); 1680441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr == NULL) 1681441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"), 1682441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), elf_errmsg (-1)); 1683441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1684441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1685441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr->sh_type != SHT_SYMTAB) 1686441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1687441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section reference in sh_link is no symbol table\n"), 1688441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1689441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1690441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM, 1691441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1, EV_CURRENT)) 1692441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1693441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': invalid symbol index in sh_info\n"), 1694441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1695441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1696441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags != 0) 1697441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"), 1698441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1699441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1700441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (be_strict 1701441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT)) 1702441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"), 1703441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1704441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1705441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1706441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1707441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data == NULL) 1708441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"), 1709441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), elf_errmsg (-1)); 1710441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1711441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1712441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT); 1713441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1714441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf32_Word val; 1715441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1716441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data->d_size % elsize != 0) 1717441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1718441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"), 1719441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1720441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1721441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data->d_size < elsize) 1722441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1723441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section group without flags word\n"), 1724441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1725441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (be_strict) 1726441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1727441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (data->d_size < 2 * elsize) 1728441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1729441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section group without member\n"), 1730441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1731441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (data->d_size < 3 * elsize) 1732441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section group with only one member\n"), 1734441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1735441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1736441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1737441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#if ALLOW_UNALIGNED 1738441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project val = *((Elf32_Word *) data->d_buf); 1739441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#else 1740441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project memcpy (&val, data->d_buf, elsize); 1741441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif 1742441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((val & ~GRP_COMDAT) != 0) 1743441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"), 1744441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx)); 1745441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1746441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = elsize; cnt < data->d_size; cnt += elsize) 1747441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1748441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#if ALLOW_UNALIGNED 1749441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project val = *((Elf32_Word *) ((char *) data->d_buf + cnt)); 1750441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#else 1751441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project memcpy (&val, (char *) data->d_buf + cnt, elsize); 1752441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif 1753441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1754441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (val > shnum) 1755441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1756441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section index %Zu out of range\n"), 1757441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt / elsize); 1758441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1759441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1760441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr refshdr_mem; 1761441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *refshdr; 1762441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1763441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project refshdr = gelf_getshdr (elf_getscn (ebl->elf, val), 1764441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &refshdr_mem); 1765441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (refshdr == NULL) 1766441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1767441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': cannot get section header for element %zu: %s\n"), 1768441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt / elsize, 1769441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_errmsg (-1)); 1770441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1771441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1772441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (refshdr->sh_type == SHT_GROUP) 1773441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1774441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': section group contains another group [%2d] '%s'\n"), 1775441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 1776441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project val, section_name (ebl, ehdr, val)); 1777441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1778441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((refshdr->sh_flags & SHF_GROUP) == 0) 1779441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1780441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP flag set\n"), 1781441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), cnt / elsize, 1782441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project val, section_name (ebl, ehdr, val)); 1783441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1784441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1785441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (++scnref[val] == 2) 1786441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1787441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s' is contained in more than one section group\n"), 1788441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project val, section_name (ebl, ehdr, val)); 1789441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1790441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1791441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1792441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1793441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1794441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1795441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool has_loadable_segment; 1796441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic bool has_interp_segment; 1797441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1798441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const struct 1799441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1800441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *name; 1801441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t namelen; 1802441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Word type; 1803441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project enum { unused, exact, atleast } attrflag; 1804441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Word attr; 1805441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Word attr2; 1806441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} special_sections[] = 1807441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1808441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* See figure 4-14 in the gABI. */ 1809441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 1810441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".comment", 8, SHT_PROGBITS, exact, 0, 0 }, 1811441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 1812441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 1813441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".debug", 7, SHT_PROGBITS, exact, 0, 0 }, 1814441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE }, 1815441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 }, 1816441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 }, 1817441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 1818441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 1819441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info? 1820441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 }, 1821441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 1822441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 1823441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests? 1824441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".line", 6, SHT_PROGBITS, exact, 0, 0 }, 1825441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".note", 6, SHT_NOTE, exact, 0, 0 }, 1826441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests 1827441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 1828441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC }, // XXX more tests 1829441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests 1830441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".rodata", 8, SHT_PROGBITS, exact, SHF_ALLOC, 0 }, 1831441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".rodata1", 9, SHT_PROGBITS, exact, SHF_ALLOC, 0 }, 1832441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 }, 1833441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 1834441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 1835441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests 1836441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 1837441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 1838441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 1839441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 } 1840441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1841441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define nspecial_sections \ 1842441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (sizeof (special_sections) / sizeof (special_sections[0])) 1843441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1844441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1845441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char * 1846441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection_flags_string (GElf_Word flags, char *buf, size_t len) 1847441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1848441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project static const struct 1849441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1850441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Word flag; 1851441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *name; 1852441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } known_flags[] = 1853441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1854441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define NEWFLAG(name) { SHF_##name, #name } 1855441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (WRITE), 1856441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (ALLOC), 1857441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (EXECINSTR), 1858441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (MERGE), 1859441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (STRINGS), 1860441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (INFO_LINK), 1861441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (LINK_ORDER), 1862441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (OS_NONCONFORMING), 1863441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (GROUP), 1864441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project NEWFLAG (TLS) 1865441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project }; 1866441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#undef NEWFLAG 1867441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]); 1868441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1869441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char *cp = buf; 1870441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1871441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1872441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 0; cnt < nknown_flags; ++cnt) 1873441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (flags & known_flags[cnt].flag) 1874441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1875441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cp != buf && len > 1) 1876441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1877441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp++ = '|'; 1878441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project --len; 1879441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1880441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1881441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name)); 1882441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cp = mempcpy (cp, known_flags[cnt].name, ncopy); 1883441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project len -= ncopy; 1884441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1885441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project flags ^= known_flags[cnt].flag; 1886441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1887441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1888441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (flags != 0 || cp == buf) 1889441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags); 1890441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1891441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *cp = '\0'; 1892441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1893441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return buf; 1894441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1895441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1896441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1897441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1898441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_versym (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1899441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1900441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The number of elements in the version symbol table must be the 1901441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project same as the number of symbols. */ 1902441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr symshdr_mem; 1903441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 1904441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project &symshdr_mem); 1905441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr == NULL) 1906441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The error has already been reported. */ 1907441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1908441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1909441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (symshdr->sh_type != SHT_DYNSYM) 1910441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1911441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1912441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"), 1913441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 1914441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_link, section_name (ebl, ehdr, shdr->sh_link)); 1915441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1916441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1917441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1918441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_size / shdr->sh_entsize 1919441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project != symshdr->sh_size / symshdr->sh_entsize) 1920441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1921441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"), 1922441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx, section_name (ebl, ehdr, idx), 1923441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_link, section_name (ebl, ehdr, shdr->sh_link)); 1924441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1925441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // XXX TODO A lot more tests 1926441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // check value of the fields. local symbols must have zero entries. 1927441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // nonlocal symbols refer to valid version. Check that version index 1928441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // in bound. 1929441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 1930441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1931441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1932441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 1933441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_sections (Ebl *ebl, GElf_Ehdr *ehdr) 1934441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 1935441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr shdr_mem; 1936441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Shdr *shdr; 1937441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t cnt; 1938441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool dot_interp_section = false; 1939441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1940441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_shoff == 0) 1941441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* No section header. */ 1942441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 1943441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1944441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Allocate array to count references in section groups. */ 1945441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scnref = (int *) xcalloc (shnum, sizeof (int)); 1946441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1947441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the zeroth section first. It must not have any contents 1948441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project and the section header must contain nonzero value at most in the 1949441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_size and sh_link fields. */ 1950441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 1951441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL) 1952441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("cannot get section header of zeroth section\n")); 1953441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 1954441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1955441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_name != 0) 1956441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("zeroth section has nonzero name\n")); 1957441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_type != 0) 1958441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("zeroth section has nonzero type\n")); 1959441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags != 0) 1960441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("zeroth section has nonzero flags\n")); 1961441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_addr != 0) 1962441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("zeroth section has nonzero address\n")); 1963441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_offset != 0) 1964441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("zeroth section has nonzero offset\n")); 1965441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_info != 0) 1966441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("zeroth section has nonzero info field\n")); 1967441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_addralign != 0) 1968441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("zeroth section has nonzero align value\n")); 1969441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != 0) 1970441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("zeroth section has nonzero entry size value\n")); 1971441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1972441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_size != 0 && ehdr->e_shnum != 0) 1973441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1974441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectzeroth section has nonzero size value while ELF header has nonzero shnum value\n")); 1975441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1976441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX) 1977441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1978441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectzeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n")); 1979441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1980441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1981441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (cnt = 1; cnt < shnum; ++cnt) 1982441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1983441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn; 1984441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1985441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn = elf_getscn (ebl->elf, cnt); 1986441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr = gelf_getshdr (scn, &shdr_mem); 1987441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr == NULL) 1988441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 1989441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 1990441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcannot get section header for section [%2zu] '%s': %s\n"), 1991441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt), elf_errmsg (-1)); 1992441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 1993441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 1994441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1995441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 1996441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 1997441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (scnname == NULL) 1998441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2zu]: invalid name\n"), cnt); 1999441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2000441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2001441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check whether it is one of the special sections defined in 2002441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project the gABI. */ 2003441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t s; 2004441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (s = 0; s < nspecial_sections; ++s) 2005441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (strncmp (scnname, special_sections[s].name, 2006441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project special_sections[s].namelen) == 0) 2007441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2008441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char stbuf1[100]; 2009441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char stbuf2[100]; 2010441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char stbuf3[100]; 2011441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2012441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_type != special_sections[s].type) 2013441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2014441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2d] '%s' has wrong type: expected %s, is %s\n"), 2015441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) cnt, scnname, 2016441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_section_type_name (ebl, special_sections[s].type, 2017441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stbuf1, sizeof (stbuf1)), 2018441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_section_type_name (ebl, shdr->sh_type, 2019441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stbuf2, sizeof (stbuf2))); 2020441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2021441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (special_sections[s].attrflag == exact) 2022441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2023441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Except for the link order and group bit all the 2024441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project other bits should match exactly. */ 2025441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP)) 2026441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project != special_sections[s].attr) 2027441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2028441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' has wrong flags: expected %s, is %s\n"), 2029441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, scnname, 2030441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_flags_string (special_sections[s].attr, 2031441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stbuf1, sizeof (stbuf1)), 2032441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_flags_string (shdr->sh_flags 2033441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project & ~SHF_LINK_ORDER, 2034441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stbuf2, sizeof (stbuf2))); 2035441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2036441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (special_sections[s].attrflag == atleast) 2037441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2038441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((shdr->sh_flags & special_sections[s].attr) 2039441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project != special_sections[s].attr 2040441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP 2041441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project | special_sections[s].attr 2042441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project | special_sections[s].attr2)) 2043441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project != 0)) 2044441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2045441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"), 2046441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, scnname, 2047441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_flags_string (special_sections[s].attr, 2048441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stbuf1, sizeof (stbuf1)), 2049441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_flags_string (special_sections[s].attr2, 2050441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stbuf2, sizeof (stbuf2)), 2051441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project section_flags_string (shdr->sh_flags 2052441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project & ~(SHF_LINK_ORDER 2053441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project | SHF_GROUP), 2054441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project stbuf3, sizeof (stbuf3))); 2055441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2056441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2057441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (strcmp (scnname, ".interp") == 0) 2058441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2059441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dot_interp_section = true; 2060441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2061441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type == ET_REL) 2062441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2063441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' present in object file\n"), 2064441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, scnname); 2065441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2066441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((shdr->sh_flags & SHF_ALLOC) != 0 2067441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && !has_loadable_segment) 2068441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2069441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 2070441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, scnname); 2071441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if ((shdr->sh_flags & SHF_ALLOC) == 0 2072441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && has_loadable_segment) 2073441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2074441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 2075441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, scnname); 2076441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2077441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2078441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2079441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (strcmp (scnname, ".symtab_shndx") == 0 2080441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_type != ET_REL) 2081441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2082441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' is extension section index table in non-object file\n"), 2083441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, scnname); 2084441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2085441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* These sections must have the SHF_ALLOC flag set iff 2086441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project a loadable segment is available. 2087441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2088441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project .relxxx 2089441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project .strtab 2090441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project .symtab 2091441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project .symtab_shndx 2092441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2093441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Check that if there is a reference from the 2094441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project loaded section these sections also have the 2095441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ALLOC flag set. */ 2096441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#if 0 2097441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // XXX TODO 2098441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((shdr->sh_flags & SHF_ALLOC) != 0 2099441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && !has_loadable_segment) 2100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 2102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, scnname); 2103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if ((shdr->sh_flags & SHF_ALLOC) == 0 2104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && has_loadable_segment) 2105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 2107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, scnname); 2108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif 2109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize) 2116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': size not multiple of entry size\n"), 2118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 2119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL) 2121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("cannot get section header\n")); 2122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_type >= SHT_NUM 2124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_type != SHT_GNU_LIBLIST 2125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_type != SHT_CHECKSUM 2126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_type != SHT_GNU_verdef 2127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_type != SHT_GNU_verneed 2128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && shdr->sh_type != SHT_GNU_versym) 2129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("unsupported section type %d\n"), (int) shdr->sh_type); 2130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ 2132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ 2133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) 2134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & ~ALL_SH_FLAGS) 2135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("section [%2zu] '%s' contain unknown flag(s) %d\n"), 2136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt), 2137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (int) shdr->sh_flags & ~ALL_SH_FLAGS); 2138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (shdr->sh_flags & SHF_TLS) 2139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // XXX Correct? 2141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_addr != 0 && !gnuld) 2142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': thread-local data sections address not zero\n"), 2144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 2145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project // XXX TODO more tests!? 2147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_link >= shnum) 2150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': invalid section reference in link value\n"), 2152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 2153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum) 2155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': invalid section reference in info value\n"), 2157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 2158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((shdr->sh_flags & SHF_MERGE) == 0 2160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (shdr->sh_flags & SHF_STRINGS) != 0 2161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && be_strict) 2162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': strings flag set without merge flag\n"), 2164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 2165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0) 2167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': merge flag set but entry size is zero\n"), 2169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 2170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_flags & SHF_GROUP) 2172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_scn_group (ebl, ehdr, cnt); 2173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0) 2175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Make sure the section is contained in a loaded segment 2177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project and that the initialization part matches NOBITS sections. */ 2178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int pcnt; 2179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr phdr_mem; 2180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr *phdr; 2181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 2183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL 2184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ((phdr->p_type == PT_LOAD 2185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (shdr->sh_flags & SHF_TLS) == 0) 2186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || (phdr->p_type == PT_TLS 2187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (shdr->sh_flags & SHF_TLS) != 0)) 2188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && phdr->p_offset <= shdr->sh_offset 2189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && phdr->p_offset + phdr->p_memsz > shdr->sh_offset) 2190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Found the segment. */ 2192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr->p_offset + phdr->p_memsz 2193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project < shdr->sh_offset + shdr->sh_size) 2194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' not fully contained in segment of program header entry %d\n"), 2196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt), pcnt); 2197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_type == SHT_NOBITS) 2199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz) 2201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"), 2203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt), pcnt); 2204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_offset >= phdr->p_offset + phdr->p_filesz) 2208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2209441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"), 2210441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt), pcnt); 2211441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2212441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2214441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (pcnt == ehdr->e_phnum) 2217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2218441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': alloc flag set but section not in any loaded segment\n"), 2219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 2220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB) 2223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectsection [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"), 2225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, section_name (ebl, ehdr, cnt)); 2226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (shdr->sh_type) 2228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_SYMTAB: 2230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_DYNSYM: 2231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_symtab (ebl, ehdr, cnt); 2232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_RELA: 2235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_rela (ebl, ehdr, cnt); 2236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_REL: 2239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_rel (ebl, ehdr, cnt); 2240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_DYNAMIC: 2243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_dynamic (ebl, ehdr, cnt); 2244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_SYMTAB_SHNDX: 2247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_symtab_shndx (ebl, ehdr, cnt); 2248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_HASH: 2251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_hash (ebl, ehdr, cnt); 2252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_NULL: 2255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_null (ebl, ehdr, shdr, cnt); 2256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_GROUP: 2259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_group (ebl, ehdr, shdr, cnt); 2260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_GNU_versym: 2263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_versym (ebl, ehdr, shdr, cnt); 2264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 2267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Nothing. */ 2268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (has_interp_segment && !dot_interp_section) 2273441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("INTERP program header entry but no .interp section\n")); 2274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project free (scnref); 2276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 2280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt) 2281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL 2283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 2284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectphdr[%d]: no note entries defined for the type of file\n"), 2286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt); 2287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project char *notemem = gelf_rawchunk (ebl->elf, phdr->p_offset, phdr->p_filesz); 2289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* ELF64 files often use note section entries in the 32-bit format. 2291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project The p_align field is set to 8 in case the 64-bit format is used. 2292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project In case the p_align value is 0 or 4 the 32-bit format is 2293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project used. */ 2294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Xword align = phdr->p_align == 0 || phdr->p_align == 4 ? 4 : 8; 2295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1)) 2296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Xword idx = 0; 2298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (idx < phdr->p_filesz) 2299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2300441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint64_t namesz; 2301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint64_t descsz; 2302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint64_t type; 2303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint32_t namesz32; 2304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint32_t descsz32; 2305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (align == 4) 2307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint32_t *ptr = (uint32_t *) (notemem + idx); 2309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((__BYTE_ORDER == __LITTLE_ENDIAN 2311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 2312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || (__BYTE_ORDER == __BIG_ENDIAN 2313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 2314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project namesz32 = namesz = bswap_32 (*ptr); 2316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++ptr; 2317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project descsz32 = descsz = bswap_32 (*ptr); 2318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++ptr; 2319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project type = bswap_32 (*ptr); 2320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project namesz32 = namesz = *ptr++; 2324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project descsz32 = descsz = *ptr++; 2325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project type = *ptr; 2326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint64_t *ptr = (uint64_t *) (notemem + idx); 2331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project uint32_t *ptr32 = (uint32_t *) (notemem + idx); 2332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((__BYTE_ORDER == __LITTLE_ENDIAN 2334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 2335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || (__BYTE_ORDER == __BIG_ENDIAN 2336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 2337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project namesz = bswap_64 (*ptr); 2339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++ptr; 2340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project descsz = bswap_64 (*ptr); 2341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++ptr; 2342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project type = bswap_64 (*ptr); 2343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project namesz32 = bswap_32 (*ptr32); 2345441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ++ptr32; 2346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project descsz32 = bswap_32 (*ptr32); 2347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project namesz = *ptr++; 2351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project descsz = *ptr++; 2352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project type = *ptr; 2353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project namesz32 = *ptr32++; 2355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project descsz32 = *ptr32; 2356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (idx + 3 * align > phdr->p_filesz 2360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || (idx + 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz) 2361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project > phdr->p_filesz)) 2362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2363441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_ident[EI_CLASS] == ELFCLASS64 2364441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && idx + 3 * 4 <= phdr->p_filesz 2365441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (idx + 3 * 4 + ALIGNED_LEN (namesz32) + ALIGNED_LEN (descsz32) 2366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project <= phdr->p_filesz)) 2367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2368441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectphdr[%d]: note entries probably in form of a 32-bit ELF file\n"), cnt); 2369441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2370441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("phdr[%d]: extra %zu bytes after last note\n"), 2371441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, (size_t) (phdr->p_filesz - idx)); 2372441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2373441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2374441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Make sure it is one of the note types we know about. */ 2376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type == ET_CORE) 2377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (type) 2379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_PRSTATUS: 2381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_FPREGSET: 2382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_PRPSINFO: 2383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_TASKSTRUCT: /* NT_PRXREG on Solaris. */ 2384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_PLATFORM: 2385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_AUXV: 2386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_GWINDOWS: 2387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_ASRS: 2388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_PSTATUS: 2389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_PSINFO: 2390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_PRCRED: 2391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_UTSNAME: 2392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_LWPSTATUS: 2393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_LWPSINFO: 2394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case NT_PRFPXREG: 2395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Known type. */ 2396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 2399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectphdr[%d]: unknown core file note type %" PRIu64 " at offset %" PRIu64 "\n"), 2401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, type, idx); 2402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (type != NT_VERSION) 2407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectphdr[%d]: unknown object file note type %" PRIu64 " at offset %" PRIu64 "\n"), 2409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, type, idx); 2410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Move to the next entry. */ 2413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project idx += 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz); 2414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project gelf_freechunk (ebl->elf, notemem); 2418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 2422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcheck_program_header (Ebl *ebl, GElf_Ehdr *ehdr) 2423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_phoff == 0) 2425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 2428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_type != ET_CORE) 2429441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2430441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectonly executables, shared objects, and core files can have program headers\n")); 2431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2432441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int num_pt_interp = 0; 2433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int num_pt_tls = 0; 2434441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int num_pt_relro = 0; 2435441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2436441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (int cnt = 0; cnt < ehdr->e_phnum; ++cnt) 2437441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2438441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr phdr_mem; 2439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr *phdr; 2440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2441441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 2442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr == NULL) 2443441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2444441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("cannot get program header entry %d: %s\n"), 2445441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt, elf_errmsg (-1)); 2446441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 2447441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2448441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2449441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME 2450441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && phdr->p_type != PT_GNU_STACK) 2451441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2452441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprogram header entry %d: unknown program header entry type\n"), 2453441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt); 2454441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2455441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr->p_type == PT_LOAD) 2456441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project has_loadable_segment = true; 2457441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (phdr->p_type == PT_INTERP) 2458441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2459441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (++num_pt_interp != 1) 2460441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2461441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (num_pt_interp == 2) 2462441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2463441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmore than one INTERP entry in program header\n")); 2464441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2465441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project has_interp_segment = true; 2466441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2467441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (phdr->p_type == PT_TLS) 2468441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2469441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (++num_pt_tls == 2) 2470441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("more than one TLS entry in program header\n")); 2471441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2472441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (phdr->p_type == PT_NOTE) 2473441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_note (ebl, ehdr, phdr, cnt); 2474441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (phdr->p_type == PT_DYNAMIC 2475441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_type == ET_EXEC && ! has_interp_segment) 2476441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("static executable cannot have dynamic sections\n")); 2477441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (phdr->p_type == PT_GNU_RELRO) 2478441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2479441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (++num_pt_relro == 2) 2480441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2481441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmore than one GNU_RELRO entry in program header\n")); 2482441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2483441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2484441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check that the region is in a writable segment. */ 2485441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int inner; 2486441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project for (inner = 0; inner < ehdr->e_phnum; ++inner) 2487441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2488441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr phdr2_mem; 2489441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Phdr *phdr2; 2490441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2491441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project phdr2 = gelf_getphdr (ebl->elf, cnt, &phdr2_mem); 2492441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr2 == NULL) 2493441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project continue; 2494441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2495441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr2->p_type == PT_LOAD 2496441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && phdr->p_vaddr >= phdr2->p_vaddr 2497441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (phdr->p_vaddr + phdr->p_memsz 2498441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project <= phdr2->p_vaddr + phdr2->p_memsz)) 2499441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2500441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((phdr2->p_flags & PF_W) == 0) 2501441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2502441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectloadable segment GNU_RELRO applies to is not writable\n")); 2503441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if ((phdr2->p_flags & PF_X) != 0) 2504441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2505441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectloadable segment GNU_RELRO applies to is executable\n")); 2506441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 2507441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2508441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2509441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2510441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (inner >= ehdr->e_phnum) 2511441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2512441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectGNU_RELRO segment not contained in a loaded segment\n")); 2513441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2514441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2515441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2516441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr->p_filesz > phdr->p_memsz) 2517441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2518441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprogram header entry %d: file size greater than memory size\n"), 2519441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project cnt); 2520441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2521441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (phdr->p_align > 1) 2522441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2523441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!powerof2 (phdr->p_align)) 2524441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2525441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprogram header entry %d: alignment not a power of 2\n"), cnt); 2526441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0) 2527441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("\ 2528441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprogram header entry %d: file offset and virtual address not module of alignment\n"), cnt); 2529441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2530441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2531441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2532441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2533441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2534441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Process one file. */ 2535441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void 2536441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprocess_elf_file (Elf *elf, const char *prefix, const char *suffix, 2537441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project const char *fname, size_t size, bool only_one) 2538441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 2539441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Reset variables. */ 2540441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ndynamic = 0; 2541441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2542441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Ehdr ehdr_mem; 2543441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 2544441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Ebl *ebl; 2545441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2546441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Print the file name. */ 2547441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (!only_one) 2548441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2549441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (prefix != NULL) 2550441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("\n%s(%s)%s:\n", prefix, fname, suffix); 2551441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 2552441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project printf ("\n%s:\n", fname); 2553441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2554441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2555441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr == NULL) 2556441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 2557441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1)); 2558441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return; 2559441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 2560441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2561441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl = ebl_openbackend (elf); 2562441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* If there is no appropriate backend library we cannot test 2563441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project architecture and OS specific features. Any encountered extension 2564441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project is an error. */ 2565441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Go straight by the gABI, check all the parts in turn. */ 2567441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_elf_header (ebl, ehdr, size); 2568441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2569441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check the program header. */ 2570441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_program_header (ebl, ehdr); 2571441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2572441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Next the section headers. It is OK if there are no section 2573441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project headers at all. */ 2574441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project check_sections (ebl, ehdr); 2575441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 2576441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Free the resources. */ 2577441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ebl_closebackend (ebl); 2578441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 2579