elflint.c revision 607e05466d3fef5e3ad90aa200d3bba1950cf982
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Pedantic checking of ELF files compliance with gABI/psABI spec. 271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Written by Ulrich Drepper <drepper@redhat.com>, 2001. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper This program is Open Source software; you can redistribute it and/or 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard modify it under the terms of the Open Software License version 1.0 as 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard published by the Open Source Initiative. 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received a copy of the Open Software License along 10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper with this program; if not, you may obtain a copy of the Open Software 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard License version 1.0 from http://www.opensource.org/licenses/osl.php or 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 3001 King Ranch Road, Ukiah, CA 95482. */ 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard#ifdef HAVE_CONFIG_H 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard# include <config.h> 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard#endif 18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h> 20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <byteswap.h> 22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <endian.h> 23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h> 24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <gelf.h> 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <inttypes.h> 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h> 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <locale.h> 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/param.h> 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <elf-knowledge.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <system.h> 37b337b1fd5f3b3410fe522a690ccee70bce8519eeRoland McGrath#include "../libebl/libeblP.h" 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program. */ 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state); 42059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathvoid (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; 43059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address. */ 45059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathconst char *argp_program_bug_address = PACKAGE_BUGREPORT; 46059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 47059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath#define ARGP_strict 300 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ARGP_gnuld 301 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions. */ 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] = 52fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper{ 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "strict", ARGP_strict, NULL, 0, 55fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper N_("Be extremely strict, flag level 2 features."), 0 }, 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 }, 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 }, 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "gnu-ld", ARGP_gnuld, NULL, 0, 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Binary has been created with GNU ld and is therefore known to be \ 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperbroken in certain ways"), 0 }, 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, NULL, 0 } 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program. */ 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("\ 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperPedantic checking of ELF files compliance with gABI/psABI spec."); 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts. */ 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("FILE..."); 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler. */ 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions. */ 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp = 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper options, parse_opt, args_doc, doc, NULL, NULL, NULL 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Declarations of local functions. */ 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void process_file (int fd, Elf *elf, const char *prefix, 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *suffix, const char *fname, size_t size, 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool only_one); 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void process_elf_file (Elf *elf, const char *prefix, const char *suffix, 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one); 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Report an error. */ 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ERROR(str, args...) \ 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do { \ 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf (str, ##args); \ 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++error_count; \ 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } while (0) 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic unsigned int error_count; 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath/* True if we should perform very strict testing. */ 9759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathstatic bool be_strict; 9859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if no message is to be printed if the run is succesful. */ 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool be_quiet; 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if binary is from strip -f, not a normal ELF file. */ 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool is_debuginfo; 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if binary is assumed to be generated with GNU ld. */ 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool gnuld; 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Index of section header string table. */ 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic uint32_t shstrndx; 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Array to count references in section groups. */ 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int *scnref; 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[]) 117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set locale. */ 119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper setlocale (LC_ALL, ""); 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Initialize the message catalog. */ 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper textdomain (PACKAGE); 123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Parse and process arguments. */ 125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int remaining; 12671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek argp_parse (&argp, argc, argv, 0, &remaining, NULL); 12771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 12871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek /* Before we start tell the ELF library which version we are using. */ 12971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek elf_version (EV_CURRENT); 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now process all the files given at the command line. */ 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool only_one = remaining + 1 == argc; 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Open the file. */ 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fd = open (argv[remaining], O_RDONLY); 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fd == -1) 138b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper { 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("cannot open input file")); 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create an `Elf' descriptor. */ 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf == NULL) 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot generate Elf descriptor: %s\n"), 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int prev_error_count = error_count; 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct stat64 st; 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fstat64 (fd, &st) != 0) 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("cannot stat '%s': %m\n", argv[remaining]); 156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size, 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper only_one); 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now we can close the descriptor. */ 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (elf) != 0) 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("error while closing Elf descriptor: %s\n"), 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prev_error_count == error_count && !be_quiet) 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper puts (gettext ("No errors")); 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (++remaining < argc); 175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return error_count != 0; 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments. */ 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt (int key, char *arg __attribute__ ((unused)), 183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct argp_state *state __attribute__ ((unused))) 184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_strict: 188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper be_strict = true; 189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'q': 192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper be_quiet = true; 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'd': 196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is_debuginfo = true; 197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_gnuld: 199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gnuld = true; 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_KEY_NO_ARGS: 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fputs (gettext ("Missing file name.\n"), stderr); 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, 205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper program_invocation_short_name); 206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper exit (1); 207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information. */ 216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, VERSION); 2205ee720c60a298352b52513d03ede85814ab63ad5Ulrich Drepper fprintf (stream, gettext ("\ 2215ee720c60a298352b52513d03ede85814ab63ad5Ulrich DrepperCopyright (C) %s Red Hat, Inc.\n\ 222b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions. There is NO\n\ 223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper"), "2005"); 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Process one file. */ 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_file (int fd, Elf *elf, const char *prefix, const char *suffix, 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one) 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 234b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper /* We can handle two types of files: ELF files and archives. */ 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Kind kind = elf_kind (elf); 236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (kind) 238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2393a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper case ELF_K_ELF: 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Yes! It's an ELF file. */ 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_elf_file (elf, prefix, suffix, fname, size, only_one); 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_AR: 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *subelf; 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Cmd cmd = ELF_C_READ_MMAP; 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t fname_len = strlen (fname) + 1; 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_prefix[prefix_len + 1 + fname_len]; 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2]; 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = new_prefix; 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the full name of the file. */ 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, prefix, prefix_len); 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = '('; 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper strcpy (stpcpy (new_suffix, suffix), ")"); 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_suffix[0] = '\0'; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (cp, fname, fname_len); 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* It's an archive. We process each file in it. */ 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper kind = elf_kind (subelf); 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Call this function recursively. */ 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (kind == ELF_K_ELF || kind == ELF_K_AR) 272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Arhdr *arhdr = elf_getarhdr (subelf); 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (arhdr != NULL); 275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_file (fd, subelf, new_prefix, new_suffix, 277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arhdr->ar_name, arhdr->ar_size, false); 278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get next archive element. */ 281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cmd = elf_next (subelf); 282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (subelf) != 0) 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"), 284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We cannot do anything. */ 291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 292b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperNot an ELF file - it has the wrong magic bytes at the start\n")); 293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char * 299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_name (Ebl *ebl, int idx) 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr; 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem); 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 30741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper} 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const int valid_e_machine[] = 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370, 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC, 314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM, 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300, 316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE, 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16, 31871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7, 31971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX, 32071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM, 32171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300, 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 32471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek#define nvalid_e_machine \ 32571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 32771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 32871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek/* Number of sections. */ 32971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinekstatic unsigned int shnum; 33071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size) 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[512]; 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check e_ident field. */ 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG0] != ELFMAG0) 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0); 341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG1] != ELFMAG1) 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1); 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG2] != ELFMAG2) 344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2); 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG3] != ELFMAG3) 346257dcf47ed0cf57bcd2ad225cc7aaa6a8dfeb2abJeff Kenton ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3); 34798c8a7395b4e5e7bed233397148b15c1f8c66490Petr Machata 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_CLASS] != ELFCLASS32 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_CLASS] != ELFCLASS64) 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%d] == %d is no known class\n"), 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_CLASS, ehdr->e_ident[EI_CLASS]); 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] != ELFDATA2MSB) 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"), 356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_DATA, ehdr->e_ident[EI_DATA]); 357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"), 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_VERSION, ehdr->e_ident[EI_VERSION]); 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We currently don't handle any OS ABIs. */ 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE) 364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"), 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_OSABI, 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No ABI versions other than zero supported either. */ 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_ABIVERSION] != 0) 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unsupport ABI version e_ident[%d] == %d\n"), 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]); 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt) 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[cnt] != 0) 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt); 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_type field. */ 378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC 379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE) 380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type); 381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_machine field. */ 38396d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper for (cnt = 0; cnt < nvalid_e_machine; ++cnt) 38496d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper if (valid_e_machine[cnt] == ehdr->e_machine) 38596d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper break; 386e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (cnt == nvalid_e_machine) 387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine); 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_version field. */ 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_version != EV_CURRENT) 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown object file version\n")); 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_phoff and e_phnum fields. */ 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phoff == 0) 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phnum != 0) 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header offset\n")); 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperexecutables and DSOs cannot have zero program header offset\n")); 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_phnum == 0) 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid number of program header entries\n")); 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_shoff field. */ 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shnum = ehdr->e_shnum; 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shstrndx = ehdr->e_shstrndx; 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shoff == 0) 409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shnum != 0) 411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header table offset\n")); 412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_CORE) 414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section header table must be present\n")); 415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shnum == 0) 419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the header of the zeroth section. The sh_size field 421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might contain the section number. */ 422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr != NULL) 425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The error will be reported later. */ 427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size == 0) 428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperinvalid number of section header table entries\n")); 430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shnum = shdr->sh_size; 432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shstrndx == SHN_XINDEX) 436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the header of the zeroth section. The sh_size field 438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might contain the section number. */ 439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr != NULL && shdr->sh_link < shnum) 442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shstrndx = shdr->sh_link; 443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (shstrndx >= shnum) 445acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("invalid section header index\n")); 446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_flags field. */ 449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!ebl_machine_flag_check (ebl, ehdr->e_flags)) 450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid machine flags: %s\n"), 451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check e_ehsize, e_phentsize, and e_shentsize fields. */ 454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gelf_getclass (ebl->elf) == ELFCLASS32) 455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr)) 457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr)) 460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header size: %hd\n"), 461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_phentsize); 462acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size) 463acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("invalid program header position or size\n")); 464acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr)) 466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header size: %hd\n"), 467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_shentsize); 468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header position or size\n")); 470bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath } 471bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath else if (gelf_getclass (ebl->elf) == ELFCLASS64) 472bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath { 473bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr)) 474bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 475bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath 476bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr)) 477bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ERROR (gettext ("invalid program header size: %hd\n"), 478bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ehdr->e_phentsize); 479bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size) 480bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ERROR (gettext ("invalid program header position or size\n")); 481bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath 482bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr)) 483bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ERROR (gettext ("invalid section header size: %hd\n"), 484bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ehdr->e_shentsize); 485bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 486bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ERROR (gettext ("invalid section header position or size\n")); 487bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath } 488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check that there is a section group section with index < IDX which 492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper contains section IDX and that there is exactly one. */ 493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_scn_group (Ebl *ebl, int idx) 495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnref[idx] == 0) 497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No reference so far. Search following sections, maybe the 499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper order is wrong. */ 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 502bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (cnt = idx + 1; cnt < shnum; ++cnt) 503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = elf_getscn (ebl->elf, cnt); 505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 508bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath /* We cannot get the section header so we cannot check it. 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper The error to get the section header will be shown 510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper somewhere else. */ 511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type != SHT_GROUP) 514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL || data->d_size < sizeof (Elf32_Word)) 518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cannot check the section. */ 519bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath continue; 520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word *grpdata = (Elf32_Word *) data->d_buf; 522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word); 523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++inner) 524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (grpdata[inner] == (Elf32_Word) idx) 525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto out; 526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out: 529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == shnum) 530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"), 532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group [%2zu] '%s' does not preceed group member\n"), 536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 544acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper{ 545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool no_xndx_warned = false; 546acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper int no_pt_tls = 0; 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr strshdr_mem; 556acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 5570a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard &strshdr_mem); 5580a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (strshdr == NULL) 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 562acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 563acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link), 564acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Search for an extended section index table section. */ 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *xndxdata = NULL; 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndxscnidx = 0; 570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool found_xndx = false; 571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < shnum; ++cnt) 572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt != (size_t) idx) 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt); 575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr xndxshdr_mem; 5763b495d8e963eead963a37b5be5b063c96bb58c63Roland McGrath GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxshdr == NULL) 578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && xndxshdr->sh_link == (GElf_Word) idx) 582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (found_xndx) 584dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol table cannot have more than one extended index section\n"), 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 588dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper xndxdata = elf_getdata (xndxscn, NULL); 589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndxscnidx = elf_ndxscn (xndxscn); 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper found_xndx = true; 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)) 595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 596dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': entry size is does not match ElfXX_Sym\n"), 597dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 598dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 599dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Test the zeroth entry. */ 600dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Sym sym_mem; 601dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf32_Word xndx; 602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx); 603521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (sym == NULL) 604521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"), 605521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath idx, section_name (ebl, idx), 0, elf_errmsg (-1)); 606521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath else 607521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 608521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (sym->st_name != 0) 609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_name"); 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value != 0) 612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 613acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx), "st_value"); 6143cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper if (sym->st_size != 0) 615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_size"); 617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_info != 0) 618acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 619acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx), "st_info"); 620acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (sym->st_other != 0) 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_other"); 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != 0) 624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 625acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx), "st_shndx"); 626acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (xndxdata != NULL && xndx != 0) 627acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 628acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': XINDEX for zeroth entry not zero\n"), 629acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper xndxscnidx, section_name (ebl, xndxscnidx)); 630acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 631acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 632acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 633acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 634acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx); 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 63771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"), 63871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 6403cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper } 6413cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name = NULL; 643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_name >= strshdr->sh_size) 644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: invalid name value\n"), 646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name); 650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (name != NULL); 651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx == SHN_XINDEX) 654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxdata == NULL) 656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"), 659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper no_xndx_warned = true; 661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (xndx < SHN_LORESERVE) 663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"), 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndxscnidx, section_name (ebl, xndxscnidx), cnt, 666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndx); 667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((sym->st_shndx >= SHN_LORESERVE 669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // && sym->st_shndx <= SHN_HIRESERVE always true 670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym->st_shndx != SHN_ABS 671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym->st_shndx != SHN_COMMON) 672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (sym->st_shndx >= shnum 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (sym->st_shndx < SHN_LORESERVE 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* || sym->st_shndx > SHN_HIRESERVE always false */))) 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 67671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s': symbol %zu: invalid section index\n"), 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndx = sym->st_shndx; 680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_TYPE (sym->st_info) >= STT_NUM 682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0)) 683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"), 684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_BIND (sym->st_info) >= STB_NUM) 687521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath ERROR (gettext ("\ 688521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrathsection [%2d] '%s': symbol %zu: unknown symbol binding\n"), 689521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath idx, section_name (ebl, idx), cnt); 690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndx == SHN_COMMON) 692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Common symbols can only appear in relocatable files. */ 694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 6960a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"), 6970a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx), cnt); 698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt < shdr->sh_info) 699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"), 701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_R_TYPE (sym->st_info) == STT_FUNC) 703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 704fd992543185126eb0280c1ee0883e073020499b4Roland McGrathsection [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"), 705fd992543185126eb0280c1ee0883e073020499b4Roland McGrath idx, section_name (ebl, idx), cnt); 706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 707fd992543185126eb0280c1ee0883e073020499b4Roland McGrath else if (xndx > 0 && xndx < shnum) 708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr destshdr_mem; 710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *destshdr; 711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem); 713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (destshdr != NULL) 714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_TYPE (sym->st_info) != STT_TLS) 716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! ebl_check_special_symbol (ebl, ehdr, sym, name, 718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destshdr)) 719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((sym->st_value - destshdr->sh_addr) 721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > destshdr->sh_size) 722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds\n"), 724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((sym->st_value - destshdr->sh_addr 726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + sym->st_size) > destshdr->sh_size) 727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 72918e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath idx, section_name (ebl, idx), cnt, 73018e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath (int) xndx, section_name (ebl, xndx)); 731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 73496d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper { 73596d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper if ((destshdr->sh_flags & SHF_TLS) == 0) 73696d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper ERROR (gettext ("\ 737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"), 738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 74096d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper 74196d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper if (ehdr->e_type == ET_REL) 74296d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper { 74396d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper /* For object files the symbol value must fall 74496d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper into the section. */ 745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value > destshdr->sh_size) 746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (sym->st_value + sym->st_size 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > destshdr->sh_size) 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr = NULL; 761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int pcnt; 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr != NULL && phdr->p_type == PT_TLS) 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 770b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (pcnt == ehdr->e_phnum) 771b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 772c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard if (no_pt_tls++ == 0) 773c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard ERROR (gettext ("\ 774c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaardsection [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"), 775c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard idx, section_name (ebl, idx), cnt); 776c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard } 777c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard else 778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value 780c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper < destshdr->sh_offset - phdr->p_offset) 781c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 782c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Dreppersection [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"), 783c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard idx, section_name (ebl, idx), cnt, 784ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper (int) xndx, section_name (ebl, xndx)); 785ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper else if (sym->st_value 786ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper > (destshdr->sh_offset - phdr->p_offset 7873bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard + destshdr->sh_size)) 7883bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard ERROR (gettext ("\ 7893bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaardsection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 790ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper idx, section_name (ebl, idx), cnt, 7913bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard (int) xndx, section_name (ebl, xndx)); 7923bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard else if (sym->st_value + sym->st_size 7933bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard > (destshdr->sh_offset - phdr->p_offset 7943bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard + destshdr->sh_size)) 795ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper ERROR (gettext ("\ 796ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 797ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper idx, section_name (ebl, idx), cnt, 798ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper (int) xndx, section_name (ebl, xndx)); 799ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper } 8003bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard } 8013bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard } 802b94cceae503b56fb360cd597f154fa2b33552887Mark Wielaard } 803a95c4ad24cf83b2b0273fee73162bf476cebec8fMark Wielaard } 804a95c4ad24cf83b2b0273fee73162bf476cebec8fMark Wielaard 805ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 807ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper if (cnt >= shdr->sh_info) 808ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper ERROR (gettext ("\ 809c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaardsection [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"), 810c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), cnt); 811c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 813c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper { 814c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (cnt < shdr->sh_info) 815c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"), 817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_TYPE (sym->st_info) == STT_SECTION 821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local section symbol\n"), 824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (name != NULL) 827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 828c49d00afc4bda21181cd4237e67930f3f5228adfMark Wielaard if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 829c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard { 830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check that address and size match the global offset table. */ 831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr destshdr_mem; 833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), 834c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard &destshdr_mem); 835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (destshdr == NULL && xndx == SHN_ABS) 837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* In a DSO, we have to find the GOT section by name. */ 839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *gotscn = NULL; 840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *gscn = NULL; 841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL) 842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destshdr = gelf_getshdr (gscn, &destshdr_mem); 844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (destshdr != NULL); 845bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath const char *sname = elf_strptr (ebl->elf, 846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_shstrndx, 847bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath destshdr->sh_name); 848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sname != NULL) 849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (sname, ".got.plt") == 0) 851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (sname, ".got") == 0) 853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Do not stop looking. 854bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath There might be a .got.plt section. */ 855b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gotscn = gscn; 856b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 857b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 858b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destshdr = NULL; 859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 860b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 86177be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard if (destshdr == NULL && gotscn != NULL) 86277be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard destshdr = gelf_getshdr (gotscn, &destshdr_mem); 86377be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard } 86477be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard 86577be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard const char *sname = (destshdr == NULL ? NULL 86677be59bca4057b22af70b0b2d0197f9505577381Mark Wielaard : elf_strptr (ebl->elf, ehdr->e_shstrndx, 867b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destshdr->sh_name)); 868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sname == NULL) 869c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard ERROR (gettext ("\ 870b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section\n"), 871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (strcmp (sname, ".got.plt") != 0 873b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && strcmp (sname, ".got") != 0) 874b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 875c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaardsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to '%s' section\n"), 876b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), sname); 877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (destshdr != NULL) 879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found it. */ 881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!ebl_check_special_symbol (ebl, ehdr, sym, name, 882c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard destshdr)) 883b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value != destshdr->sh_addr) 885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This test is more strict than the psABIs which 886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper usually allow the symbol to be in the middle of 887b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the .got section, allowing negative offsets. */ 888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"), 890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (uint64_t) sym->st_value, 892b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sname, (uint64_t) destshdr->sh_addr); 893b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 894b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!gnuld && sym->st_size != destshdr->sh_size) 895b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 896b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"), 897b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (uint64_t) sym->st_size, 899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sname, (uint64_t) destshdr->sh_size); 900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"), 905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 906b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (strcmp (name, "_DYNAMIC") == 0) 908b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check that address and size match the dynamic section. 909b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper We locate the dynamic section via the program header 910b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper entry. */ 911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 912b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 913b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 914b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value != phdr->p_vaddr) 919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 920653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"), 921653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath idx, section_name (ebl, idx), 922653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath (uint64_t) sym->st_value, 923653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath (uint64_t) phdr->p_vaddr); 924653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 925653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (!gnuld && sym->st_size != phdr->p_memsz) 926653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ERROR (gettext ("\ 927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"), 928653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath idx, section_name (ebl, idx), 929653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath (uint64_t) sym->st_size, 930c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (uint64_t) phdr->p_memsz); 931653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 933653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath } 934653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath } 935653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath } 936653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath } 937653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath} 938653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 940c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepperstatic bool 941653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathis_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr, 942c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper bool rela) 943653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath{ 944653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* If this is no executable or DSO it cannot be a .rel.dyn section. */ 945653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 947653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 948653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* Check the section name. Unfortunately necessary. */ 949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (section_name (ebl, idx), rela ? ".rela.dyn" : ".rel.dyn")) 950653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath return false; 951653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 952653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section 953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper entry can be present as well. */ 954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 955b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 956b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 957653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Shdr rcshdr_mem; 958653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem); 959653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath assert (rcshdr != NULL); 960b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 961b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (rcshdr->sh_type == SHT_DYNAMIC) 962b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 963b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper /* Found the dynamic section. Look through it. */ 964b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper Elf_Data *d = elf_getdata (scn, NULL); 965b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper size_t cnt; 966b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 967653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt) 968653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath { 969653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Dyn dyn_mem; 970b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem); 971b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper assert (dyn != NULL); 972b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 973653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (dyn->d_tag == DT_RELCOUNT) 974653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath { 975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found it. One last check: does the number 976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper specified number of relative relocations exceed 977c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper the total number of relocations? */ 978c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 979c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 980b597dfad924980dede10d7c19d87900b6172e599Ulrich Dreppersection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 981b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper idx, section_name (ebl, idx), 982c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (int) dyn->d_un.d_val); 983c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 984c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 985c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper 986653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath break; 987c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 988c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 989c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper 990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 991c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper} 992c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper 993653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 994c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepperstruct loaded_segment 995c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper{ 996c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper GElf_Addr from; 997c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper GElf_Addr to; 998b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool read_only; 999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loaded_segment *next; 1000b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 1001b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1002b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1003b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check whether binary has text relocation flag set. */ 1004b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool textrel; 100541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 100641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper/* Keep track of whether text relocation flag is needed. */ 100741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool needed_textrel; 1008bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath 100941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 101041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool 101141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppercheck_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr, 1012b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int idx, int reltype, GElf_Shdr **destshdrp, 101341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp) 101441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper{ 101541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper bool reldyn = false; 101641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1017b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether the link to the section we relocate is reasonable. */ 101841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (shdr->sh_info >= shnum) 101941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), 102041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx)); 1021b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (shdr->sh_info != 0) 102241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 102341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1024b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destshdr_memp); 102541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (*destshdrp != NULL) 102641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 102741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if((*destshdrp)->sh_type != SHT_PROGBITS 1028b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (*destshdrp)->sh_type != SHT_NOBITS) 102941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 103041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); 1031b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!reldyn) 1032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1033c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Dreppersection [%2d] '%s': invalid destination section type\n"), 1034c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper idx, section_name (ebl, idx)); 1035c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper else 1036c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper { 1037c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper /* There is no standard, but we require that .rel{,a}.dyn 1038c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper sections have a sh_info value of zero. */ 1039a062b6bcadd1565d360acf640f9d4c159b2270eaMark Wielaard if (shdr->sh_info != 0) 1040c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper ERROR (gettext ("\ 1041c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Dreppersection [%2d] '%s': sh_info should be zero\n"), 1042c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper idx, section_name (ebl, idx)); 1043c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper } 1044b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1045b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1046b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) 1047b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1048b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': no relocations for merge-able sections possible\n"), 1049c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx)); 105028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 1051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1052b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1053b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT)) 1054b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext (reltype == ELF_T_RELA ? "\ 1055b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ 1056b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rel\n"), 105728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 1058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* In preparation of checking whether relocations are text 1060b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper relocations or not we need to determine whether the file is 1061b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper flagged to have text relocation and we need to determine a) what 1062b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the loaded segments are and b) which are read-only. This will 1063b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper also allow us to determine whether the same reloc section is 1064b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper modifying loaded and not loaded segments. */ 1065b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int i = 0; i < ehdr->e_phnum; ++i) 1066b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1067b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 106871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 106971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (phdr == NULL) 107071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek continue; 10710a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 1072b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_type == PT_LOAD) 1073b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1074b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct loaded_segment *newp = xmalloc (sizeof (*newp)); 1075b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->from = phdr->p_vaddr; 1076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->to = phdr->p_vaddr + phdr->p_memsz; 10770a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard newp->read_only = (phdr->p_flags & PF_W) == 0; 10780a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard newp->next = *loadedp; 10790a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard *loadedp = newp; 10800a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 10810a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard else if (phdr->p_type == PT_DYNAMIC) 1082b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1083b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset); 1084b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr dynshdr_mem; 1085b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem); 108671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Elf_Data *dyndata = elf_getdata (dynscn, NULL); 108771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC 108871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek && dyndata != NULL) 1089b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j) 1090b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1091b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn dyn_mem; 109228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem); 109328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn != NULL 1094b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (dyn->d_tag == DT_TEXTREL 109528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper || (dyn->d_tag == DT_FLAGS 109628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && (dyn->d_un.d_val & DF_TEXTREL) != 0))) 109728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 109828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper textrel = true; 109928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 110028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 110128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 110271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 110371c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 110471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 110528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* A quick test which can be easily done here (although it is a bit 1106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out of place): the text relocation flag makes only sense if there 110728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper is a segment which is not writable. */ 110828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (textrel) 110928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 111028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper struct loaded_segment *seg = *loadedp; 111128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper while (seg != NULL && !seg->read_only) 111228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper seg = seg->next; 111328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (seg == NULL) 11140a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 111528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppertext relocation flag set but there is no read-only segment\n")); 111628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 111728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 111828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return reldyn; 111928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 112028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 112128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 112228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperenum load_state 112328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 112428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper state_undecided, 112528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper state_loaded, 112628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper state_unloaded, 112728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper state_error 112828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper }; 112928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 113028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 113128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 113228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx, 113328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata, 113428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Addr r_offset, GElf_Xword r_info, 113528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper const GElf_Shdr *destshdr, bool reldyn, 113628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper struct loaded_segment *loaded, enum load_state *statep) 113728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 113828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper bool known_broken = gnuld; 113928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 114028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info))) 114128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), 114228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt); 114328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 114428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The executable/DSO can contain relocation sections with 114528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper all the relocations the linker has applied. Those sections 114628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper are marked non-loaded, though. */ 114728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper || (relshdr->sh_flags & SHF_ALLOC) != 0) 114828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info))) 114928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 115028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), 115128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt); 115228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 115328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL 115428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && ((GELF_R_SYM (r_info) + 1) 115528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) 11560a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard > symshdr->sh_size)) 11570a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 115828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relocation %zu: invalid symbol index\n"), 115928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt); 116028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 116128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info))) 116228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 116328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper const char *name; 116428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper char buf[64]; 116528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym sym_mem; 116628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 11670a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (sym != NULL 116828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Get the name for the symbol. */ 116928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) 117028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) 117128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 117228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), 117328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt, 117428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ebl_reloc_type_name (ebl, GELF_R_SYM (r_info), 117528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper buf, sizeof (buf))); 117628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 117728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 117828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (reldyn) 117928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 118028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper // XXX TODO Check .rel.dyn section addresses. 118128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 118228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (!known_broken) 118328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 118428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (destshdr != NULL 118528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && GELF_R_TYPE (r_info) != 0 118628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && (r_offset - destshdr->sh_addr) >= destshdr->sh_size) 118728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 118828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relocation %zu: offset out of bounds\n"), 118928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt); 119028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 119128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 119228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym sym_mem; 119328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 119428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 1195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info)) 1196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the referenced symbol is an object or unspecified. */ 1197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym != NULL 1198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE 1199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) 1200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[64]; 1202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), 1203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 1205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf, sizeof (buf))); 120641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 120741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 120841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper bool in_loaded_seg = false; 120941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 121041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 121141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (r_offset < loaded->to 121241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from) 121341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 121441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* The symbol is in this segment. */ 121541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (loaded->read_only) 121641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 121741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (textrel) 121841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper needed_textrel = true; 121941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else 122041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"), 122141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), cnt); 1222c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1223c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1224c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper in_loaded_seg = true; 122541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 1226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loaded = loaded->next; 1228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (*statep == state_undecided) 1231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *statep = in_loaded_seg ? state_loaded : state_unloaded; 1232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((*statep == state_unloaded && in_loaded_seg) 1233c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper || (*statep == state_loaded && !in_loaded_seg)) 1234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1235c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1236c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': relocations are against loaded and unloaded data\n"), 1237c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx)); 1238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *statep = state_error; 1239028d0ab0cc1cb5f96ee48feef966b7d8d56c6a8eMark Wielaard } 1240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1248c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the fields of the section header. */ 1255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr destshdr_mem; 1256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *destshdr = NULL; 1257c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper struct loaded_segment *loaded = NULL; 1258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr, 1259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &destshdr_mem, &loaded); 1260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 1263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 126471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Elf_Data *symdata = elf_getdata (symscn, NULL); 126571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek enum load_state state = state_undecided; 1266c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1267c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1268c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rela rela_mem; 1270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem); 127141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (rela == NULL) 127241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 127341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 127441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"), 127541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 127641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper continue; 1277bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath } 127841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 127941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 128041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper rela->r_offset, rela->r_info, destshdr, reldyn, loaded, 128141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper &state); 128241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 128341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 128441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 128541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 128641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *old = loaded; 128741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper loaded = loaded->next; 128841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper free (old); 128941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 129041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper} 129141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 129241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 129341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic void 129441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppercheck_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 129541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper{ 129641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 129741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (data == NULL) 129841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 129941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 13000a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx)); 130141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper return; 130241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 130341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 130441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Check the fields of the section header. */ 130541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr destshdr_mem; 130641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *destshdr = NULL; 130741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded = NULL; 130841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr, 130941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper &destshdr_mem, &loaded); 131041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 131141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 131241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr symshdr_mem; 131341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 131441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 131541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper enum load_state state = state_undecided; 131641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 131741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 131841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 131941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Rel rel_mem; 132041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem); 132141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (rel == NULL) 132241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 132341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 132441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"), 132541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 132641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper continue; 132741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 132841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 132941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1330c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper rel->r_offset, rel->r_info, destshdr, reldyn, loaded, 1331c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper &state); 1332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 133441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 133541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 133641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *old = loaded; 133741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper loaded = loaded->next; 133841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper free (old); 133941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 134041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper} 134141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 134241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1343c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper/* Number of dynamic sections. */ 1344607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepperstatic int ndynamic; 1345607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1346607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 134741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic void 134841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppercheck_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1349c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper{ 1350c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *data; 1351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr strshdr_mem; 1352c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *strshdr; 1353c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper size_t cnt; 1354c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper static const bool dependencies[DT_NUM][DT_NUM] = 1355607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1356607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper [DT_NEEDED] = { [DT_STRTAB] = true }, 1357607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper [DT_PLTRELSZ] = { [DT_JMPREL] = true }, 1358607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper [DT_HASH] = { [DT_SYMTAB] = true }, 1359607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper [DT_STRTAB] = { [DT_STRSZ] = true }, 1360607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_HASH] = true, 1361c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_SYMENT] = true }, 1362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true }, 1363c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_RELASZ] = { [DT_RELA] = true }, 1364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELAENT] = { [DT_RELA] = true }, 1365c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_STRSZ] = { [DT_STRTAB] = true }, 1366c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_SYMENT] = { [DT_SYMTAB] = true }, 1367c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_SONAME] = { [DT_STRTAB] = true }, 1368c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_RPATH] = { [DT_STRTAB] = true }, 1369c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true }, 1370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELSZ] = { [DT_REL] = true }, 1371c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_RELENT] = { [DT_REL] = true }, 1372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true }, 13736ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper [DT_RUNPATH] = { [DT_STRTAB] = true }, 13746ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper [DT_PLTREL] = { [DT_JMPREL] = true }, 13756ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper [DT_PLTRELSZ] = { [DT_JMPREL] = true } 13766ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper }; 1377c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool has_dt[DT_NUM]; 1378c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper static const bool level2[DT_NUM] = 1379c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1380c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_RPATH] = true, 1381c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_SYMBOLIC] = true, 1382c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_TEXTREL] = true, 1383c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_BIND_NOW] = true 1384c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper }; 1385c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper static const bool mandatory[DT_NUM] = 1386c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1387c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_NULL] = true, 1388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_HASH] = true, 1389c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_STRTAB] = true, 1390c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_SYMTAB] = true, 1391c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_STRSZ] = true, 1392c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper [DT_SYMENT] = true 1393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1394c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Addr reladdr = 0; 1395c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Word relsz = 0; 1396c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Addr pltreladdr = 0; 1397c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Word pltrelsz = 0; 1398c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1399c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper memset (has_dt, '\0', sizeof (has_dt)); 1400c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1401c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (++ndynamic == 2) 1402b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper ERROR (gettext ("more than one dynamic section present\n")); 1403b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 1404c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1407c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 140941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper return; 141041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 141141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 141241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem); 1413c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB) 141441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 141541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 141641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link), 141741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx)); 141841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 141941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT)) 142041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 142141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Dyn\n"), 142241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx)); 142341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 142441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (shdr->sh_info != 0) 1425038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1426038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx)); 142741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1428038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper bool non_null_warned = false; 1429038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1431038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper GElf_Dyn dyn_mem; 1432038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem); 143341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (dyn == NULL) 1434038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1435038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("\ 1436038129b11ac71a13ccaf9029122be86d6c532990Ulrich Dreppersection [%2d] '%s': cannot get dynamic section entry %zu: %s\n"), 1437038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1438038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper continue; 1439038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper } 1440038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper 1441038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned) 1442038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1443038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("\ 1444038129b11ac71a13ccaf9029122be86d6c532990Ulrich Dreppersection [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"), 144541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx)); 144641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper non_null_warned = true; 1447038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper } 1448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 144941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (!ebl_dynamic_tag_check (ebl, dyn->d_tag)) 1450038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"), 1451038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx), cnt); 1452038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper 1453038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM) 1454038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1455038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (has_dt[dyn->d_tag] 145641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && dyn->d_tag != DT_NEEDED 1457038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper && dyn->d_tag != DT_NULL 1458038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper && dyn->d_tag != DT_POSFLAG_1) 1459038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: more than one entry with tag %s\n"), 1463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, 1465c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper buf, sizeof (buf))); 1466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1467c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (be_strict && level2[dyn->d_tag]) 1469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: level 2 tag %s used\n"), 1473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, 1475c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper buf, sizeof (buf))); 1476c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1477c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 147841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper has_dt[dyn->d_tag] = true; 1479c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 148041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1481c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL 1482c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && dyn->d_un.d_val != DT_RELA) 1483c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1484c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"), 1485c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 148641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1487c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (dyn->d_tag == DT_REL) 148871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek reladdr = dyn->d_un.d_ptr; 148971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (dyn->d_tag == DT_RELSZ) 1490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper relsz = dyn->d_un.d_val; 1491c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (dyn->d_tag == DT_JMPREL) 1492c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper pltreladdr = dyn->d_un.d_ptr; 1493c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (dyn->d_tag == DT_PLTRELSZ) 1494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper pltrelsz = dyn->d_un.d_val; 1495c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1496c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Check that addresses for entries are in loaded segments. */ 1497c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper switch (dyn->d_tag) 1498c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t n; 1500c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper default: 1501607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI) 1502607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Value is no pointer. */ 1503607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 150441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* FALLTHROUGH */ 150541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 150641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper case DT_PLTGOT: 150741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper case DT_HASH: 150841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper case DT_STRTAB: 150941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper case DT_SYMTAB: 151041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper case DT_RELA: 1511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DT_INIT: 1512c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_FINI: 1513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case DT_SONAME: 1514c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_RPATH: 1515c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_SYMBOLIC: 1516c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_REL: 1517c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_JMPREL: 1518c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_INIT_ARRAY: 1519c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_FINI_ARRAY: 1520c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_RUNPATH: 1521c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_VERSYM: 1522c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_VERDEF: 1523c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_VERNEED: 1524c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_AUXILIARY: 1525c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper case DT_FILTER: 1526c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper for (n = 0; n < ehdr->e_phnum; ++n) 1527c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1528c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Phdr phdr_mem; 152941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem); 1530c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (phdr != NULL && phdr->p_type == PT_LOAD 153141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && phdr->p_vaddr <= dyn->d_un.d_ptr 1532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr) 1533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (n >= ehdr->e_phnum)) 1536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 153741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper char buf[50]; 1538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 153971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s': entry %zu: %s value must point into loaded segment\n"), 154071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek idx, section_name (ebl, idx), cnt, 1541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sizeof (buf))); 1543c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < DT_NUM; ++cnt) 1548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[cnt]) 1549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int inner = 0; inner < DT_NUM; ++inner) 1551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dependencies[cnt][inner] && ! has_dt[inner]) 1552607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1553607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper char buf1[50]; 1554607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper char buf2[50]; 155541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 155641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 155741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': contains %s entry but not %s\n"), 155841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), 155941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)), 156041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2))); 156141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 1562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (mandatory[cnt]) 1566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': mandatory tag %s not present\n"), 1570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1571607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf))); 1572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the rel/rela tags. At least one group must be available. */ 1576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT]) 1577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT])) 1578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper "DT_RELA", "DT_RELASZ", "DT_RELAENT"); 1582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1583231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT]) 1584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT])) 1585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper "DT_REL", "DT_RELSZ", "DT_RELENT"); 1589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 1596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': only relocatable files can have extended section index\n"), 1599231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1600231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper return; 1601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 1605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB) 1607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended section index section not for symbol table\n"), 1609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 1611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symdata == NULL) 1612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get data for symbol section\n")); 1613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != sizeof (Elf32_Word)) 1615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry size does not match Elf32_Word\n"), 1617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1618231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1619231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (symshdr != NULL 1620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_size / shdr->sh_entsize 1621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < symshdr->sh_size / symshdr->sh_entsize)) 1622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended index table too small for symbol table\n"), 162441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx)); 1625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = idx + 1; cnt < shnum; ++cnt) 1631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr rshdr_mem; 1633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem); 1634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX 1635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && rshdr->sh_link == shdr->sh_link) 1636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 16380a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"), 16390a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx), 16400a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard cnt, section_name (ebl, cnt)); 16410a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard break; 16420a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 16430a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 16440a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 1645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 164671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 164771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (*((Elf32_Word *) data->d_buf) != 0) 1648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("symbol 0 should have zero extended section index\n")); 1649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt]; 1653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndx != 0) 1655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym_data; 165771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data); 1658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 1659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1660acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("cannot get data for symbol %zu\n"), cnt); 1661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != SHN_XINDEX) 1665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperextended section index is %" PRIu32 " but symbol index is not XINDEX\n"), 1667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (uint32_t) xndx); 1668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_hash (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL) 1677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocatable files cannot have hash tables\n"), 1680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 1693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 1694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &symshdr_mem); 1695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM) 1696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': hash table not for dynamic symbol table\n"), 1698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != sizeof (Elf32_Word)) 1701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry size does not match Elf32_Word\n"), 1703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) == 0) 1706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"), 1707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 17080a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 1709231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (shdr->sh_size < 2 * shdr->sh_entsize) 1710231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper { 17110a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 1712231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': hash table has not even room for nbucket and nchain\n"), 1713231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 1718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 1719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 1721607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 1722607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 1723607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 1724607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 1725cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1726cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (symshdr != NULL) 1727cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper { 1728cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 1729cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper size_t cnt; 1730cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1731cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (nchain < symshdr->sh_size / symshdr->sh_entsize) 1732cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("section [%2d] '%s': chain array not large enough\n"), 1733cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx)); 1734cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1735cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper for (cnt = 2; cnt < 2 + nbucket; ++cnt) 1736cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (((Elf32_Word *) data->d_buf)[cnt] >= symsize) 1737cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("\ 1738607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': hash bucket reference %zu out of bounds\n"), 1739607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper idx, section_name (ebl, idx), cnt - 2); 1740607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1741607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper for (; cnt < 2 + nbucket + nchain; ++cnt) 1742607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (((Elf32_Word *) data->d_buf)[cnt] >= symsize) 1743607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 1744cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': hash chain reference %zu out of bounds\n"), 1745cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), cnt - 2 - nbucket); 1746cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper } 1747cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper} 1748607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1749607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1750607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepperstatic void 1751cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppercheck_null (Ebl *ebl, GElf_Shdr *shdr, int idx) 1752cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper{ 1753cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper#define TEST(name, extra) \ 1754cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (extra && shdr->sh_##name != 0) \ 1755cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"), \ 1756cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), #name) 1757607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1758607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper TEST (name, 1); 1759cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper TEST (flags, 1); 1760cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper TEST (addr, 1); 1761bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath TEST (offset, 1); 1762607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper TEST (size, idx != 0); 1763607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper TEST (link, idx != 0); 1764607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper TEST (info, 1); 1765607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper TEST (addralign, 1); 1766607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper TEST (entsize, 1); 1767607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper} 1768607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1769607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1770bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrathstatic void 1771607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppercheck_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1772607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper{ 1773607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (ehdr->e_type != ET_REL) 1774607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1775607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 1776607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': section groups only allowed in relocatable object files\n"), 1777607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper idx, section_name (ebl, idx)); 1778607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper return; 1779cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper } 1780cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1781cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper /* Check that sh_link is an index of a symbol table. */ 1782cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper GElf_Shdr symshdr_mem; 1783cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 1784cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper &symshdr_mem); 1785cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (symshdr == NULL) 1786cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"), 1787cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), elf_errmsg (-1)); 1788cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper else 1789cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper { 1790cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (symshdr->sh_type != SHT_SYMTAB) 1791cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("\ 1792cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': section reference in sh_link is no symbol table\n"), 1793cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx)); 1794cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1795cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM, 1796607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1, EV_CURRENT)) 1797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': invalid symbol index in sh_info\n"), 1799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags != 0) 1802acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"), 1803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (be_strict 1806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT)) 1807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"), 1808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"), 1814b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), elf_errmsg (-1)); 1815b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT); 1818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 1819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word val; 1820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size % elsize != 0) 1822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"), 1824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size < elsize) 1827231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1828231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section group without flags word\n"), 1829231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1830231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper else if (be_strict) 1831231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper { 1832231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (data->d_size < 2 * elsize) 1833231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1834231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section group without member\n"), 1835231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1836231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper else if (data->d_size < 3 * elsize) 1837231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1838231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section group with only one member\n"), 1839231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1840231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED 1843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val = *((Elf32_Word *) data->d_buf); 1844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#else 1845b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (&val, data->d_buf, elsize); 1846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 1847b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((val & ~GRP_COMDAT) != 0) 1848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"), 1849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = elsize; cnt < data->d_size; cnt += elsize) 1852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED 1854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val = *((Elf32_Word *) ((char *) data->d_buf + cnt)); 1855231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper#else 1856231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper memcpy (&val, (char *) data->d_buf + cnt, elsize); 1857231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper#endif 1858231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1859231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (val > shnum) 1860231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1861231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section index %Zu out of range\n"), 1862231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), cnt / elsize); 1863231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper else 1864231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper { 1865231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper GElf_Shdr refshdr_mem; 1866231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val), 1867231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper &refshdr_mem); 1868231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (refshdr == NULL) 1869231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1870231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': cannot get section header for element %zu: %s\n"), 1871231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), cnt / elsize, 1872231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper elf_errmsg (-1)); 1873231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper else 1874231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper { 1875231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (refshdr->sh_type == SHT_GROUP) 1876231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1877231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': section group contains another group [%2d] '%s'\n"), 1878231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), 1879231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper val, section_name (ebl, val)); 1880231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1881231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if ((refshdr->sh_flags & SHF_GROUP) == 0) 1882231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1883231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP flag set\n"), 1884231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), cnt / elsize, 1885231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper val, section_name (ebl, val)); 1886231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1887231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1888231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (++scnref[val] == 2) 1889231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1890231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s' is contained in more than one section group\n"), 1891231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper val, section_name (ebl, val)); 1892231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1893231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1894231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1895231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper} 1896231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1897231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char * 1899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_flags_string (GElf_Word flags, char *buf, size_t len) 1900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const struct 1902acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 1903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word flag; 1904acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper const char *name; 1905acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } known_flags[] = 1906acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 1907acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper#define NEWFLAG(name) { SHF_##name, #name } 1908acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper NEWFLAG (WRITE), 1909acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper NEWFLAG (ALLOC), 1910acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper NEWFLAG (EXECINSTR), 1911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (MERGE), 1912acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper NEWFLAG (STRINGS), 1913acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper NEWFLAG (INFO_LINK), 1914acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper NEWFLAG (LINK_ORDER), 1915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (OS_NONCONFORMING), 1916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (GROUP), 1917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (TLS) 1918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 19190a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard#undef NEWFLAG 19200a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]); 19210a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 19220a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard char *cp = buf; 1923acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 1924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < nknown_flags; ++cnt) 1925b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags & known_flags[cnt].flag) 1926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cp != buf && len > 1) 1928b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1929b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = '|'; 1930b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper --len; 1931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 19330a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name)); 19340a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard cp = mempcpy (cp, known_flags[cnt].name, ncopy); 1935b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper len -= ncopy; 1936b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1937b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper flags ^= known_flags[cnt].flag; 1938b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1940b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags != 0 || cp == buf) 1941b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags); 1942b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1943b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp = '\0'; 1944b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1945acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return buf; 1946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1947b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1948acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 1949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 1950b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperhas_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx) 1951b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* First find the relocation section for the symbol table. */ 1953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 1954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 1955b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr = NULL; 1956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1957b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1958b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr = gelf_getshdr (scn, &shdr_mem); 1959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr != NULL 1960acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) 19610a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard && shdr->sh_link == symscnndx) 196271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek /* Found the section. */ 196371c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek break; 196471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 196571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 196671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (scn == NULL) 1967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 1968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 1970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1971acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return 0; 1972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type == SHT_REL) 1974b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 1975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel rel_mem; 1977b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel *rel = gelf_getrel (data, i, &rel_mem); 1978b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rel == NULL) 1979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_R_SYM (rel->r_info) == symndx 1982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) 1983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 1984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 1987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1988b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rela rela_mem; 1989b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rela *rela = gelf_getrela (data, i, &rela_mem); 1990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rela == NULL) 1991b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1992b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1993b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_R_SYM (rela->r_info) == symndx 1994b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) 199528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return 1; 199628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 199728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 199828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return 0; 199928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 200028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 200128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 200228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic int 200328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperin_nobits_scn (Ebl *ebl, unsigned int shndx) 200428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 200528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr shdr_mem; 200628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem); 200728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return shdr != NULL && shdr->sh_type == SHT_NOBITS; 200828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 200971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 201028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 201128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic struct version_namelist 201228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 201328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper const char *objname; 201428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper const char *name; 201528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Word ndx; 201628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper enum { ver_def, ver_need } type; 201728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper struct version_namelist *next; 201828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} *version_namelist; 201928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 202071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 202171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinekstatic int 202228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperadd_version (const char *objname, const char *name, GElf_Word ndx, int type) 202328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 202471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek /* Check that there are no duplications. */ 202571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek struct version_namelist *nlp = version_namelist; 202671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek while (nlp != NULL) 202771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek { 202828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((nlp->objname == NULL && objname == NULL) 202928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper || (nlp->objname != NULL && objname != NULL 203028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && strcmp (nlp->objname, objname) == 0)) 203171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek && strcmp (nlp->name, name) == 0) 203228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return nlp->type == ver_def ? 1 : -1; 203328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper nlp = nlp->next; 203471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 203571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 203671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek nlp = xmalloc (sizeof (*nlp)); 203771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek nlp->objname = objname; 203828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper nlp->name = name; 203928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper nlp->ndx = ndx; 204028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper nlp->type = type; 204171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek nlp->next = version_namelist; 204228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper version_namelist = nlp; 204328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 204428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return 0; 204528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 204628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 204728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 204828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 204928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_versym (Ebl *ebl, int idx) 205028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 205128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Scn *scn = elf_getscn (ebl->elf, idx); 205228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr shdr_mem; 205328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 205428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr == NULL) 205528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The error has already been reported. */ 205628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return; 205728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 205828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 205928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (data == NULL) 20600a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 206128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 206228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 206328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return; 206428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 206528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 206628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 206728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr symshdr_mem; 206828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 206928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr == NULL) 207028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The error has already been reported. */ 207171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek return; 207271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 207328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr->sh_type != SHT_DYNSYM) 207428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 207571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek ERROR (gettext ("\ 207671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"), 207771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek idx, section_name (ebl, idx), 207871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek shdr->sh_link, section_name (ebl, shdr->sh_link)); 207928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return; 208028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 208128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 208271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek /* The number of elements in the version symbol table must be the 208328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper same as the number of symbols. */ 208428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_size / shdr->sh_entsize 208571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek != symshdr->sh_size / symshdr->sh_entsize) 208671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek ERROR (gettext ("\ 208771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"), 208871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek idx, section_name (ebl, idx), 208928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 2090dcf6160602985e6eb70c96c6546ed9614a414d98Ulrich Drepper 209171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Elf_Data *symdata = elf_getdata (symscn, NULL); 209271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (symdata == NULL) 209328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The error has already been reported. */ 209428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return; 209528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 209628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 209728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 209828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Versym versym_mem; 209928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem); 2100281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard if (versym == NULL) 2101281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard { 2102281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard ERROR (gettext ("\ 2103281bb49c71665f306b23107cbf821636f59211e0Mark Wielaardsection [%2d] '%s': symbol %d: cannot read version data\n"), 2104281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard idx, section_name (ebl, idx), cnt); 2105281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard break; 2106281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard } 2107281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard 210828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym sym_mem; 210928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem); 21108ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (sym == NULL) 211128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Already reported elsewhere. */ 2112281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard continue; 2113281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard 2114281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard if (*versym == VER_NDX_GLOBAL) 2115281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard { 2116281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard /* Global symbol. Make sure it is not defined as local. */ 2117281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2118281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard ERROR (gettext ("\ 21198ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': symbol %d: local symbol with global scope\n"), 21208ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), cnt); 21218ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 21228ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper else if (*versym != VER_NDX_LOCAL) 21238ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 21248ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper /* Versioned symbol. Make sure it is not defined as local. */ 2125281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2126281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard ERROR (gettext ("\ 2127281bb49c71665f306b23107cbf821636f59211e0Mark Wielaardsection [%2d] '%s': symbol %d: local symbol with version\n"), 2128281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard idx, section_name (ebl, idx), cnt); 212928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 213028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Look through the list of defined versions and locate the 213171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek index we need for this symbol. */ 213228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper struct version_namelist *runp = version_namelist; 2133281bb49c71665f306b23107cbf821636f59211e0Mark Wielaard while (runp != NULL) 213428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (runp->ndx == *versym) 213528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 213628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 21378ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper runp = runp->next; 213816e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaard 213916e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaard if (runp == NULL) 21408ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 214116e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaardsection [%2d] '%s': symbol %d: invalid version index %d\n"), 214216e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaard idx, section_name (ebl, idx), cnt, (int) *versym); 214316e2ac344788f2bb08ae9dc0a20948f554ca560cMark Wielaard else if (sym->st_shndx == SHN_UNDEF 21448ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper && runp->type == ver_def) 21458ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 21468ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for defined version\n"), 214728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 21480a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard else if (sym->st_shndx != SHN_UNDEF 214928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && runp->type == ver_need) 215028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 215128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Unless this symbol has a copy relocation associated 215228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper this must not happen. */ 215328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (!has_copy_reloc (ebl, shdr->sh_link, cnt) 21548ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper && !in_nobits_scn (ebl, sym->st_shndx)) 21558ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 21568ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for requested version\n"), 21578ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 21588ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 21598ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 21608ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 21618ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper} 21628ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 216328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 21648ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepperstatic int 216528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperunknown_dependency_p (Elf *elf, GElf_Ehdr *ehdr, const char *fname) 21668ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper{ 216728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Phdr phdr_mem; 216828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Phdr *phdr = NULL; 21698ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 217028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper int i; 217128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (i = 0; i < ehdr->e_phnum; ++i) 217228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL 217328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && phdr->p_type == PT_DYNAMIC) 217428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 21758ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 217628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (i == ehdr->e_phnum) 217728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return 1; 217828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper assert (phdr != NULL); 217928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); 218028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr shdr_mem; 21818ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 21828ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 21838ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL) 218428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) 218528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 218628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Dyn dyn_mem; 218728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); 218828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn != NULL && dyn->d_tag == DT_NEEDED) 218928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 219028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val); 219128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (str != NULL && strcmp (str, fname) == 0) 2192231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* Found it. */ 2193231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper return 0; 219428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 219528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 21965530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper 21975530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper return 1; 219828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 21990a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 22000a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 22010a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardstatic unsigned int nverneed; 22020a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 220328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 220428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_verneed (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 220528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 220628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (++nverneed == 2) 220728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("more than one version reference section present\n")); 220828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 22095530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper GElf_Shdr strshdr_mem; 22105530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 22118ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper &strshdr_mem); 22128ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (strshdr == NULL) 22138ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper return; 22140a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (strshdr->sh_type != SHT_STRTAB) 22150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 22160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': sh_link does not link to string table\n"), 22170a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx)); 22180a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 22190a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 22200a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (data == NULL) 22210a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 22228ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 22238ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx)); 22248ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper return; 22258ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 22268ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper unsigned int offset = 0; 22278ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper for (int cnt = shdr->sh_info; --cnt >= 0; ) 22288ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 22298ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper /* Get the data at the next offset. */ 22308ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper GElf_Verneed needmem; 22318ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 22328ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (need == NULL) 22338ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper break; 22348ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 22358ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper unsigned int auxoffset = offset + need->vn_aux; 223628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 223728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (need->vn_version != EV_CURRENT) 223828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 223928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"), 224028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) need->vn_version); 224128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 224228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED, 224328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 1, EV_CURRENT)) 224428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 224528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 224628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt); 224728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 22485530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper const char *libname = elf_strptr (ebl->elf, shdr->sh_link, 22490a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard need->vn_file); 225028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (libname == NULL) 225128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 225228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 22535530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Dreppersection [%2d] '%s': entry %d has invalid file reference\n"), 225428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt); 22558ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper goto next_need; 22568ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 22578ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 22588ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper /* Check that there is a DT_NEEDED entry for the referenced library. */ 22598ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (unknown_dependency_p (ebl->elf, ehdr, libname)) 22608ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 22618ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': entry %d references unknown dependency\n"), 226228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt); 226328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 226428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 226528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 226628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Vernaux auxmem; 2267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 2268acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (aux == NULL) 2269acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper break; 2270acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2271acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if ((aux->vna_flags & ~VER_FLG_WEAK) != 0) 2272acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2273acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"), 2274acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2276acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper const char *verstr = elf_strptr (ebl->elf, shdr->sh_link, 22770a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard aux->vna_name); 2278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (verstr == NULL) 2279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"), 2281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2284acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Word hashval = elf_hash (verstr); 2285acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (hashval != aux->vna_hash) 2286acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"), 2288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, (int) hashval, (int) aux->vna_hash); 2290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 22910a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard int res = add_version (libname, verstr, aux->vna_other, 22920a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ver_need); 22930a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (unlikely (res !=0)) 22940a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 2295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (res > 0); 229628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 22978ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"), 22988ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, 229928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper cnt, verstr); 2300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 230128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 2302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((aux->vna_next != 0 || cnt2 > 0) 2304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, 2305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EV_CURRENT)) 2306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 23088ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"), 2309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 23118ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 2312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper auxoffset += MAX (aux->vna_next, 2314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT)); 2315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 231628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 2317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Find the next offset. */ 231828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper next_need: 231928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper offset += need->vn_next; 232028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 232128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if ((need->vn_next != 0 || cnt > 0) 232228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && offset < auxoffset) 232328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 2324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %d has invalid offset to next entry\n"), 232528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt); 232628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 232728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 2328ee4b927bae351b21787355e00a3d28371bf78e8fUlrich Drepper 232928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 23308ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepperstatic unsigned int nverdef; 2331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx) 2334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 23357c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (++nverdef == 2) 23367c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("more than one version definition section present\n")); 23377c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23387c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr strshdr_mem; 23397c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 23407c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper &strshdr_mem); 23417c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (strshdr == NULL) 23427c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper return; 23437c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (strshdr->sh_type != SHT_STRTAB) 23447c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 23457c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': sh_link does not link to string table\n"), 23467c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper idx, section_name (ebl, idx)); 23477c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23487c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 23497c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (data == NULL) 23500a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 23510a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard no_data: 23527c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 23537c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper idx, section_name (ebl, idx)); 23547c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper return; 23557c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23567c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23577c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* Iterate over all version definition entries. We check that there 23587c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper is a BASE entry and that each index is unique. To do the later 23597c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper we collection the information in a list which is later 23607c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper examined. */ 23617c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper struct namelist 23627c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23637c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const char *name; 23647c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper struct namelist *next; 23657c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } *namelist = NULL; 23667c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper struct namelist *refnamelist = NULL; 23677c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23687c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper bool has_base = false; 23697c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper unsigned int offset = 0; 23707c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (int cnt = shdr->sh_info; --cnt >= 0; ) 23717c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23720a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard /* Get the data at the next offset. */ 23730a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard GElf_Verdef defmem; 23747c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 23757c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (def == NULL) 23760a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard goto no_data; 23770a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 23780a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if ((def->vd_flags & VER_FLG_BASE) != 0) 23790a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 23800a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (has_base) 23810a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 23820a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': more than one BASE definition\n"), 23830a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx)); 23840a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (def->vd_ndx != VER_NDX_GLOBAL) 23850a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 23860a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"), 23870a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx)); 23880a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard has_base = true; 23890a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 23907c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0) 23917c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 23927c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': entry %d has unknown flag\n"), 23937c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper idx, section_name (ebl, idx), cnt); 23947c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23957c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (def->vd_version != EV_CURRENT) 23960a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 23977c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"), 23987c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) def->vd_version); 23997c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 24000a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF, 24010a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 1, EV_CURRENT)) 24020a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 24030a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 24040a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx), cnt); 24050a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 24060a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard unsigned int auxoffset = offset + def->vd_aux; 24070a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard GElf_Verdaux auxmem; 24080a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 24090a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (aux == NULL) 24100a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard goto no_data; 24110a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 24120a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 24130a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (name == NULL) 24140a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 24150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 24160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': entry %d has invalid name reference\n"), 24170a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx), cnt); 24180a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard goto next_def; 24190a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 24207c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Word hashval = elf_hash (name); 24217c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (def->vd_hash != hashval) 24227c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 2423ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaardsection [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"), 2424ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard idx, section_name (ebl, idx), cnt, (int) hashval, 2425ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard (int) def->vd_hash); 2426ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard 2427ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard int res = add_version (NULL, name, def->vd_ndx, ver_def); 2428ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard if (unlikely (res !=0)) 2429ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard { 2430ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard assert (res > 0); 2431ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard ERROR (gettext ("\ 2432ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaardsection [%2d] '%s': entry %d has duplicate version name '%s'\n"), 2433ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard idx, section_name (ebl, idx), cnt, name); 2434ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard } 2435ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard 2436ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard struct namelist *newname = alloca (sizeof (*newname)); 2437ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard newname->name = name; 2438ae9aa3e4b2853d58598a6928eb1dbaacf6488496Mark Wielaard newname->next = namelist; 24397c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper namelist = newname; 24407c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 24417c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper auxoffset += aux->vda_next; 24427c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 24437c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 24447c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper aux = gelf_getverdaux (data, auxoffset, &auxmem); 24457c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (aux == NULL) 24460a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard goto no_data; 24470a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 24480a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 24490a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (name == NULL) 24500a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 24510a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"), 24520a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx), cnt); 24530a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard else 24547c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 24550a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard newname = alloca (sizeof (*newname)); 24560a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard newname->name = name; 24570a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard newname->next = refnamelist; 24580a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard refnamelist = newname; 24590a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 24600a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 24610a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt) 24620a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, 24630a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard EV_CURRENT)) 24640a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 24657c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 24667c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': entry %d has wrong next field in auxiliary data\n"), 24677c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper idx, section_name (ebl, idx), cnt); 24687c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper break; 24697c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 24707c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 24710a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard auxoffset += MAX (aux->vda_next, 24727c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT)); 24737c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 24747c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 24757c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* Find the next offset. */ 24767c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper next_def: 24777c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper offset += def->vd_next; 24780a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 24797c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if ((def->vd_next != 0 || cnt > 0) 24807c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper && offset < auxoffset) 24810a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 24820a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardsection [%2d] '%s': entry %d has invalid offset to next entry\n"), 24830a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx), cnt); 24840a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 24850a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 24860a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (!has_base) 24870a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("section [%2d] '%s': no BASE definition\n"), 24880a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard idx, section_name (ebl, idx)); 24897c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 24900a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard /* Check whether the referenced names are available. */ 24910a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard while (namelist != NULL) 24920a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 24930a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard struct version_namelist *runp = version_namelist; 24940a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard while (runp != NULL) 24950a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 24960a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (runp->type == ver_def 24970a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard && strcmp (runp->name, namelist->name) == 0) 24980a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard break; 24990a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard runp = runp->next; 25000a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 25010a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 25027c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (runp == NULL) 25037c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 25047c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersection [%2d] '%s': unknown parent version '%s'\n"), 25057c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper idx, section_name (ebl, idx), namelist->name); 25067c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 25077c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper namelist = namelist->next; 25080a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 25097c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper} 25107c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 25117c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 25127c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepperstatic bool has_loadable_segment; 25137c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepperstatic bool has_interp_segment; 25147c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 25150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardstatic const struct 25160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard{ 25170a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard const char *name; 25180a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard size_t namelen; 25190a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard GElf_Word type; 25200a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard enum { unused, exact, atleast } attrflag; 25210a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard GElf_Word attr; 25227c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Word attr2; 25237c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper} special_sections[] = 25247c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 25257c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* See figure 4-14 in the gABI. */ 25267c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 25277c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".comment", 8, SHT_PROGBITS, exact, 0, 0 }, 25287c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 25297c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 25307c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".debug", 7, SHT_PROGBITS, exact, 0, 0 }, 25317c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE }, 25327c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 }, 25337c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 }, 25340a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 25357c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 25367c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info? 25377c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 }, 25387c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 25397c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 25407c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests? 25417c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".line", 6, SHT_PROGBITS, exact, 0, 0 }, 25427c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".note", 6, SHT_NOTE, exact, 0, 0 }, 25437c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests 25447c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 25457c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC }, // XXX more tests 25467c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests 25477c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 25487c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 25497c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 }, 25507c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 25517c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 25527c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests 25537c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 25547c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 25557c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 25567c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 25577c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 25587c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* The following are GNU extensions. */ 25597c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 }, 25607c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 }, 2561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 } 2562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 2563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define nspecial_sections \ 2564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (sizeof (special_sections) / sizeof (special_sections[0])) 2565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_sections (Ebl *ebl, GElf_Ehdr *ehdr) 2569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shoff == 0) 2571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No section header. */ 2572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate array to count references in section groups. */ 2575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scnref = (int *) xcalloc (shnum, sizeof (int)); 2576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the zeroth section first. It must not have any contents 2578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper and the section header must contain nonzero value at most in the 2579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sh_size and sh_link fields. */ 2580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 2581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 2582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 2583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get section header of zeroth section\n")); 2584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_name != 0) 2587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero name\n")); 2588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type != 0) 2589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero type\n")); 2590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags != 0) 2591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero flags\n")); 2592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addr != 0) 25930e864dd86871c809668c557985ca19344dfff787Ulrich Drepper ERROR (gettext ("zeroth section has nonzero address\n")); 2594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_offset != 0) 25950e864dd86871c809668c557985ca19344dfff787Ulrich Drepper ERROR (gettext ("zeroth section has nonzero offset\n")); 2596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 2597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero info field\n")); 2598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addralign != 0) 2599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero align value\n")); 2600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != 0) 2601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero entry size value\n")); 2602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size != 0 && ehdr->e_shnum != 0) 2604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero size value while ELF header has nonzero shnum value\n")); 2606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX) 2608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n")); 2610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool dot_interp_section = false; 2613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t versym_scnndx = 0; 2615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 1; cnt < shnum; ++cnt) 26160e864dd86871c809668c557985ca19344dfff787Ulrich Drepper { 26170e864dd86871c809668c557985ca19344dfff787Ulrich Drepper shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem); 26180e864dd86871c809668c557985ca19344dfff787Ulrich Drepper if (shdr == NULL) 26190e864dd86871c809668c557985ca19344dfff787Ulrich Drepper { 26200e864dd86871c809668c557985ca19344dfff787Ulrich Drepper ERROR (gettext ("\ 26210e864dd86871c809668c557985ca19344dfff787Ulrich Dreppercannot get section header for section [%2zu] '%s': %s\n"), 26220e864dd86871c809668c557985ca19344dfff787Ulrich Drepper cnt, section_name (ebl, cnt), elf_errmsg (-1)); 26230a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard continue; 26240a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 26250a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 26260a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 26270e864dd86871c809668c557985ca19344dfff787Ulrich Drepper 26280e864dd86871c809668c557985ca19344dfff787Ulrich Drepper if (scnname == NULL) 26290e864dd86871c809668c557985ca19344dfff787Ulrich Drepper ERROR (gettext ("section [%2zu]: invalid name\n"), cnt); 26303b495d8e963eead963a37b5be5b063c96bb58c63Roland McGrath else 26310e864dd86871c809668c557985ca19344dfff787Ulrich Drepper { 26320e864dd86871c809668c557985ca19344dfff787Ulrich Drepper /* Check whether it is one of the special sections defined in 2633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the gABI. */ 2634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t s; 2635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (s = 0; s < nspecial_sections; ++s) 2636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strncmp (scnname, special_sections[s].name, 2637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper special_sections[s].namelen) == 0) 2638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf1[100]; 26400a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard char stbuf2[100]; 2641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf3[100]; 2642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word good_type = special_sections[s].type; 2644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (special_sections[s].namelen == sizeof ".plt" && 2645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper !memcmp (special_sections[s].name, ".plt", sizeof ".plt") 2646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_bss_plt_p (ebl, ehdr)) 2647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper good_type = SHT_NOBITS; 2648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type != good_type 2650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !(is_debuginfo && shdr->sh_type == SHT_NOBITS)) 2651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' has wrong type: expected %s, is %s\n"), 2653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) cnt, scnname, 2654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_type_name (ebl, special_sections[s].type, 2655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 2656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_type_name (ebl, shdr->sh_type, 2657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2))); 2658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (special_sections[s].attrflag == exact) 2660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Except for the link order and group bit all the 2662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper other bits should match exactly. */ 2663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP)) 2664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != special_sections[s].attr) 2665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s, is %s\n"), 2667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname, 2668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr, 2669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 2670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (shdr->sh_flags 2671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~SHF_LINK_ORDER, 2672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2))); 2673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (special_sections[s].attrflag == atleast) 2675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & special_sections[s].attr) 2677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != special_sections[s].attr 2678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP 2679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | special_sections[s].attr 2680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | special_sections[s].attr2)) 2681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != 0)) 2682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"), 2684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname, 2685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr, 2686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 2687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr2, 2688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2)), 26892ec957327cdfae6cee592a52958a9c937ea4b13cChih-Hung Hsieh section_flags_string (shdr->sh_flags 2690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~(SHF_LINK_ORDER 2691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_GROUP), 2692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf3, sizeof (stbuf3))); 2693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2694acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2695acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strcmp (scnname, ".interp") == 0) 2696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper dot_interp_section = true; 2698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL) 2700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' present in object file\n"), 2702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 2703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) != 0 2705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !has_loadable_segment) 2706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 2708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 2709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((shdr->sh_flags & SHF_ALLOC) == 0 2710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && has_loadable_segment) 27112ec957327cdfae6cee592a52958a9c937ea4b13cChih-Hung Hsieh ERROR (gettext ("\ 2712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 2713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 2714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 27160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 2717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (scnname, ".symtab_shndx") == 0 2718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_REL) 2719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' is extension section index table in non-object file\n"), 2721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 2722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* These sections must have the SHF_ALLOC flag set iff 2724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper a loadable segment is available. 2725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .relxxx 2727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .strtab 2728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .symtab 2729099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath .symtab_shndx 2730099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath 2731099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath Check that if there is a reference from the 2732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loaded section these sections also have the 2733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ALLOC flag set. */ 2734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if 0 2735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX TODO 2736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) != 0 2737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !has_loadable_segment) 2738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 2740b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 2741b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((shdr->sh_flags & SHF_ALLOC) == 0 2742b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && has_loadable_segment) 2743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 2745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 2746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 2747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 2750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize) 2754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2755acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2zu] '%s': size not multiple of entry size\n"), 2756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 2757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL) 2759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get section header\n")); 2760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type >= SHT_NUM 2762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_LIBLIST 2763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_CHECKSUM 2764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_verdef 2765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_verneed 2766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_versym 2767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL) 2768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"), 2769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), 2770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) shdr->sh_type); 2771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ 2773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ 2774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) 2775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags & ~ALL_SH_FLAGS) 2776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" 2777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper " %#" PRIx64 "\n"), 2778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), 2779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (uint64_t) shdr->sh_flags & ~(uint64_t) ALL_SH_FLAGS); 2780dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (shdr->sh_flags & SHF_TLS) 2781dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2782dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper // XXX Correct? 2783dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr->sh_addr != 0 && !gnuld) 2784dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2785dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': thread-local data sections address not zero\n"), 2786dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 2787dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2788dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper // XXX TODO more tests!? 2789dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2790dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2791dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr->sh_link >= shnum) 2792dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2793dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': invalid section reference in link value\n"), 2794dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 2795dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2796dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum) 2797dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2798dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': invalid section reference in info value\n"), 2799dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 2800dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 28010a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if ((shdr->sh_flags & SHF_MERGE) == 0 2802dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && (shdr->sh_flags & SHF_STRINGS) != 0 2803dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && be_strict) 2804dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2805dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': strings flag set without merge flag\n"), 2806dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 2807dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2808dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0) 2809dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2810dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': merge flag set but entry size is zero\n"), 2811dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 2812dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2813dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr->sh_flags & SHF_GROUP) 2814dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_scn_group (ebl, cnt); 2815dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2816dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0) 2817dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2818dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Make sure the section is contained in a loaded segment 2819dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper and that the initialization part matches NOBITS sections. */ 2820dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int pcnt; 2821dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr phdr_mem; 2822dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr *phdr; 2823dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2824dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 2825dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL 2826dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ((phdr->p_type == PT_LOAD 2827dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && (shdr->sh_flags & SHF_TLS) == 0) 2828dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper || (phdr->p_type == PT_TLS 2829dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && (shdr->sh_flags & SHF_TLS) != 0)) 2830dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr->p_offset <= shdr->sh_offset 2831dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr->p_offset + phdr->p_memsz > shdr->sh_offset) 2832dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2833637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper /* Found the segment. */ 2834637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper if (phdr->p_offset + phdr->p_memsz 2835637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper < shdr->sh_offset + shdr->sh_size) 2836637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper ERROR (gettext ("\ 2837637963b564240fe6db4908b28238b75aa0758a06Ulrich Dreppersection [%2zu] '%s' not fully contained in segment of program header entry %d\n"), 2838637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper cnt, section_name (ebl, cnt), pcnt); 2839637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2840637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper if (shdr->sh_type == SHT_NOBITS) 2841637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { 2842dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz 2843dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && !is_debuginfo) 2844dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2845dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"), 2846858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath cnt, section_name (ebl, cnt), pcnt); 2847dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2848dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2849dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2850dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const GElf_Off end = phdr->p_offset + phdr->p_filesz; 2851dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr->sh_offset > end || 2852dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper (shdr->sh_offset == end && shdr->sh_size != 0)) 2853858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath ERROR (gettext ("\ 2854dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"), 2855dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt), pcnt); 2856dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2857dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2858dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2859dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2860dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2861dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (pcnt == ehdr->e_phnum) 2862dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2863dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': alloc flag set but section not in any loaded segment\n"), 2864dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 2865dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2866dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2867dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB) 2868dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2869dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"), 2870dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 2871dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2872dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper switch (shdr->sh_type) 2873dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2874dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case SHT_DYNSYM: 2875dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (ehdr->e_type == ET_REL) 2876dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2877dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), 2878dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, section_name (ebl, cnt)); 2879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* FALLTHROUGH */ 2880dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case SHT_SYMTAB: 2881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_symtab (ebl, ehdr, shdr, cnt); 2882dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2883dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2884dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case SHT_RELA: 2885dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_rela (ebl, ehdr, shdr, cnt); 2886dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2887dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2888dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case SHT_REL: 2889dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_rel (ebl, ehdr, shdr, cnt); 2890dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2891dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2892dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case SHT_DYNAMIC: 2893dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_dynamic (ebl, ehdr, shdr, cnt); 2894dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2895dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2896dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case SHT_SYMTAB_SHNDX: 2897dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_symtab_shndx (ebl, ehdr, shdr, cnt); 2898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 2899dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_HASH: 2901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_hash (ebl, ehdr, shdr, cnt); 2902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 2903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_NULL: 2905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_null (ebl, shdr, cnt); 2906b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 2907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2908b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GROUP: 2909b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_group (ebl, ehdr, shdr, cnt); 2910b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 2911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2912b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GNU_versym: 2913dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* We cannot process this section now since we have no guarantee 2914dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper that the verneed and verdef sections have already been read. 29150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard Just remember the section index. */ 291671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (versym_scnndx != 0) 291771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek ERROR (gettext ("more than one version symbol table present\n")); 2918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper versym_scnndx = cnt; 2919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 2920b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2921b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GNU_verneed: 2922b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_verneed (ebl, ehdr, shdr, cnt); 2923dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 29240a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 2925dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case SHT_GNU_verdef: 2926dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_verdef (ebl, shdr, cnt); 2927dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2928dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2929dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper default: 2930dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Nothing. */ 2931dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2932dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2933dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2934dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2935dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (has_interp_segment && !dot_interp_section) 2936dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("INTERP program header entry but no .interp section\n")); 2937dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2938dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (version_namelist != NULL) 2939dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2940dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym_scnndx == 0) 2941dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2942dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperno .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n")); 2943dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2944dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_versym (ebl, versym_scnndx); 2945dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 294661655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper /* Check for duplicate index numbers. */ 2947dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper do 2948dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2949dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist->next; 2950dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 2951dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2952dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (version_namelist->ndx == runp->ndx) 2953dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 295461655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper ERROR (gettext ("duplicate version index %d\n"), 2955dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper (int) version_namelist->ndx); 2956c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper break; 2957c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper } 2958c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper runp = runp->next; 2959c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper } 2960c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper 2961c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper struct version_namelist *old = version_namelist; 2962dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper version_namelist = version_namelist->next; 2963dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper free (old); 2964dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2965dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (version_namelist != NULL); 2966858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath } 2967dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (versym_scnndx != 0) 2968dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2969dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n")); 2970dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2971dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper free (scnref); 2972dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2973dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2974dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2975dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic void 2976dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt) 2977dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2978dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL 2979dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 2980dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2981dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperphdr[%d]: no note entries defined for the type of file\n"), 2982dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt); 2983dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2984dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (is_debuginfo) 2985637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper /* The p_offset values in a separate debug file are bogus. */ 2986637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper return; 2987dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2988dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper char *notemem = gelf_rawchunk (ebl->elf, phdr->p_offset, phdr->p_filesz); 2989dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2990dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* ELF64 files often use note section entries in the 32-bit format. 2991dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper The p_align field is set to 8 in case the 64-bit format is used. 2992dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper In case the p_align value is 0 or 4 the 32-bit format is 2993dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper used. */ 2994dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Xword align = phdr->p_align == 0 || phdr->p_align == 4 ? 4 : 8; 2995dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1)) 2996dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2997bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath GElf_Xword idx = 0; 2998dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (idx < phdr->p_filesz) 2999dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3000dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper uint64_t namesz; 3001dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper uint64_t descsz; 3002bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath uint64_t type; 3003bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath uint32_t namesz32; 3004dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper uint32_t descsz32; 3005dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3006dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (align == 4) 3007dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3008bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath uint32_t *ptr = (uint32_t *) (notemem + idx); 3009dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3010dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((__BYTE_ORDER == __LITTLE_ENDIAN 3011dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 3012dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper || (__BYTE_ORDER == __BIG_ENDIAN 3013dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 3014dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 30150a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard namesz32 = namesz = bswap_32 (*ptr); 30160a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ++ptr; 3017dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper descsz32 = descsz = bswap_32 (*ptr); 3018dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ++ptr; 3019dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper type = bswap_32 (*ptr); 3020dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3021dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 3022dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3023dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper namesz32 = namesz = *ptr++; 3024dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper descsz32 = descsz = *ptr++; 3025dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper type = *ptr; 3026dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3027dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3028dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 3029dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3030dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper uint64_t *ptr = (uint64_t *) (notemem + idx); 3031b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t *ptr32 = (uint32_t *) (notemem + idx); 3032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3033b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((__BYTE_ORDER == __LITTLE_ENDIAN 3034acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 3035acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper || (__BYTE_ORDER == __BIG_ENDIAN 3036b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 3037bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath { 3038b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz = bswap_64 (*ptr); 3039acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ++ptr; 3040acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper descsz = bswap_64 (*ptr); 3041acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ++ptr; 3042acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper type = bswap_64 (*ptr); 3043acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3044acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper namesz32 = bswap_32 (*ptr32); 3045acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ++ptr32; 3046acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper descsz32 = bswap_32 (*ptr32); 3047acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 3048acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper else 3049acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 3050acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper namesz = *ptr++; 3051dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper descsz = *ptr++; 3052dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper type = *ptr; 3053dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3054dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper namesz32 = *ptr32++; 3055dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper descsz32 = *ptr32; 3056dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3057dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3058dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3059dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (idx + 3 * align > phdr->p_filesz 30609d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard || (idx + 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz) 3061dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper > phdr->p_filesz)) 30629d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard { 30639d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard if (ehdr->e_ident[EI_CLASS] == ELFCLASS64 3064dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && idx + 3 * 4 <= phdr->p_filesz 3065dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && (idx + 3 * 4 + ALIGNED_LEN (namesz32) + ALIGNED_LEN (descsz32) 3066dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper <= phdr->p_filesz)) 3067dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3068dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperphdr[%d]: note entries probably in form of a 32-bit ELF file\n"), cnt); 3069dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 3070dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("phdr[%d]: extra %zu bytes after last note\n"), 3071dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, (size_t) (phdr->p_filesz - idx)); 3072dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3073dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3074dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3075dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Make sure it is one of the note types we know about. */ 3076dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (ehdr->e_type == ET_CORE) 3077dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3078dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper switch (type) 30790a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 30800a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard case NT_PRSTATUS: 3081dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_FPREGSET: 30820a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard case NT_PRPSINFO: 30830a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard case NT_TASKSTRUCT: /* NT_PRXREG on Solaris. */ 30840a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard case NT_PLATFORM: 3085dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_AUXV: 3086dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_GWINDOWS: 3087dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_ASRS: 3088dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_PSTATUS: 3089dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_PSINFO: 3090dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_PRCRED: 3091dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_UTSNAME: 3092dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_LWPSTATUS: 3093dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_LWPSINFO: 3094dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper case NT_PRFPXREG: 3095dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Known type. */ 3096dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3097bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath 3098dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper default: 3099dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3100dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperphdr[%d]: unknown core file note type %" PRIu64 " at offset %" PRIu64 "\n"), 3101dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, type, idx); 3102dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3103dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3104dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 3105dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3106dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (type != NT_VERSION) 3107dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3108dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperphdr[%d]: unknown object file note type %" PRIu64 " at offset %" PRIu64 "\n"), 3109dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, type, idx); 3110dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3111dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3112dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Move to the next entry. */ 3113dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx += 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz); 3114dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3115dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3116dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 31170a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard gelf_freechunk (ebl->elf, notemem); 31180a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard} 3119dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 31200a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 31210a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardstatic void 31220a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaardcheck_program_header (Ebl *ebl, GElf_Ehdr *ehdr) 3123dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 3124dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (ehdr->e_phoff == 0) 3125dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 3126dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3127dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 3128dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ehdr->e_type != ET_CORE) 3129dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3130dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperonly executables, shared objects, and core files can have program headers\n")); 3131dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3132dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int num_pt_interp = 0; 3133dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int num_pt_tls = 0; 3134dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int num_pt_relro = 0; 3135dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3136dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = 0; cnt < ehdr->e_phnum; ++cnt) 3137dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3138dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr phdr_mem; 3139dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr *phdr; 3140dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3141dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 3142dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (phdr == NULL) 3143dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3144dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("cannot get program header entry %d: %s\n"), 3145dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, elf_errmsg (-1)); 3146dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 3147dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3148dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3149dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME 3150dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO 3151dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check for a known machine-specific type. */ 3152dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL) 3153dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3154dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header entry %d: unknown program header entry type %#" PRIx64 "\n"), 3155dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, (uint64_t) phdr->p_type); 3156dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3157dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (phdr->p_type == PT_LOAD) 3158dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper has_loadable_segment = true; 3159dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (phdr->p_type == PT_INTERP) 3160dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3161dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (++num_pt_interp != 1) 3162dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 31630a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (num_pt_interp == 2) 31640a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 3165dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppermore than one INTERP entry in program header\n")); 31660a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 31670a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard has_interp_segment = true; 31680a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 31690a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard else if (phdr->p_type == PT_TLS) 31700a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 31710a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (++num_pt_tls == 2) 31720a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("more than one TLS entry in program header\n")); 31730a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard } 31740a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard else if (phdr->p_type == PT_NOTE) 31750a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard check_note (ebl, ehdr, phdr, cnt); 31760a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard else if (phdr->p_type == PT_DYNAMIC) 3177dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3178acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type == ET_EXEC && ! has_interp_segment) 3179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3180acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic executable cannot have dynamic sections\n")); 3181acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper else 3182acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 3183acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper /* Check that the .dynamic section, if it exists, has 3184acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper the same address. */ 3185acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Scn *scn = NULL; 3186acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 3187acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 3188acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr shdr_mem; 3189acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 3190acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 3191acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 3192acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (phdr->p_offset != shdr->sh_offset) 3193acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 3194acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperdynamic section reference in program header has wrong offset\n")); 3195acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (phdr->p_memsz != shdr->sh_size) 3196acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 3197acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperdynamic section size mismatch in program and section header\n")); 3198dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3199dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3200dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3201dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3202dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3203dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (phdr->p_type == PT_GNU_RELRO) 3204dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3205dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (++num_pt_relro == 2) 3206dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3207dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppermore than one GNU_RELRO entry in program header\n")); 3208dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 3209dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3210dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that the region is in a writable segment. */ 3211dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int inner; 3212dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (inner = 0; inner < ehdr->e_phnum; ++inner) 3213dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3214dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr phdr2_mem; 3215dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr *phdr2; 3216dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3217dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 3218dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (phdr2 == NULL) 3219dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 3220dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 32219d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard if (phdr2->p_type == PT_LOAD 3222dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr->p_vaddr >= phdr2->p_vaddr 32239d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard && (phdr->p_vaddr + phdr->p_memsz 32249d0926538635fe9a2bda0684623516aaf4407ecbMark Wielaard <= phdr2->p_vaddr + phdr2->p_memsz)) 3225dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3226dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((phdr2->p_flags & PF_W) == 0) 3227dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3228dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperloadable segment GNU_RELRO applies to is not writable\n")); 3229dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((phdr2->p_flags & PF_X) != 0) 3230dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3231dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperloadable segment GNU_RELRO applies to is executable\n")); 3232dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3233dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3234dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3235dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3236dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (inner >= ehdr->e_phnum) 3237dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3238dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper%s segment not contained in a loaded segment\n"), "GNU_RELRO"); 3239dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3240dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3241dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (phdr->p_type == PT_PHDR) 3242dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3243dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that the region is in a writable segment. */ 3244dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int inner; 3245dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (inner = 0; inner < ehdr->e_phnum; ++inner) 3246dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3247dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr phdr2_mem; 3248dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr *phdr2; 3249dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3250dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 3251dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (phdr2 != NULL 3252dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr2->p_type == PT_LOAD 3253dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr->p_vaddr >= phdr2->p_vaddr 3254dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && (phdr->p_vaddr + phdr->p_memsz 32550a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard <= phdr2->p_vaddr + phdr2->p_memsz)) 32560a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard break; 3257dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 32580a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 32590a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (inner >= ehdr->e_phnum) 32600a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard ERROR (gettext ("\ 3261dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper%s segment not contained in a loaded segment\n"), "PHDR"); 3262dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3263dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that offset in segment corresponds to offset in ELF 3264dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper header. */ 3265dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (phdr->p_offset != ehdr->e_phoff) 3266dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3267dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header offset in ELF header and PHDR entry do not match")); 3268dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3269dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3270dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (phdr->p_filesz > phdr->p_memsz) 3271dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3272dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header entry %d: file size greater than memory size\n"), 3273dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt); 3274dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3275dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (phdr->p_align > 1) 3276dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3277dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (!powerof2 (phdr->p_align)) 3278dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3279dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header entry %d: alignment not a power of 2\n"), cnt); 3280dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0) 3281dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3282dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprogram header entry %d: file offset and virtual address not module of alignment\n"), cnt); 3283dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3284dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3285dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 3286dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3287dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3288dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper/* Process one file. */ 3289dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic void 3290dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperprocess_elf_file (Elf *elf, const char *prefix, const char *suffix, 3291dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *fname, size_t size, bool only_one) 32926247d634c33be4c9ee4bfc650bb8f06f5add41e5Ulrich Drepper{ 3293dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Reset variables. */ 3294dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ndynamic = 0; 3295dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nverneed = 0; 3296dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nverdef = 0; 3297dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper textrel = false; 3298dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper needed_textrel = false; 3299dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper has_loadable_segment = false; 3300dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper has_interp_segment = false; 3301dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3302dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Ehdr ehdr_mem; 3303c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 3304c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper Ebl *ebl; 33050a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 33060a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard /* Print the file name. */ 3307c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper if (!only_one) 33080a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard { 33090a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard if (prefix != NULL) 33100a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard printf ("\n%s(%s)%s:\n", prefix, fname, suffix); 3311c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper else 3312c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper printf ("\n%s:\n", fname); 3313c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper } 3314c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper 3315c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper if (ehdr == NULL) 3316c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper { 3317c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1)); 3318dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 3319dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3320dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3321dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ebl = ebl_openbackend (elf); 3322dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* If there is no appropriate backend library we cannot test 3323dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper architecture and OS specific features. Any encountered extension 3324dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper is an error. */ 3325dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3326dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Go straight by the gABI, check all the parts in turn. */ 3327dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_elf_header (ebl, ehdr, size); 3328dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3329dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check the program header. */ 3330dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_program_header (ebl, ehdr); 3331dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3332dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Next the section headers. It is OK if there are no section 3333dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper headers at all. */ 3334dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_sections (ebl, ehdr); 3335dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3336dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Report if no relocation section needed the text relocation flag. */ 3337dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (textrel && !needed_textrel) 3338dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("text relocation flag set but not needed\n")); 33390a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard 33400a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard /* Free the resources. */ 3341dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ebl_closebackend (ebl); 33420a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard} 33430a545e678f2c0605ba050b4f72080572ac7c8470Mark Wielaard