elflint.c revision c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Pedantic checking of ELF files compliance with gABI/psABI spec. 271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Copyright (C) 2001-2014 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2001. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of the GNU General Public License as published by 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the Free Software Foundation; either version 3 of the License, or 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard (at your option) any later version. 10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard GNU General Public License for more details. 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received a copy of the GNU General Public License 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h> 24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <byteswap.h> 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <endian.h> 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h> 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <gelf.h> 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <inttypes.h> 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <locale.h> 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 37b337b1fd5f3b3410fe522a690ccee70bce8519eeRoland McGrath#include <sys/stat.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/param.h> 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <elf-knowledge.h> 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <system.h> 42059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath#include "../libelf/libelfP.h" 43059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath#include "../libelf/common.h" 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "../libebl/libeblP.h" 45059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath#include "../libdw/libdwP.h" 46059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath#include "../libdwfl/libdwflP.h" 47059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath#include "../libdw/memory-access.h" 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program. */ 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state); 52fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address. */ 55fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ARGP_strict 300 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ARGP_gnuld 301 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions. */ 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] = 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "strict", ARGP_strict, NULL, 0, 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Be extremely strict, flag level 2 features."), 0 }, 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 }, 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 }, 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "gnu-ld", ARGP_gnuld, NULL, 0, 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Binary has been created with GNU ld and is therefore known to be \ 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperbroken in certain ways"), 0 }, 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, NULL, 0 } 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program. */ 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("\ 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperPedantic checking of ELF files compliance with gABI/psABI spec."); 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts. */ 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("FILE..."); 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler. */ 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions. */ 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp = 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper options, parse_opt, args_doc, doc, NULL, NULL, NULL 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Declarations of local functions. */ 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void process_file (int fd, Elf *elf, const char *prefix, 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *suffix, const char *fname, size_t size, 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool only_one); 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void process_elf_file (Elf *elf, const char *prefix, const char *suffix, 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one); 9659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathstatic void check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, 9759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath GElf_Shdr *shdr, int idx); 9859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Report an error. */ 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ERROR(str, args...) \ 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do { \ 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf (str, ##args); \ 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++error_count; \ 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } while (0) 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic unsigned int error_count; 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if we should perform very strict testing. */ 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool be_strict; 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if no message is to be printed if the run is succesful. */ 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool be_quiet; 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if binary is from strip -f, not a normal ELF file. */ 115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool is_debuginfo; 116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if binary is assumed to be generated with GNU ld. */ 118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool gnuld; 119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Index of section header string table. */ 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic uint32_t shstrndx; 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Array to count references in section groups. */ 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int *scnref; 125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 12671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek/* Numbers of sections and program headers. */ 12771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinekstatic unsigned int shnum; 12871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinekstatic unsigned int phnum; 12971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[]) 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set locale. */ 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper setlocale (LC_ALL, ""); 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Initialize the message catalog. */ 138b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper textdomain (PACKAGE_TARNAME); 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Parse and process arguments. */ 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int remaining; 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_parse (&argp, argc, argv, 0, &remaining, NULL); 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Before we start tell the ELF library which version we are using. */ 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_version (EV_CURRENT); 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now process all the files given at the command line. */ 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool only_one = remaining + 1 == argc; 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Open the file. */ 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fd = open (argv[remaining], O_RDONLY); 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fd == -1) 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("cannot open input file")); 156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create an `Elf' descriptor. */ 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf == NULL) 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot generate Elf descriptor: %s\n"), 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int prev_error_count = error_count; 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct stat64 st; 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fstat64 (fd, &st) != 0) 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("cannot stat '%s': %m\n", argv[remaining]); 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size, 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper only_one); 178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now we can close the descriptor. */ 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (elf) != 0) 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("error while closing Elf descriptor: %s\n"), 182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prev_error_count == error_count && !be_quiet) 185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper puts (gettext ("No errors")); 186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (++remaining < argc); 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return error_count != 0; 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments. */ 197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt (int key, char *arg __attribute__ ((unused)), 199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct argp_state *state __attribute__ ((unused))) 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_strict: 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper be_strict = true; 205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'q': 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper be_quiet = true; 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'd': 212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is_debuginfo = true; 213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_gnuld: 215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gnuld = true; 216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_KEY_NO_ARGS: 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fputs (gettext ("Missing file name.\n"), stderr); 2205ee720c60a298352b52513d03ede85814ab63ad5Ulrich Drepper argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name); 2215ee720c60a298352b52513d03ede85814ab63ad5Ulrich Drepper exit (EXIT_FAILURE); 222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information. */ 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 234b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("\ 236b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCopyright (C) %s Red Hat, Inc.\n\ 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions. There is NO\n\ 238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 2393a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper"), "2012"); 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Process one file. */ 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_file (int fd, Elf *elf, const char *prefix, const char *suffix, 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one) 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We can handle two types of files: ELF files and archives. */ 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Kind kind = elf_kind (elf); 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (kind) 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_ELF: 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Yes! It's an ELF file. */ 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_elf_file (elf, prefix, suffix, fname, size, only_one); 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_AR: 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *subelf; 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Cmd cmd = ELF_C_READ_MMAP; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t fname_len = strlen (fname) + 1; 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_prefix[prefix_len + 1 + fname_len]; 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2]; 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = new_prefix; 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the full name of the file. */ 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, prefix, prefix_len); 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = '('; 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper strcpy (stpcpy (new_suffix, suffix), ")"); 275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_suffix[0] = '\0'; 278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (cp, fname, fname_len); 279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* It's an archive. We process each file in it. */ 281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper kind = elf_kind (subelf); 284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Call this function recursively. */ 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (kind == ELF_K_ELF || kind == ELF_K_AR) 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Arhdr *arhdr = elf_getarhdr (subelf); 289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (arhdr != NULL); 290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_file (fd, subelf, new_prefix, new_suffix, 292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arhdr->ar_name, arhdr->ar_size, false); 293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get next archive element. */ 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cmd = elf_next (subelf); 297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (subelf) != 0) 298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"), 299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We cannot do anything. */ 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 30741de488a0ad6679e816dbab960351e5f62ab8eadUlrich DrepperNot an ELF file - it has the wrong magic bytes at the start\n")); 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char * 314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_name (Ebl *ebl, int idx) 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr; 31871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek const char *ret; 31971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 32071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if ((unsigned int) idx > shnum) 32171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek return "<invalid>"; 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem); 32471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (shdr == NULL) 32571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek return "<invalid>"; 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 32771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 32871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (ret == NULL) 32971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek return "<invalid>"; 33071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek return ret; 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const int valid_e_machine[] = 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370, 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC, 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM, 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300, 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE, 341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16, 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7, 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX, 344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM, 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300, 346257dcf47ed0cf57bcd2ad225cc7aaa6a8dfeb2abJeff Kenton EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA, 34798c8a7395b4e5e7bed233397148b15c1f8c66490Petr Machata EM_TILEGX, EM_TILEPRO, EM_AARCH64 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define nvalid_e_machine \ 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size) 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[512]; 357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check e_ident field. */ 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG0] != ELFMAG0) 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0); 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG1] != ELFMAG1) 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1); 364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG2] != ELFMAG2) 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2); 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG3] != ELFMAG3) 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3); 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_CLASS] != ELFCLASS32 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_CLASS] != ELFCLASS64) 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%d] == %d is no known class\n"), 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_CLASS, ehdr->e_ident[EI_CLASS]); 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] != ELFDATA2MSB) 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"), 377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_DATA, ehdr->e_ident[EI_DATA]); 378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) 380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"), 381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_VERSION, ehdr->e_ident[EI_VERSION]); 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 38396d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper /* We currently don't handle any OS ABIs other than Linux. */ 38496d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE 38596d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper && ehdr->e_ident[EI_OSABI] != ELFOSABI_LINUX) 386e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"), 387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_OSABI, 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No ABI versions other than zero supported either. */ 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_ABIVERSION] != 0) 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unsupport ABI version e_ident[%d] == %d\n"), 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]); 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt) 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[cnt] != 0) 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt); 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_type field. */ 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE) 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type); 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_machine field. */ 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 0; cnt < nvalid_e_machine; ++cnt) 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (valid_e_machine[cnt] == ehdr->e_machine) 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == nvalid_e_machine) 409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine); 410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_version field. */ 412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_version != EV_CURRENT) 413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown object file version\n")); 414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_phoff and e_phnum fields. */ 416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phoff == 0) 417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phnum != 0) 419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header offset\n")); 420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) 421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperexecutables and DSOs cannot have zero program header offset\n")); 423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_phnum == 0) 425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid number of program header entries\n")); 426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_shoff field. */ 428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shnum = ehdr->e_shnum; 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shstrndx = ehdr->e_shstrndx; 430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shoff == 0) 431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shnum != 0) 433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header table offset\n")); 434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_CORE) 436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section header table must be present\n")); 437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shnum == 0) 441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the header of the zeroth section. The sh_size field 443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might contain the section number. */ 444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 445acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr != NULL) 447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The error will be reported later. */ 449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size == 0) 450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperinvalid number of section header table entries\n")); 452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shnum = shdr->sh_size; 454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shstrndx == SHN_XINDEX) 458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the header of the zeroth section. The sh_size field 460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might contain the section number. */ 461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 462acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 463acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (shdr != NULL && shdr->sh_link < shnum) 464acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper shstrndx = shdr->sh_link; 465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (shstrndx >= shnum) 467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header index\n")); 468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 470bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath phnum = ehdr->e_phnum; 471bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (ehdr->e_phnum == PN_XNUM) 472bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath { 473bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath /* Get the header of the zeroth section. The sh_info field 474bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath might contain the phnum count. */ 475bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath GElf_Shdr shdr_mem; 476bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 477bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (shdr != NULL) 478bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath { 479bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath /* The error will be reported later. */ 480bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (shdr->sh_info < PN_XNUM) 481bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ERROR (gettext ("\ 482bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrathinvalid number of program header table entries\n")); 483bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath else 484bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath phnum = shdr->sh_info; 485bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath } 486bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath } 487bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath 488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_flags field. */ 489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!ebl_machine_flag_check (ebl, ehdr->e_flags)) 490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid machine flags: %s\n"), 491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check e_ehsize, e_phentsize, and e_shentsize fields. */ 494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gelf_getclass (ebl->elf) == ELFCLASS32) 495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr)) 497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr)) 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header size: %hd\n"), 501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_phentsize); 502bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size) 503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header position or size\n")); 504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr)) 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header size: %hd\n"), 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_shentsize); 508bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath else if (ehdr->e_shoff + shnum * ehdr->e_shentsize > size) 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header position or size\n")); 510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (gelf_getclass (ebl->elf) == ELFCLASS64) 512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr)) 514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr)) 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header size: %hd\n"), 518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_phentsize); 519bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size) 520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header position or size\n")); 521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr)) 523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header size: %hd\n"), 524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_shentsize); 525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header position or size\n")); 527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check that there is a section group section with index < IDX which 532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper contains section IDX and that there is exactly one. */ 533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_scn_group (Ebl *ebl, int idx) 535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnref[idx] == 0) 537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No reference so far. Search following sections, maybe the 539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper order is wrong. */ 540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = idx + 1; cnt < shnum; ++cnt) 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 544acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Scn *scn = elf_getscn (ebl->elf, cnt); 545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 546acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We cannot get the section header so we cannot check it. 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper The error to get the section header will be shown 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper somewhere else. */ 551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type != SHT_GROUP) 554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 556acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL || data->d_size < sizeof (Elf32_Word)) 558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cannot check the section. */ 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 561acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf32_Word *grpdata = (Elf32_Word *) data->d_buf; 562acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word); 563acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ++inner) 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (grpdata[inner] == (Elf32_Word) idx) 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto out; 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out: 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == shnum) 570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"), 572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 5753b495d8e963eead963a37b5be5b063c96bb58c63Roland McGrathsection [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"), 576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 583dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool no_xndx_warned = false; 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int no_pt_tls = 0; 587dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 595dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr strshdr_mem; 596dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 597dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper &strshdr_mem); 598dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (strshdr == NULL) 599dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 600dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 602521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 603521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 604521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr->sh_link, section_name (ebl, shdr->sh_link), 605521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath idx, section_name (ebl, idx)); 606521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath strshdr = NULL; 607521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Search for an extended section index table section. */ 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *xndxdata = NULL; 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndxscnidx = 0; 612acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper bool found_xndx = false; 6133cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper for (size_t cnt = 1; cnt < shnum; ++cnt) 614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt != (size_t) idx) 615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt); 617acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr xndxshdr_mem; 618acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); 619acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (xndxshdr == NULL) 620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && xndxshdr->sh_link == (GElf_Word) idx) 624acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 625acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (found_xndx) 626acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 627acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': symbol table cannot have more than one extended index section\n"), 628acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 629acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 630acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper xndxdata = elf_getdata (xndxscn, NULL); 631acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper xndxscnidx = elf_ndxscn (xndxscn); 632acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper found_xndx = true; 633acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 63671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT); 63771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (shdr->sh_entsize != sh_entsize) 638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 6393cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Dreppersection [%2u] '%s': entry size is does not match ElfXX_Sym\n"), 6403cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper idx, section_name (ebl, idx)); 641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Test the zeroth entry. */ 643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym_mem; 644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndx; 645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx); 646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"), 648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 0, elf_errmsg (-1)); 649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_name != 0) 652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_name"); 654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value != 0) 655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_value"); 657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_size != 0) 658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_size"); 660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_info != 0) 661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_info"); 663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_other != 0) 664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_other"); 666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != 0) 667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_shndx"); 669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxdata != NULL && xndx != 0) 670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': XINDEX for zeroth entry not zero\n"), 672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndxscnidx, section_name (ebl, xndxscnidx)); 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 67571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek for (size_t cnt = 1; cnt < shdr->sh_size / sh_entsize; ++cnt) 676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx); 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"), 681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name = NULL; 686521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (strshdr == NULL) 687521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath name = ""; 688521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath else if (sym->st_name >= strshdr->sh_size) 689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: invalid name value\n"), 691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name); 69571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek assert (name != NULL 69671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek || strshdr->sh_type != SHT_STRTAB); 697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx == SHN_XINDEX) 700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxdata == NULL) 702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 703fd992543185126eb0280c1ee0883e073020499b4Roland McGrath if (!no_xndx_warned) 704fd992543185126eb0280c1ee0883e073020499b4Roland McGrath ERROR (gettext ("\ 705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"), 706fd992543185126eb0280c1ee0883e073020499b4Roland McGrath idx, section_name (ebl, idx), cnt); 707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper no_xndx_warned = true; 708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (xndx < SHN_LORESERVE) 710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"), 712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndxscnidx, section_name (ebl, xndxscnidx), cnt, 713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndx); 714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((sym->st_shndx >= SHN_LORESERVE 716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // && sym->st_shndx <= SHN_HIRESERVE always true 717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym->st_shndx != SHN_ABS 718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym->st_shndx != SHN_COMMON) 719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (sym->st_shndx >= shnum 720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (sym->st_shndx < SHN_LORESERVE 721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* || sym->st_shndx > SHN_HIRESERVE always false */))) 722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: invalid section index\n"), 724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndx = sym->st_shndx; 727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 72818e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath if (GELF_ST_TYPE (sym->st_info) >= STT_NUM 72918e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0)) 730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"), 731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 73396d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper if (GELF_ST_BIND (sym->st_info) >= STB_NUM 73496d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper && !ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), NULL, 73596d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper 0)) 736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: unknown symbol binding\n"), 738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 73996d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper if (GELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE 74096d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) 74196d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper ERROR (gettext ("\ 74296d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Dreppersection [%2d] '%s': symbol %zu: unique symbol not of object type\n"), 74396d950e3e28d89469b62b46d5a014ad1260e6a1aUlrich Drepper idx, section_name (ebl, idx), cnt); 744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndx == SHN_COMMON) 746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Common symbols can only appear in relocatable files. */ 748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"), 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt < shdr->sh_info) 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"), 755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_R_TYPE (sym->st_info) == STT_FUNC) 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"), 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (xndx > 0 && xndx < shnum) 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr destshdr_mem; 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *destshdr; 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem); 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (destshdr != NULL) 768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 769b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper GElf_Addr sh_addr = (ehdr->e_type == ET_REL ? 0 770b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper : destshdr->sh_addr); 771c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard GElf_Addr st_value; 772c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard if (GELF_ST_TYPE (sym->st_info) == STT_FUNC 773c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard || (GELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)) 774c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard st_value = sym->st_value & ebl_func_addr_mask (ebl); 775c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard else 776c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard st_value = sym->st_value; 777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_TYPE (sym->st_info) != STT_TLS) 778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 779c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (! ebl_check_special_symbol (ebl, ehdr, sym, name, 780c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper destshdr)) 781c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper { 782c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard if (st_value - sh_addr > destshdr->sh_size) 783ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper { 784ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper /* GNU ld has severe bugs. When it decides to remove 785ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper empty sections it leaves symbols referencing them 7863bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard behind. These are symbols in .symtab or .dynsym 7873bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard and for the named symbols have zero size. See 7883bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard sourceware PR13621. */ 789ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper if (!gnuld 7903bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard || (strcmp (section_name (ebl, idx), ".symtab") 7913bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard && strcmp (section_name (ebl, idx), 7923bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard ".dynsym")) 7933bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard || sym->st_size != 0 794ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper || (strcmp (name, "__preinit_array_start") != 0 795ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__preinit_array_end") != 0 796ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__init_array_start") != 0 797ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__init_array_end") != 0 798ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__fini_array_start") != 0 7993bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard && strcmp (name, "__fini_array_end") != 0 8003bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard && strcmp (name, "__bss_start") != 0 801b94cceae503b56fb360cd597f154fa2b33552887Mark Wielaard && strcmp (name, "__bss_start__") != 0 8023bdc16ce98295463c071192eab2ec611a8edc508Mark Wielaard && strcmp (name, "__TMC_END__") != 0)) 803ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper ERROR (gettext ("\ 804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds\n"), 805ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper idx, section_name (ebl, idx), cnt); 806ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper } 807c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard else if ((st_value - sh_addr 808c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper + sym->st_size) > destshdr->sh_size) 809c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 811c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), cnt, 812c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (int) xndx, section_name (ebl, xndx)); 813c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 814b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 815b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((destshdr->sh_flags & SHF_TLS) == 0) 818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"), 820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL) 824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* For object files the symbol value must fall 826c49d00afc4bda21181cd4237e67930f3f5228adfMark Wielaard into the section. */ 827c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard if (st_value > destshdr->sh_size) 828b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 832c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard else if (st_value + sym->st_size 833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > destshdr->sh_size) 834b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr = NULL; 843bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath unsigned int pcnt; 844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 845bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (pcnt = 0; pcnt < phnum; ++pcnt) 846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 847b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr != NULL && phdr->p_type == PT_TLS) 849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 852bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (pcnt == phnum) 853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (no_pt_tls++ == 0) 855b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 856b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"), 857b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 858b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 860b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 861c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard if (st_value 862b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < destshdr->sh_offset - phdr->p_offset) 863b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 864b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"), 865b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 866b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 867c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard else if (st_value 868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > (destshdr->sh_offset - phdr->p_offset 869b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + destshdr->sh_size)) 870b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 873b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 874c1c1c06e30f0b3b4ae66fcfec6318a93b8f31569Mark Wielaard else if (st_value + sym->st_size 875b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > (destshdr->sh_offset - phdr->p_offset 876b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + destshdr->sh_size)) 877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 882b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 883b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 887b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt >= shdr->sh_info) 890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"), 892b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 893b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 894b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 895b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 896b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt < shdr->sh_info) 897b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"), 899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_TYPE (sym->st_info) == STT_SECTION 903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local section symbol\n"), 906b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 908b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (name != NULL) 909b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 910b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 912653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* Check that address and size match the global offset table. */ 913653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 914653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Shdr destshdr_mem; 915653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), 916653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath &destshdr_mem); 917653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 918653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr == NULL && xndx == SHN_ABS) 919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 920653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* In a DSO, we have to find the GOT section by name. */ 921653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath Elf_Scn *gotscn = NULL; 922c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper Elf_Scn *gscn = NULL; 923653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL) 924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 925653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = gelf_getshdr (gscn, &destshdr_mem); 926653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath assert (destshdr != NULL); 927653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const char *sname = elf_strptr (ebl->elf, 928653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ehdr->e_shstrndx, 929653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr->sh_name); 930653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (sname != NULL) 931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 932c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (sname, ".got.plt") == 0) 933653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath break; 934c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (sname, ".got") == 0) 935653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* Do not stop looking. 936653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath There might be a .got.plt section. */ 937653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath gotscn = gscn; 938b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 939653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 940653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = NULL; 941b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 942653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 943653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr == NULL && gotscn != NULL) 944653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = gelf_getshdr (gotscn, &destshdr_mem); 945b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 947b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper const char *sname = ((destshdr == NULL || xndx == SHN_UNDEF) 948b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper ? NULL 949653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath : elf_strptr (ebl->elf, ehdr->e_shstrndx, 950653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr->sh_name)); 951653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (sname == NULL) 952b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { 953b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (xndx != SHN_UNDEF || ehdr->e_type != ET_REL) 954b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper ERROR (gettext ("\ 955b597dfad924980dede10d7c19d87900b6172e599Ulrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \ 956b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepperbad section [%2d]\n"), 957b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper idx, section_name (ebl, idx), xndx); 958b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper } 959653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath else if (strcmp (sname, ".got.plt") != 0 960653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath && strcmp (sname, ".got") != 0) 961653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ERROR (gettext ("\ 962b597dfad924980dede10d7c19d87900b6172e599Ulrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \ 963b597dfad924980dede10d7c19d87900b6172e599Ulrich Dreppersection [%2d] '%s'\n"), 964b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper idx, section_name (ebl, idx), xndx, sname); 965653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 966653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr != NULL) 967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found it. */ 969c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (!ebl_check_special_symbol (ebl, ehdr, sym, name, 970c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper destshdr)) 971c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper { 972b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (ehdr->e_type != ET_REL 973b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper && sym->st_value != destshdr->sh_addr) 974c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper /* This test is more strict than the psABIs which 975c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper usually allow the symbol to be in the middle of 976c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper the .got section, allowing negative offsets. */ 977c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 978653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"), 979c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), 980c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (uint64_t) sym->st_value, 981c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper sname, (uint64_t) destshdr->sh_addr); 982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 983c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (!gnuld && sym->st_size != destshdr->sh_size) 984c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 985653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"), 986c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), 987c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (uint64_t) sym->st_size, 988c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper sname, (uint64_t) destshdr->sh_size); 989c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 991b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 992b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 993b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"), 994b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 995b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 996b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (strcmp (name, "_DYNAMIC") == 0) 99741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Check that address and size match the dynamic section. 99841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper We locate the dynamic section via the program header 99941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper entry. */ 1000bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt) 100141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 100241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr phdr_mem; 100341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 1004b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 100541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 100641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 100741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (sym->st_value != phdr->p_vaddr) 100841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 1009b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"), 101041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), 101141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) sym->st_value, 101241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) phdr->p_vaddr); 1013b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 101441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (!gnuld && sym->st_size != phdr->p_memsz) 101541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 1016b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"), 101741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), 101841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) sym->st_size, 101941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) phdr->p_memsz); 1020b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 102141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 102241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 1023b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1024b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1025c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper 1026c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper if (GELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT 1027c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper && shdr->sh_type == SHT_DYNSYM) 1028c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper ERROR (gettext ("\ 1029c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Dreppersection [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-default visibility\n"), 1030c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper idx, section_name (ebl, idx), cnt); 1031a062b6bcadd1565d360acf640f9d4c159b2270eaMark Wielaard if (! ebl_check_st_other_bits (ebl, sym->st_other)) 1032c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper ERROR (gettext ("\ 1033c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Dreppersection [%2d] '%s': symbol %zu: unknown bit set in st_other\n"), 1034c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper idx, section_name (ebl, idx), cnt); 1035c803fbe6c3fa15d08dee1c99948ec66326db1e9eUlrich Drepper 1036b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1037b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1038b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1039b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1040b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool 1041c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperis_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr, 104228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper bool is_rela) 1043b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1044b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If this is no executable or DSO it cannot be a .rel.dyn section. */ 1045b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1046b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 1047b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1048b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the section name. Unfortunately necessary. */ 104928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn")) 1050b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 1051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1052b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section 1053b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper entry can be present as well. */ 1054b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 1055b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1056b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1057b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr rcshdr_mem; 1058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem); 1059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 106071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (rcshdr == NULL) 106171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek break; 106271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 106371c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize) 1064b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1065b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found the dynamic section. Look through it. */ 1066b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *d = elf_getdata (scn, NULL); 1067b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 1068b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1069b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt) 1070b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1071b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn dyn_mem; 1072b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem); 107371c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek 107471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (dyn == NULL) 107571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek break; 1076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1077b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_RELCOUNT) 1078b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 107928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Found it. Does the type match. */ 108028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (is_rela) 1081b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 108228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELCOUNT used for this RELA section\n"), 108328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 108428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 108528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 108628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Does the number specified number of relative 108728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations exceed the total number of 108828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations? */ 108971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (shdr->sh_entsize != 0 109071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek && dyn->d_un.d_val > (shdr->sh_size 109171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek / shdr->sh_entsize)) 109228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 1093b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 109428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 109528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 109628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 109728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Make sure the specified number of relocations are 109828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relative. */ 109928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, 110028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx), NULL); 110128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (reldata != NULL) 110228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (size_t inner = 0; 110328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner < shdr->sh_size / shdr->sh_entsize; 110428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++inner) 110528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 110628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rel rel_mem; 110728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rel *rel = gelf_getrel (reldata, inner, 110828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper &rel_mem); 110928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (rel == NULL) 111028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The problem will be reported elsewhere. */ 111128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 111228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 111328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_relative_reloc_p (ebl, 111428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GELF_R_TYPE (rel->r_info))) 111528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 111628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (inner >= dyn->d_un.d_val) 111728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 111828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), 111928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 112028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 112128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 112228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (inner < dyn->d_un.d_val) 112328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 112428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), 112528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 112628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner, (int) dyn->d_un.d_val); 112728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 112828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 112928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 113028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 113128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn->d_tag == DT_RELACOUNT) 113228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 113328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Found it. Does the type match. */ 113428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (!is_rela) 113528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 113628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELACOUNT used for this REL section\n"), 113728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 113828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 113928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 114028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Does the number specified number of relative 114128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations exceed the total number of 114228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations? */ 114328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 114428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 114528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 114628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 114728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 114828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 114928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Make sure the specified number of relocations are 115028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relative. */ 115128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, 115228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx), NULL); 115328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (reldata != NULL) 115428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (size_t inner = 0; 115528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner < shdr->sh_size / shdr->sh_entsize; 115628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++inner) 115728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 115828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rela rela_mem; 115928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rela *rela = gelf_getrela (reldata, inner, 116028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper &rela_mem); 116128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (rela == NULL) 116228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The problem will be reported elsewhere. */ 116328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 116428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 116528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_relative_reloc_p (ebl, 116628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GELF_R_TYPE (rela->r_info))) 116728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 116828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (inner >= dyn->d_un.d_val) 116928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 117028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), 117128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 117228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 117328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 117428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (inner < dyn->d_un.d_val) 117528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 117628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), 117728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 117828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner, (int) dyn->d_un.d_val); 117928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 118028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 1181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 1189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 119241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstruct loaded_segment 119341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper{ 119441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Addr from; 119541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Addr to; 119641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper bool read_only; 119741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *next; 119841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper}; 119941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 120041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 120141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper/* Check whether binary has text relocation flag set. */ 120241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool textrel; 120341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 120441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper/* Keep track of whether text relocation flag is needed. */ 120541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool needed_textrel; 120641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 120741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1208c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic bool 1209c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr, 1210c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper int idx, int reltype, GElf_Shdr **destshdrp, 121141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp) 1212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool reldyn = false; 1214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether the link to the section we relocate is reasonable. */ 1216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info >= shnum) 1217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), 1218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1219c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper else if (shdr->sh_info != 0) 1220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1221c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1222c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper destshdr_memp); 1223c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (*destshdrp != NULL) 1224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1225028d0ab0cc1cb5f96ee48feef966b7d8d56c6a8eMark Wielaard if(! ebl_check_reloc_target_type (ebl, (*destshdrp)->sh_type)) 1226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); 1228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!reldyn) 1229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': invalid destination section type\n"), 1231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1234c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* There is no standard, but we require that .rel{,a}.dyn 1235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sections have a sh_info value of zero. */ 1236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': sh_info should be zero\n"), 1239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1243c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) 1244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': no relocations for merge-able sections possible\n"), 1246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 125071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT); 125171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (shdr->sh_entsize != sh_entsize) 1252c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext (reltype == ELF_T_RELA ? "\ 1253c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ 1254c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rel\n"), 1255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 125741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* In preparation of checking whether relocations are text 125841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper relocations or not we need to determine whether the file is 125941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper flagged to have text relocation and we need to determine a) what 126041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper the loaded segments are and b) which are read-only. This will 126141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper also allow us to determine whether the same reloc section is 126241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper modifying loaded and not loaded segments. */ 1263bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (unsigned int i = 0; i < phnum; ++i) 126441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 126541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr phdr_mem; 126641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 126741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr == NULL) 126841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper continue; 126941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 127041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_type == PT_LOAD) 127141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 127241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *newp = xmalloc (sizeof (*newp)); 127341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->from = phdr->p_vaddr; 127441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->to = phdr->p_vaddr + phdr->p_memsz; 127541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->read_only = (phdr->p_flags & PF_W) == 0; 127641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->next = *loadedp; 127741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper *loadedp = newp; 127841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 127941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else if (phdr->p_type == PT_DYNAMIC) 128041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 128141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset); 128241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr dynshdr_mem; 128341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem); 128441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Data *dyndata = elf_getdata (dynscn, NULL); 128541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC 128641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && dyndata != NULL) 128741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j) 128841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 128941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Dyn dyn_mem; 129041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem); 129141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (dyn != NULL 129241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && (dyn->d_tag == DT_TEXTREL 129341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper || (dyn->d_tag == DT_FLAGS 129441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && (dyn->d_un.d_val & DF_TEXTREL) != 0))) 129541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 129641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper textrel = true; 129741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 129841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 129941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 130041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 130141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 130241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 130341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* A quick test which can be easily done here (although it is a bit 130441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper out of place): the text relocation flag makes only sense if there 130541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper is a segment which is not writable. */ 130641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (textrel) 130741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 130841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *seg = *loadedp; 130941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (seg != NULL && !seg->read_only) 131041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper seg = seg->next; 131141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (seg == NULL) 131241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 131341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppertext relocation flag set but there is no read-only segment\n")); 131441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 131541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1316c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper return reldyn; 1317c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper} 1318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 132041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperenum load_state 132141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 132241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_undecided, 132341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_loaded, 132441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_unloaded, 132541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_error 132641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper }; 132741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 132841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1329c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic void 1330607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppercheck_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx, 1331607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata, 1332607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Addr r_offset, GElf_Xword r_info, 133341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper const GElf_Shdr *destshdr, bool reldyn, 133441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded, enum load_state *statep) 1335c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper{ 1336c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool known_broken = gnuld; 1337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1338c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info))) 1339c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), 1340c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1341607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1342607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* The executable/DSO can contain relocation sections with 1343607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper all the relocations the linker has applied. Those sections 1344607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper are marked non-loaded, though. */ 1345607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper || (relshdr->sh_flags & SHF_ALLOC) != 0) 1346607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info))) 1347c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), 1349c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1351c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (symshdr != NULL 1352c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && ((GELF_R_SYM (r_info) + 1) 1353c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) 1354c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper > symshdr->sh_size)) 1355c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: invalid symbol index\n"), 1357c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 13596ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper /* No more tests if this is a no-op relocation. */ 13606ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper if (ebl_none_reloc_p (ebl, GELF_R_TYPE (r_info))) 13616ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper return; 13626ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper 1363c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info))) 1364c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1365c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper const char *name; 1366c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper char buf[64]; 1367c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Sym sym_mem; 1368c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 1369c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (sym != NULL 1370c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Get the name for the symbol. */ 1371c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) 1372c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) 1373c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), 1375c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt, 1376c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ebl_reloc_type_name (ebl, GELF_R_SYM (r_info), 1377c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper buf, sizeof (buf))); 1378c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1380c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (reldyn) 1381c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1382c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper // XXX TODO Check .rel.dyn section addresses. 1383c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1384c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper else if (!known_broken) 1385c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1386c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (destshdr != NULL 1387c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && GELF_R_TYPE (r_info) != 0 1388b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper && (r_offset - (ehdr->e_type == ET_REL ? 0 1389b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper : destshdr->sh_addr)) >= destshdr->sh_size) 1390c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: offset out of bounds\n"), 1392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1393c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 139541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Sym sym_mem; 139641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 139741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 139841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info)) 1399c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Make sure the referenced symbol is an object or unspecified. */ 140041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && sym != NULL 140141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE 140241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) 140341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 140441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper char buf[64]; 140541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), 140641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), cnt, 140741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 140841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper buf, sizeof (buf))); 140941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 141041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1411038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1412038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper || (relshdr->sh_flags & SHF_ALLOC) != 0) 141341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 1414038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper bool in_loaded_seg = false; 1415038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper while (loaded != NULL) 1416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1417038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (r_offset < loaded->to 1418038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from) 141941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 1420038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper /* The symbol is in this segment. */ 1421038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (loaded->read_only) 1422038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1423038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (textrel) 1424038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper needed_textrel = true; 1425038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper else 1426038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"), 1427038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx), cnt); 1428038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper } 1429038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper 1430038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper in_loaded_seg = true; 143141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 143241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1433038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper loaded = loaded->next; 1434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 143541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1436038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (*statep == state_undecided) 1437038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper *statep = in_loaded_seg ? state_loaded : state_unloaded; 1438038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper else if ((*statep == state_unloaded && in_loaded_seg) 1439038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper || (*statep == state_loaded && !in_loaded_seg)) 1440038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1441038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("\ 144241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': relocations are against loaded and unloaded data\n"), 1443038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx)); 1444038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper *statep = state_error; 1445038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper } 1446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1451c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1453c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1461c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Check the fields of the section header. */ 1462c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr destshdr_mem; 1463c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *destshdr = NULL; 146441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded = NULL; 1465c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr, 146641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper &destshdr_mem, &loaded); 1467c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1468c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1469c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr symshdr_mem; 1470c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1471c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 147241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper enum load_state state = state_undecided; 1473c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 147471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT); 147571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) 1476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1477c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rela rela_mem; 1478c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem); 1479c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (rela == NULL) 1480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1481c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1482c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"), 1483c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1484c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper continue; 1485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1486c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1487607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1488607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper rela->r_offset, rela->r_info, destshdr, reldyn, loaded, 1489607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper &state); 149041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 149141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 149241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 149341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 149441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *old = loaded; 149541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper loaded = loaded->next; 149641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper free (old); 1497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1498c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper} 1499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1500c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1501c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic void 1502c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1503c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper{ 1504c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1505c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (data == NULL) 1506c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1507c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1508c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx)); 1509c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper return; 1510c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1511c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1512c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Check the fields of the section header. */ 1513c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr destshdr_mem; 1514c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *destshdr = NULL; 151541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded = NULL; 1516c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr, 151741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper &destshdr_mem, &loaded); 1518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 1521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 152341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper enum load_state state = state_undecided; 1524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 152571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT); 152671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) 1527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel rel_mem; 1529c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem); 1530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rel == NULL) 1531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"), 1534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1538607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1539607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper rel->r_offset, rel->r_info, destshdr, reldyn, loaded, 1540607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper &state); 154141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 154241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 154341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 154441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 154541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *old = loaded; 154641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper loaded = loaded->next; 154741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper free (old); 1548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Number of dynamic sections. */ 1553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int ndynamic; 1554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1557607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppercheck_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data; 1560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr strshdr_mem; 1561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *strshdr; 1562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 1563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool dependencies[DT_NUM][DT_NUM] = 1564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_NEEDED] = { [DT_STRTAB] = true }, 1566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_PLTRELSZ] = { [DT_JMPREL] = true }, 1567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_HASH] = { [DT_SYMTAB] = true }, 1568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRTAB] = { [DT_STRSZ] = true }, 1569231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_SYMENT] = true }, 1570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true }, 1571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELASZ] = { [DT_RELA] = true }, 1572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELAENT] = { [DT_RELA] = true }, 1573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRSZ] = { [DT_STRTAB] = true }, 1574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMENT] = { [DT_SYMTAB] = true }, 1575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SONAME] = { [DT_STRTAB] = true }, 1576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RPATH] = { [DT_STRTAB] = true }, 1577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true }, 1578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELSZ] = { [DT_REL] = true }, 1579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELENT] = { [DT_REL] = true }, 1580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true }, 1581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RUNPATH] = { [DT_STRTAB] = true }, 1582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_PLTREL] = { [DT_JMPREL] = true }, 1583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool has_dt[DT_NUM]; 1585231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper bool has_val_dt[DT_VALNUM]; 1586231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper bool has_addr_dt[DT_ADDRNUM]; 1587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool level2[DT_NUM] = 1588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RPATH] = true, 1590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMBOLIC] = true, 1591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_TEXTREL] = true, 1592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_BIND_NOW] = true 1593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool mandatory[DT_NUM] = 1595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_NULL] = true, 1597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRTAB] = true, 1598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMTAB] = true, 1599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRSZ] = true, 1600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMENT] = true 1601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memset (has_dt, '\0', sizeof (has_dt)); 1604231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper memset (has_val_dt, '\0', sizeof (has_val_dt)); 1605231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper memset (has_addr_dt, '\0', sizeof (has_addr_dt)); 1606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++ndynamic == 2) 1608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("more than one dynamic section present\n")); 1609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 161041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem); 1619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB) 1620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 1622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link), 1623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 162571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT); 162671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (shdr->sh_entsize != sh_entsize) 1627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Dyn\n"), 1629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool non_null_warned = false; 163671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) 1637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn dyn_mem; 1639acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem); 1640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn == NULL) 1641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get dynamic section entry %zu: %s\n"), 1644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned) 1649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"), 1652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper non_null_warned = true; 1654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!ebl_dynamic_tag_check (ebl, dyn->d_tag)) 1657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"), 1658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM) 1661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[dyn->d_tag] 1663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_NEEDED 1664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_NULL 1665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_POSFLAG_1) 1666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: more than one entry with tag %s\n"), 1670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, 1672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf, sizeof (buf))); 1673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (be_strict && level2[dyn->d_tag]) 1676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: level 2 tag %s used\n"), 1680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, 1682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf, sizeof (buf))); 1683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_dt[dyn->d_tag] = true; 1686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1687231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper else if (dyn->d_tag <= DT_VALRNGHI 1688231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper && DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) 1689231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper has_val_dt[DT_VALTAGIDX (dyn->d_tag)] = true; 1690231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper else if (dyn->d_tag <= DT_ADDRRNGHI 1691231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper && DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) 1692231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper has_addr_dt[DT_ADDRTAGIDX (dyn->d_tag)] = true; 1693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL 1695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_un.d_val != DT_RELA) 1696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"), 1698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1700607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that addresses for entries are in loaded segments. */ 1701607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper switch (dyn->d_tag) 1702607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1703607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper size_t n; 1704cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_STRTAB: 1705cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper /* We require the referenced section is the same as the one 1706cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper specified in sh_link. */ 1707cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (strshdr->sh_addr != dyn->d_un.d_val) 1708cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper { 1709cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("\ 1710cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '%s' referenced by sh_link\n"), 1711cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), cnt, 1712cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 1713cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1714cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper } 1715cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper goto check_addr; 1716cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1717607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper default: 1718607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI) 1719607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Value is no pointer. */ 1720607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 1721607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* FALLTHROUGH */ 1722607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1723cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_AUXILIARY: 1724cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FILTER: 1725cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FINI: 1726cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FINI_ARRAY: 1727607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_HASH: 1728607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_INIT: 1729607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_INIT_ARRAY: 1730cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_JMPREL: 1731cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_PLTGOT: 1732cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_REL: 1733cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RELA: 1734cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SYMBOLIC: 1735cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SYMTAB: 1736607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_VERDEF: 1737607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_VERNEED: 1738cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_VERSYM: 1739cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper check_addr: 1740bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (n = 0; n < phnum; ++n) 1741607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1742607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr phdr_mem; 1743607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem); 1744607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr != NULL && phdr->p_type == PT_LOAD 1745607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr <= dyn->d_un.d_ptr 1746607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr) 1747607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 1748607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1749bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (unlikely (n >= phnum)) 1750607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1751607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper char buf[50]; 1752607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 1753607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': entry %zu: %s value must point into loaded segment\n"), 1754607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper idx, section_name (ebl, idx), cnt, 1755607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1756607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper sizeof (buf))); 1757607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1758cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1759cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1760cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_NEEDED: 1761cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RPATH: 1762cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RUNPATH: 1763cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SONAME: 1764cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (dyn->d_un.d_ptr >= strshdr->sh_size) 1765cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper { 1766cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper char buf[50]; 1767cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("\ 1768cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': entry %zu: %s value must be valid offset in section [%2d] '%s'\n"), 1769cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), cnt, 1770cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1771cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper sizeof (buf)), 1772cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 1773cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper } 1774cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1775607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < DT_NUM; ++cnt) 1779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[cnt]) 1780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1781acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (int inner = 0; inner < DT_NUM; ++inner) 1782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dependencies[cnt][inner] && ! has_dt[inner]) 1783b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1784b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf1[50]; 1785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf2[50]; 1786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': contains %s entry but not %s\n"), 1789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)), 1791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2))); 1792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (mandatory[cnt]) 1797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': mandatory tag %s not present\n"), 1801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf))); 1803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1806231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* Make sure we have an hash table. */ 1807231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_dt[DT_HASH] && !has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)]) 1808231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1809231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': no hash section present\n"), 1810231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1811231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1812231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* The GNU-style hash table also needs a symbol table. */ 1813231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_dt[DT_HASH] && has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)] 1814231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper && !has_dt[DT_SYMTAB]) 1815231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1816231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': contains %s entry but not %s\n"), 1817231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), 1818231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper "DT_GNU_HASH", "DT_SYMTAB"); 1819231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the rel/rela tags. At least one group must be available. */ 1821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT]) 1822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT])) 1823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper "DT_RELA", "DT_RELASZ", "DT_RELAENT"); 1827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1828b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT]) 1829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT])) 1830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper "DT_REL", "DT_RELSZ", "DT_RELENT"); 1834231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1835231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* Check that all prelink sections are present if any of them is. */ 1836231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)] 1837231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper || has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)]) 1838231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper { 1839231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)]) 1840231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1841231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in DSO marked during prelinking\n"), 1842231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_PRELINKED"); 1843231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)]) 1844231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1845231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in DSO marked during prelinking\n"), 1846231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_CHECKSUM"); 1847231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1848231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* Only DSOs can be marked like this. */ 1849231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (ehdr->e_type != ET_DYN) 1850231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1851231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': non-DSO file marked as dependency during prelink\n"), 1852231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1853231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1854231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1855231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)] 1856231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper || has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)] 1857231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)] 1858231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)]) 1859231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper { 1860231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)]) 1861231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1862231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in prelinked executable\n"), 1863231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_CONFLICTSZ"); 1864231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)]) 1865231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1866231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in prelinked executable\n"), 1867231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_LIBLISTSZ"); 1868231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)]) 1869231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1870231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in prelinked executable\n"), 1871231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_CONFLICT"); 1872231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)]) 1873231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1874231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in prelinked executable\n"), 1875231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_LIBLIST"); 1876231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1881acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1882b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1883acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type != ET_REL) 1884acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 1885acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 1886acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': only relocatable files can have extended section index\n"), 1887acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 1888acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 1889acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 1890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1891acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1892acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr symshdr_mem; 1893acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1894b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB) 1895b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1896b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended section index section not for symbol table\n"), 1897b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1898acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 1899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symdata == NULL) 1900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get data for symbol section\n")); 1901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != sizeof (Elf32_Word)) 1903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry size does not match Elf32_Word\n"), 1905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1906b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL 190871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek && shdr->sh_entsize 190971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek && symshdr->sh_entsize 1910b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_size / shdr->sh_entsize 1911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < symshdr->sh_size / symshdr->sh_entsize)) 1912b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1913b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended index table too small for symbol table\n"), 1914b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1920acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = idx + 1; cnt < shnum; ++cnt) 1921b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1922b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr rshdr_mem; 1923acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem); 1924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX 1925b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && rshdr->sh_link == shdr->sh_link) 1926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1928b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"), 1929b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1930b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 1931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1933b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1934b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1935acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 193671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (data == NULL) 193771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek { 193871c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 193971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek idx, section_name (ebl, idx)); 194071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek return; 194171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 1942b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1943b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (*((Elf32_Word *) data->d_buf) != 0) 1944b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("symbol 0 should have zero extended section index\n")); 1945b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1946acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1947b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1948b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt]; 1949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1950b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndx != 0) 1951b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym_data; 1953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data); 1954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 1955b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get data for symbol %zu\n"), cnt); 1957b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1958b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1960b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != SHN_XINDEX) 1961b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1962b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperextended section index is %" PRIu32 " but symbol index is not XINDEX\n"), 1963b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (uint32_t) xndx); 1964b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1965b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1966b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 197028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 197128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 197228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 197328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 197428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 197528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 197628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 197728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 197828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 197928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 198028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 198128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 198228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t maxidx = nchain; 198328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 198471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (symshdr != NULL && symshdr->sh_entsize != 0) 198528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 198628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 198728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 198828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (nchain > symshdr->sh_size / symshdr->sh_entsize) 198928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("section [%2d] '%s': chain array too large\n"), 199028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 199128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 199228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = symsize; 199328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 199428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 199571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Elf32_Word *buf = (Elf32_Word *) data->d_buf; 199671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Elf32_Word *end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size); 199728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 199828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (cnt = 2; cnt < 2 + nbucket; ++cnt) 199971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek { 200071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (buf + cnt >= end) 200171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek break; 200271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek else if (buf[cnt] >= maxidx) 200328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 200428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash bucket reference %zu out of bounds\n"), 200528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2); 200671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 200728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 200828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (; cnt < 2 + nbucket + nchain; ++cnt) 200971c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek { 201071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (buf + cnt >= end) 201171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek break; 201271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek else if (buf[cnt] >= maxidx) 201328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 201428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain reference %zu out of bounds\n"), 201528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2 - nbucket); 201671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 201728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 201828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 201928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 202028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 202128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 202228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 202328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 202428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; 202528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; 202628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 202728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 202828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 202928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 203028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 203128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 203228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 203328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t maxidx = nchain; 203428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 203528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL) 203628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 203728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 203828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 203928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (nchain > symshdr->sh_size / symshdr->sh_entsize) 204028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("section [%2d] '%s': chain array too large\n"), 204128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 204228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 204328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = symsize; 204428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 204528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 204671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Elf64_Xword *buf = (Elf64_Xword *) data->d_buf; 204771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek Elf64_Xword *end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size); 204828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 204928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (cnt = 2; cnt < 2 + nbucket; ++cnt) 205071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek { 205171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (buf + cnt >= end) 205271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek break; 205371c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek else if (buf[cnt] >= maxidx) 205428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 205528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash bucket reference %zu out of bounds\n"), 205628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2); 205771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 205828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 205928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (; cnt < 2 + nbucket + nchain; ++cnt) 206071c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek { 206171c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (buf + cnt >= end) 206271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek break; 206371c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek else if (buf[cnt] >= maxidx) 206428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 2065dcf6160602985e6eb70c96c6546ed9614a414d98Ulrich Dreppersection [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"), 206671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek idx, section_name (ebl, idx), (uint64_t) cnt - 2 - nbucket); 206771c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek } 206828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 206928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 207028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 207128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 207228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 207328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 207428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 207528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0]; 207628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; 20778ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; 207828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 20798ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (!powerof2 (bitmask_words)) 20808ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 20818ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': bitmask size not power of 2: %u\n"), 20828ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), bitmask_words); 20838ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 20848ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t bitmask_idxmask = bitmask_words - 1; 20858ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (gelf_getclass (ebl->elf) == ELFCLASS64) 20868ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper bitmask_words *= 2; 20878ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; 20888ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 20898ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shdr->sh_size < (4 + bitmask_words + nbuckets) * sizeof (Elf32_Word)) 209028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 209128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 209271c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelineksection [%2d] '%s': hash table section is too small (is %ld, expected at least %ld)\n"), 209328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 20948ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper (long int) ((4 + bitmask_words + nbuckets) * sizeof (Elf32_Word))); 209528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return; 209628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 209728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 20988ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shift > 31) 20998ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 21008ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': 2nd hash function shift too big: %u\n"), 21018ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), shift); 21028ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 21038ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words 21048ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + nbuckets); 210528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 210628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL) 210728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize); 210828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 210928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* We need the symbol section data. */ 211028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL); 211128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 21128ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper union 21138ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 21148ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word *p32; 21158ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf64_Xword *p64; 21168ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } bitmask = { .p32 = &((Elf32_Word *) data->d_buf)[4] }, 21178ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected = { .p32 = xcalloc (bitmask_words, sizeof (Elf32_Word)) }; 21188ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 21198ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t classbits = gelf_getclass (ebl->elf) == ELFCLASS32 ? 32 : 64; 21208ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 212128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 21228ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper for (cnt = 4 + bitmask_words; cnt < 4 + bitmask_words + nbuckets; ++cnt) 212328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 21248ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt]; 212528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 212628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx == 0) 21278ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper continue; 212828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 212928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx < symbias) 213028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 213128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 213228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"), 21338ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); 213428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper continue; 213528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 213628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 213728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper while (symidx - symbias < maxidx) 213828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 21398ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[4 21408ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + bitmask_words 21418ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + nbuckets 214228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper + symidx 214328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper - symbias]; 214428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 214528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symdata != NULL) 214628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 214728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Check that the referenced symbol is not undefined. */ 214828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym sym_mem; 214928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem); 2150231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (sym != NULL && sym->st_shndx == SHN_UNDEF 2151231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_FUNC) 215228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 215328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"), 21545530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper idx, section_name (ebl, idx), symidx, 21555530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper cnt - (4 + bitmask_words)); 215628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 215728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper const char *symname = elf_strptr (ebl->elf, symshdr->sh_link, 215828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper sym->st_name); 215928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symname != NULL) 216028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 216128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word hval = elf_gnu_hash (symname); 216228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if ((hval & ~1u) != (chainhash & ~1u)) 216328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 216428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"), 21655530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper idx, section_name (ebl, idx), symidx, 21665530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper cnt - (4 + bitmask_words)); 21678ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 21688ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper /* Set the bits in the bitmask. */ 21698ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t maskidx = (hval / classbits) & bitmask_idxmask; 21708ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (classbits == 32) 21718ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 21728ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p32[maskidx] 21738ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT32_C (1) << (hval & (classbits - 1)); 21748ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p32[maskidx] 21758ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT32_C (1) << ((hval >> shift) & (classbits - 1)); 21768ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 21778ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper else 21788ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 21798ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p64[maskidx] 21808ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT64_C (1) << (hval & (classbits - 1)); 21818ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p64[maskidx] 21828ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT64_C (1) << ((hval >> shift) & (classbits - 1)); 21838ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 218428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 218528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 218628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 218728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if ((chainhash & 1) != 0) 218828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 218928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 219028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++symidx; 219128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 219228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 219328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx - symbias >= maxidx) 219428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 219528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain for bucket %zu out of bounds\n"), 21965530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); 219728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (symshdr != NULL 219828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && symidx > symshdr->sh_size / symshdr->sh_entsize) 219928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 220028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"), 22015530ec5bbb95d2041ba9ece15ba10fe2b1d86eabUlrich Drepper idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); 220228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 22038ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 22048ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (memcmp (collected.p32, bitmask.p32, bitmask_words * sizeof (Elf32_Word))) 22058ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 22068ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': bitmask does not match names in the hash table\n"), 22078ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx)); 22088ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 22098ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper free (collected.p32); 221028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 221128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 221228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 221328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 221428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2216acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type == ET_REL) 2217acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 2218acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2219acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': relocatable files cannot have hash tables\n"), 2220acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 2221acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 2222acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 2223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2224acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 2226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2232acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr symshdr_mem; 2233acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2234acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &symshdr_mem); 2235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM) 2236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': hash table not for dynamic symbol table\n"), 2238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 224028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_entsize != (tag == SHT_GNU_HASH 22418ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ? (gelf_getclass (ebl->elf) == ELFCLASS32 22428ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ? sizeof (Elf32_Word) : 0) 224328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper : (size_t) ebl_sysvhash_entrysize (ebl))) 2244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 224528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table entry size incorrect\n"), 2246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) == 0) 2249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"), 2250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 22528ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shdr->sh_size < (tag == SHT_GNU_HASH ? 4 : 2) * (shdr->sh_entsize ?: 4)) 2253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 22558ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': hash table has not even room for initial administrative entries\n"), 2256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 226028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper switch (tag) 2261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 226228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_HASH: 226328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) 226428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_sysv_hash64 (ebl, shdr, data, idx, symshdr); 226528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 226628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_sysv_hash (ebl, shdr, data, idx, symshdr); 226728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 2268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 226928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_GNU_HASH: 227028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_gnu_hash (ebl, shdr, data, idx, symshdr); 227128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 2272ee4b927bae351b21787355e00a3d28371bf78e8fUlrich Drepper 227328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper default: 22748ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper assert (! "should not happen"); 2275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 22797c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper/* Compare content of both hash tables, it must be identical. */ 22807c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepperstatic void 22817c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppercompare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx, 22827c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper size_t gnu_hash_idx) 22837c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper{ 22847c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Scn *hash_scn = elf_getscn (ebl->elf, hash_idx); 22857c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Data *hash_data = elf_getdata (hash_scn, NULL); 22867c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr hash_shdr_mem; 22877c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr *hash_shdr = gelf_getshdr (hash_scn, &hash_shdr_mem); 22887c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Scn *gnu_hash_scn = elf_getscn (ebl->elf, gnu_hash_idx); 22897c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Data *gnu_hash_data = elf_getdata (gnu_hash_scn, NULL); 22907c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr gnu_hash_shdr_mem; 22917c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr *gnu_hash_shdr = gelf_getshdr (gnu_hash_scn, &gnu_hash_shdr_mem); 22927c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22937c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (hash_shdr == NULL || gnu_hash_shdr == NULL 22947c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper || hash_data == NULL || gnu_hash_data == NULL) 22957c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* None of these pointers should be NULL since we used the 22967c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper sections already. We are careful nonetheless. */ 22977c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper return; 22987c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22997c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* The link must point to the same symbol table. */ 23007c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (hash_shdr->sh_link != gnu_hash_shdr->sh_link) 23017c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23027c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 23037c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"), 23047c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name), 23057c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gnu_hash_idx, 23067c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 23077c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper return; 23087c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23097c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23107c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Scn *sym_scn = elf_getscn (ebl->elf, hash_shdr->sh_link); 23117c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Data *sym_data = elf_getdata (sym_scn, NULL); 23127c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr sym_shdr_mem; 23137c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr *sym_shdr = gelf_getshdr (sym_scn, &sym_shdr_mem); 23147c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23157c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (sym_data == NULL || sym_shdr == NULL) 23167c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper return; 23177c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23187c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper int nentries = sym_shdr->sh_size / sym_shdr->sh_entsize; 23197c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper char *used = alloca (nentries); 23207c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper memset (used, '\0', nentries); 23217c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23227c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* First go over the GNU_HASH table and mark the entries as used. */ 23237c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf; 23247c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf32_Word gnu_nbucket = gnu_hasharr[0]; 23257c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const int bitmap_factor = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 1 : 2; 23267c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *gnu_bucket = (gnu_hasharr 23277c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper + (4 + gnu_hasharr[2] * bitmap_factor)); 23287c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0] - gnu_hasharr[1]; 23297c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23307c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt) 23317c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23327c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf32_Word symidx = gnu_bucket[cnt]; 23337c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (symidx != STN_UNDEF) 23347c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper do 23357c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper used[symidx] |= 1; 23367c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper while ((gnu_chain[symidx++] & 1u) == 0); 23377c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23387c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23397c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* Now go over the old hash table and check that we cover the same 23407c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper entries. */ 23417c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (hash_shdr->sh_entsize == sizeof (Elf32_Word)) 23427c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23437c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *hasharr = (Elf32_Word *) hash_data->d_buf; 23447c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf32_Word nbucket = hasharr[0]; 23457c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *bucket = &hasharr[2]; 23467c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *chain = &hasharr[2 + nbucket]; 23477c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23487c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 23497c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23507c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf32_Word symidx = bucket[cnt]; 23517c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper while (symidx != STN_UNDEF) 23527c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23537c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper used[symidx] |= 2; 23547c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper symidx = chain[symidx]; 23557c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23567c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23577c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23587c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper else 23597c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23607c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf64_Xword *hasharr = (Elf64_Xword *) hash_data->d_buf; 23617c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf64_Xword nbucket = hasharr[0]; 23627c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf64_Xword *bucket = &hasharr[2]; 23637c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf64_Xword *chain = &hasharr[2 + nbucket]; 23647c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23657c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) 23667c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23677c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf64_Xword symidx = bucket[cnt]; 23687c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper while (symidx != STN_UNDEF) 23697c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23707c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper used[symidx] |= 2; 23717c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper symidx = chain[symidx]; 23727c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23737c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23747c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23757c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23767c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* Now see which entries are not set in one or both hash tables 23777c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper (unless the symbol is undefined in which case it can be omitted 23787c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper in the new table format). */ 23797c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if ((used[0] & 1) != 0) 23807c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"), 23817c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gnu_hash_idx, 23827c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 23837c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if ((used[0] & 2) != 0) 23847c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"), 23857c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name)); 23867c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23877c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (int cnt = 1; cnt < nentries; ++cnt) 23887c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (used[cnt] != 0 && used[cnt] != 3) 23897c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23907c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (used[cnt] == 1) 23917c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 23927c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersymbol %d referenced in new hash table in [%2zu] '%s' but not in old hash table in [%2zu] '%s'\n"), 23937c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper cnt, gnu_hash_idx, 23947c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name), 23957c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper hash_idx, 23967c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name)); 23977c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper else 23987c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 23997c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Sym sym_mem; 24007c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Sym *sym = gelf_getsym (sym_data, cnt, &sym_mem); 24017c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 24027c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (sym != NULL && sym->st_shndx != STN_UNDEF) 24037c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 24047c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersymbol %d referenced in old hash table in [%2zu] '%s' but not in new hash table in [%2zu] '%s'\n"), 24057c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper cnt, hash_idx, 24067c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name), 24077c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gnu_hash_idx, 24087c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 24097c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 24107c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 24117c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper} 24127c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 24137c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 2414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_null (Ebl *ebl, GElf_Shdr *shdr, int idx) 2416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define TEST(name, extra) \ 2418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (extra && shdr->sh_##name != 0) \ 2419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"), \ 2420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), #name) 2421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (name, 1); 2423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (flags, 1); 2424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (addr, 1); 2425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (offset, 1); 2426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (size, idx != 0); 2427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (link, idx != 0); 2428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (info, 1); 2429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (addralign, 1); 2430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (entsize, 1); 2431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 2438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section groups only allowed in relocatable object files\n"), 2441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check that sh_link is an index of a symbol table. */ 24460e864dd86871c809668c557985ca19344dfff787Ulrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 2447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 24480e864dd86871c809668c557985ca19344dfff787Ulrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 2449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr == NULL) 2450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"), 2451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), elf_errmsg (-1)); 2452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr->sh_type != SHT_SYMTAB) 2455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section reference in sh_link is no symbol table\n"), 2457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM, 2460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1, EV_CURRENT)) 2461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': invalid symbol index in sh_info\n"), 2463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags != 0) 2466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"), 2467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 24690e864dd86871c809668c557985ca19344dfff787Ulrich Drepper GElf_Sym sym_data; 24700e864dd86871c809668c557985ca19344dfff787Ulrich Drepper GElf_Sym *sym = gelf_getsym (elf_getdata (symscn, NULL), shdr->sh_info, 24710e864dd86871c809668c557985ca19344dfff787Ulrich Drepper &sym_data); 24720e864dd86871c809668c557985ca19344dfff787Ulrich Drepper if (sym == NULL) 24730e864dd86871c809668c557985ca19344dfff787Ulrich Drepper ERROR (gettext ("\ 24740e864dd86871c809668c557985ca19344dfff787Ulrich Dreppersection [%2d] '%s': cannot get symbol for signature\n"), 24750e864dd86871c809668c557985ca19344dfff787Ulrich Drepper idx, section_name (ebl, idx)); 24760e864dd86871c809668c557985ca19344dfff787Ulrich Drepper else if (strcmp (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name), 24770e864dd86871c809668c557985ca19344dfff787Ulrich Drepper "") == 0) 24780e864dd86871c809668c557985ca19344dfff787Ulrich Drepper ERROR (gettext ("\ 24793b495d8e963eead963a37b5be5b063c96bb58c63Roland McGrathsection [%2d] '%s': signature symbol cannot be empty string\n"), 24800e864dd86871c809668c557985ca19344dfff787Ulrich Drepper idx, section_name (ebl, idx)); 24810e864dd86871c809668c557985ca19344dfff787Ulrich Drepper 2482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (be_strict 2483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT)) 2484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"), 2485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 2490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"), 2491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), elf_errmsg (-1)); 2492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT); 2495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 2496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word val; 2497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size % elsize != 0) 2499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"), 2501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size < elsize) 2504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group without flags word\n"), 2506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (be_strict) 2508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size < 2 * elsize) 2510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group without member\n"), 2512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (data->d_size < 3 * elsize) 2514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group with only one member\n"), 2516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED 2520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val = *((Elf32_Word *) data->d_buf); 2521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#else 2522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (&val, data->d_buf, elsize); 2523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 2524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((val & ~GRP_COMDAT) != 0) 2525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"), 2526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = elsize; cnt < data->d_size; cnt += elsize) 2529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED 2531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val = *((Elf32_Word *) ((char *) data->d_buf + cnt)); 2532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#else 2533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (&val, (char *) data->d_buf + cnt, elsize); 2534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 2535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (val > shnum) 2537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section index %Zu out of range\n"), 2539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize); 2540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr refshdr_mem; 2543acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val), 2544acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &refshdr_mem); 2545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (refshdr == NULL) 2546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get section header for element %zu: %s\n"), 2548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize, 2549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 2550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (refshdr->sh_type == SHT_GROUP) 2553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group contains another group [%2d] '%s'\n"), 2555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((refshdr->sh_flags & SHF_GROUP) == 0) 2559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP flag set\n"), 2561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize, 2562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++scnref[val] == 2) 2566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' is contained in more than one section group\n"), 2568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char * 2576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_flags_string (GElf_Word flags, char *buf, size_t len) 2577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2578099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath if (flags == 0) 2579099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath return "none"; 2580099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath 2581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const struct 2582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word flag; 2584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name; 2585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } known_flags[] = 2586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define NEWFLAG(name) { SHF_##name, #name } 2588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (WRITE), 2589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (ALLOC), 2590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (EXECINSTR), 2591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (MERGE), 2592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (STRINGS), 2593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (INFO_LINK), 2594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (LINK_ORDER), 2595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (OS_NONCONFORMING), 2596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (GROUP), 2597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (TLS) 2598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 2599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#undef NEWFLAG 2600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]); 2601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = buf; 2603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2604acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 0; cnt < nknown_flags; ++cnt) 2605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags & known_flags[cnt].flag) 2606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cp != buf && len > 1) 2608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = '|'; 2610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper --len; 2611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name)); 2614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, known_flags[cnt].name, ncopy); 2615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper len -= ncopy; 2616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper flags ^= known_flags[cnt].flag; 2618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags != 0 || cp == buf) 2621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags); 2622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp = '\0'; 2624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return buf; 2626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2629dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2630dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperhas_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx) 2631dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2632dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* First find the relocation section for the symbol table. */ 2633dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = NULL; 2634dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2635dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = NULL; 2636dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2637dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2638dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper shdr = gelf_getshdr (scn, &shdr_mem); 2639dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr != NULL 2640dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) 2641dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && shdr->sh_link == symscnndx) 2642dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Found the section. */ 2643dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2644dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2645dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2646dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (scn == NULL) 2647dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2648dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2649dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2650dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2651dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2652dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2653dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr->sh_type == SHT_REL) 2654dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 2655dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2656dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rel rel_mem; 2657dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rel *rel = gelf_getrel (data, i, &rel_mem); 2658dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (rel == NULL) 2659dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2660dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2661dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_R_SYM (rel->r_info) == symndx 2662dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) 2663dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2664dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2665dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2666dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 2667dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2668dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rela rela_mem; 2669dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rela *rela = gelf_getrela (data, i, &rela_mem); 2670dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (rela == NULL) 2671dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2672dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2673dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_R_SYM (rela->r_info) == symndx 2674dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) 2675dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2676dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2677dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2678dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2679dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2680dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2681dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2682637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic int 2683637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperin_nobits_scn (Ebl *ebl, unsigned int shndx) 2684637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper{ 2685637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Shdr shdr_mem; 2686637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem); 2687637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper return shdr != NULL && shdr->sh_type == SHT_NOBITS; 2688637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper} 2689637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2690637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2691dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic struct version_namelist 2692dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2693dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *objname; 2694dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name; 2695858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath GElf_Versym ndx; 2696dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper enum { ver_def, ver_need } type; 2697dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *next; 2698dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} *version_namelist; 2699dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2700dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2701dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2702858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrathadd_version (const char *objname, const char *name, GElf_Versym ndx, int type) 2703dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2704dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that there are no duplications. */ 2705dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *nlp = version_namelist; 2706dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (nlp != NULL) 2707dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2708dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (((nlp->objname == NULL && objname == NULL) 2709dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper || (nlp->objname != NULL && objname != NULL 2710dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (nlp->objname, objname) == 0)) 2711dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (nlp->name, name) == 0) 2712dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return nlp->type == ver_def ? 1 : -1; 2713dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp = nlp->next; 2714dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2715dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2716dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp = xmalloc (sizeof (*nlp)); 2717dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->objname = objname; 2718dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->name = name; 2719dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->ndx = ndx; 2720dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->type = type; 2721dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->next = version_namelist; 2722dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper version_namelist = nlp; 2723dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2724dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2725dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2726dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2727dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2729dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_versym (Ebl *ebl, int idx) 2730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2731dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = elf_getscn (ebl->elf, idx); 2732dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2733dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2734dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr == NULL) 2735dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The error has already been reported. */ 2736dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2737dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2738dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2739dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2740dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2741dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2742dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2743dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2744dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2745dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2746dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 2747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 2748dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 2749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr == NULL) 2750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The error has already been reported. */ 2751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr->sh_type != SHT_DYNSYM) 2754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"), 2757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 2759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2762dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The number of elements in the version symbol table must be the 2763dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper same as the number of symbols. */ 276471c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek if (shdr->sh_entsize && symshdr->sh_entsize 276571c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek && (shdr->sh_size / shdr->sh_entsize 276671c1534c9c7a0652fb6c5f9295baa08f32b0b166Jakub Jelinek != symshdr->sh_size / symshdr->sh_entsize)) 2767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"), 2769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 2771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2772dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 2773dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (symdata == NULL) 2774dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The error has already been reported. */ 2775dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2776dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2777dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 2778dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2779dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Versym versym_mem; 2780dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem); 2781dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym == NULL) 2782dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2783dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2784dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: cannot read version data\n"), 2785dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2786dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2787dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2788dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2789dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Sym sym_mem; 2790dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem); 2791dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (sym == NULL) 2792dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Already reported elsewhere. */ 2793dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2794dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 279561655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper if (*versym == VER_NDX_GLOBAL) 2796dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2797dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Global symbol. Make sure it is not defined as local. */ 2798dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2799dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2800dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: local symbol with global scope\n"), 2801dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2802dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 280361655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper else if (*versym != VER_NDX_LOCAL) 2804dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2805c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper /* Versioned symbol. Make sure it is not defined as local. */ 2806c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2807c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper ERROR (gettext ("\ 2808c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Dreppersection [%2d] '%s': symbol %d: local symbol with version\n"), 2809c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper idx, section_name (ebl, idx), cnt); 2810c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper 2811dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Look through the list of defined versions and locate the 2812dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper index we need for this symbol. */ 2813dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist; 2814dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 2815858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath if (runp->ndx == (*versym & (GElf_Versym) 0x7fff)) 2816dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2817dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2818dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 2819dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2820dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp == NULL) 2821dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2822dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: invalid version index %d\n"), 2823dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2824dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (sym->st_shndx == SHN_UNDEF 2825dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && runp->type == ver_def) 2826dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2827dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for defined version\n"), 2828dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2829dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (sym->st_shndx != SHN_UNDEF 2830dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && runp->type == ver_need) 2831dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2832dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Unless this symbol has a copy relocation associated 2833dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper this must not happen. */ 2834637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper if (!has_copy_reloc (ebl, shdr->sh_link, cnt) 2835637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper && !in_nobits_scn (ebl, sym->st_shndx)) 2836dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2837dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for requested version\n"), 2838dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2839dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2840dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2841dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2842dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2843dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2844dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2845dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2846bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrathunknown_dependency_p (Elf *elf, const char *fname) 2847dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2848dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr phdr_mem; 2849dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr *phdr = NULL; 2850dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2851bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath unsigned int i; 2852bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (i = 0; i < phnum; ++i) 2853dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL 2854dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr->p_type == PT_DYNAMIC) 2855dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2856dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2857bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (i == phnum) 2858dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2859dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (phdr != NULL); 2860dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); 2861dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2862dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2863dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2864dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL) 2865dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) 2866dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2867dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Dyn dyn_mem; 2868dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); 2869dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (dyn != NULL && dyn->d_tag == DT_NEEDED) 2870dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2871dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val); 2872dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (str != NULL && strcmp (str, fname) == 0) 2873dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Found it. */ 2874dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2875dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2876dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2877dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2878dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2882acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic unsigned int nverneed; 2883acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2885bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrathcheck_verneed (Ebl *ebl, GElf_Shdr *shdr, int idx) 2886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2887acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (++nverneed == 2) 2888acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("more than one version reference section present\n")); 2889acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2890acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr strshdr_mem; 2891acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2892acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &strshdr_mem); 2893acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr == NULL) 2894acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 2895acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 2896acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2897acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': sh_link does not link to string table\n"), 2898acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 2899dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2900dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2901dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2902dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2903dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2904dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2905dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2906dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2907dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int offset = 0; 2908dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = shdr->sh_info; --cnt >= 0; ) 2909dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2910dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Get the data at the next offset. */ 2911dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verneed needmem; 2912dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 2913dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need == NULL) 2914dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2915dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2916dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int auxoffset = offset + need->vn_aux; 2917dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2918dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need->vn_version != EV_CURRENT) 2919dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2920dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"), 2921dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) need->vn_version); 2922dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2923dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED, 2924dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 1, EV_CURRENT)) 2925dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2926dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 2927dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2928dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2929dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *libname = elf_strptr (ebl->elf, shdr->sh_link, 2930dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper need->vn_file); 2931dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (libname == NULL) 2932dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2933dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2934dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid file reference\n"), 2935dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2936dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto next_need; 2937dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2938dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2939dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that there is a DT_NEEDED entry for the referenced library. */ 2940bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (unknown_dependency_p (ebl->elf, libname)) 2941dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2942dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d references unknown dependency\n"), 2943dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2944dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2945dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2946dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2947dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Vernaux auxmem; 2948dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 2949dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 2950dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2951dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2952dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vna_flags & ~VER_FLG_WEAK) != 0) 2953dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2954dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"), 2955dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2956dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2957dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *verstr = elf_strptr (ebl->elf, shdr->sh_link, 2958dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper aux->vna_name); 2959dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (verstr == NULL) 2960dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2961dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"), 2962dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2963dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2964dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2965dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Word hashval = elf_hash (verstr); 2966dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (hashval != aux->vna_hash) 2967dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2968dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"), 2969dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2970dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, (int) hashval, (int) aux->vna_hash); 2971dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2972dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int res = add_version (libname, verstr, aux->vna_other, 2973dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ver_need); 2974dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (unlikely (res !=0)) 2975dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2976dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (res > 0); 2977dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2978dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"), 2979dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2980dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, verstr); 2981dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2982dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2983dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2984dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vna_next != 0 || cnt2 > 0) 2985dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, 2986dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper EV_CURRENT)) 2987dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2988dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2989dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"), 2990dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2991dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2992dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2993dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2994dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += MAX (aux->vna_next, 2995dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT)); 2996dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2997dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2998dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Find the next offset. */ 2999dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper next_need: 3000dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper offset += need->vn_next; 3001dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3002dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((need->vn_next != 0 || cnt > 0) 3003dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && offset < auxoffset) 3004dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3005dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid offset to next entry\n"), 3006dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 3007dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3008acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper} 3009b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3010acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3011acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic unsigned int nverdef; 3012acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3013acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic void 3014acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx) 3015acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper{ 3016acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (++nverdef == 2) 3017acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("more than one version definition section present\n")); 3018acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3019acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr strshdr_mem; 3020acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 3021acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &strshdr_mem); 3022acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr == NULL) 3023acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 3024acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 3025acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 3026acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': sh_link does not link to string table\n"), 3027acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 3028dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3029dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 3030dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 3031dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3032dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper no_data: 3033dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 3034dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 3035dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 3036dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3037dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3038dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Iterate over all version definition entries. We check that there 3039dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper is a BASE entry and that each index is unique. To do the later 3040dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper we collection the information in a list which is later 3041dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper examined. */ 3042dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist 3043dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3044dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name; 3045dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *next; 3046dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } *namelist = NULL; 3047dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *refnamelist = NULL; 3048dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3049dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper bool has_base = false; 3050dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int offset = 0; 3051dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = shdr->sh_info; --cnt >= 0; ) 3052dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3053dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Get the data at the next offset. */ 3054dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdef defmem; 3055dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 3056dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def == NULL) 3057dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 3058dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3059dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_flags & VER_FLG_BASE) != 0) 3060dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3061dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (has_base) 3062dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3063dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': more than one BASE definition\n"), 3064dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 3065dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_ndx != VER_NDX_GLOBAL) 3066dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3067dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"), 3068dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 3069dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper has_base = true; 3070dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3071dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0) 3072dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3073dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has unknown flag\n"), 3074dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 3075dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3076dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_version != EV_CURRENT) 3077dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3078dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"), 3079dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) def->vd_version); 3080dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3081dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF, 3082dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 1, EV_CURRENT)) 3083dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3084dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 3085dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 3086dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3087dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int auxoffset = offset + def->vd_aux; 3088dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdaux auxmem; 3089dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 3090dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 3091dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 3092dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3093dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 3094dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (name == NULL) 3095dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3096dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3097dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid name reference\n"), 3098dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 3099dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto next_def; 3100dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3101dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Word hashval = elf_hash (name); 3102dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_hash != hashval) 3103dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3104dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"), 3105dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) hashval, 3106dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper (int) def->vd_hash); 3107dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3108dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int res = add_version (NULL, name, def->vd_ndx, ver_def); 3109dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (unlikely (res !=0)) 3110dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3111dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (res > 0); 3112dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3113dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has duplicate version name '%s'\n"), 3114dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, name); 3115dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3116dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3117dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *newname = alloca (sizeof (*newname)); 31186247d634c33be4c9ee4bfc650bb8f06f5add41e5Ulrich Drepper newname->name = name; 3119dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper newname->next = namelist; 3120dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper namelist = newname; 3121dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3122dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += aux->vda_next; 3123dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 3124dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3125dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper aux = gelf_getverdaux (data, auxoffset, &auxmem); 3126dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 3127dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 3128dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3129c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 3130c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper if (name == NULL) 3131c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper ERROR (gettext ("\ 3132c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Dreppersection [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"), 3133c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper idx, section_name (ebl, idx), cnt); 3134c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper else 3135c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper { 3136c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname = alloca (sizeof (*newname)); 3137c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname->name = name; 3138c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname->next = refnamelist; 3139c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper refnamelist = newname; 3140c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper } 3141dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3142dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt) 3143dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, 3144dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper EV_CURRENT)) 3145dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3146dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3147dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong next field in auxiliary data\n"), 3148dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 3149dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3150dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3151dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3152dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += MAX (aux->vda_next, 3153dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT)); 3154dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3155dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3156dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Find the next offset. */ 3157dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper next_def: 3158dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper offset += def->vd_next; 3159dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3160dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_next != 0 || cnt > 0) 3161dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && offset < auxoffset) 3162dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3163dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid offset to next entry\n"), 3164dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 3165dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3166dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3167dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (!has_base) 3168dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': no BASE definition\n"), 3169dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 3170dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3171dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check whether the referenced names are available. */ 3172dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (namelist != NULL) 3173dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3174dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist; 3175dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 3176dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3177dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp->type == ver_def 3178dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (runp->name, namelist->name) == 0) 3179dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3180dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 3181dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3182dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3183dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp == NULL) 3184dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3185dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': unknown parent version '%s'\n"), 3186dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), namelist->name); 3187dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3188dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper namelist = namelist->next; 3189dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3190acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper} 3191acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3192059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathstatic void 3193059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathcheck_attributes (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 3194059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath{ 3195059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (shdr->sh_size == 0) 3196059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3197059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("section [%2d] '%s': empty object attributes section\n"), 3198059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx)); 3199059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath return; 3200059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3201059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3202059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath Elf_Data *data = elf_rawdata (elf_getscn (ebl->elf, idx), NULL); 3203059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (data == NULL || data->d_size == 0) 3204059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3205059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 3206059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx)); 3207059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath return; 3208059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3209059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3210059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath inline size_t pos (const unsigned char *p) 3211059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3212059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath return p - (const unsigned char *) data->d_buf; 3213059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3214059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3215059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath const unsigned char *p = data->d_buf; 3216059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (*p++ != 'A') 3217059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3218059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("section [%2d] '%s': unrecognized attribute format\n"), 3219059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx)); 3220059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath return; 3221059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3222059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3223059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath inline size_t left (void) 3224059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3225059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath return (const unsigned char *) data->d_buf + data->d_size - p; 3226059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3227059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3228059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath while (left () >= 4) 3229059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3230059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath uint32_t len; 3231059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath memcpy (&len, p, sizeof len); 3232059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3233059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (len == 0) 3234059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3235059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: zero length field in attribute section\n"), 3236059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (p)); 3237059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3238059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 3239059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath CONVERT (len); 3240059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3241059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (len > left ()) 3242059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3243059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3244059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: invalid length in attribute section\n"), 3245059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (p)); 3246059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath break; 3247059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3248059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3249059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath const unsigned char *name = p + sizeof len; 3250059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath p += len; 3251059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3252059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath unsigned const char *q = memchr (name, '\0', len); 3253059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (q == NULL) 3254059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3255059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3256059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: unterminated vendor name string\n"), 3257059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (p)); 3258059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath continue; 3259059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3260059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ++q; 3261059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3262059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (q - name == sizeof "gnu" && !memcmp (name, "gnu", sizeof "gnu")) 3263059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath while (q < p) 3264059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3265059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath unsigned const char *chunk = q; 3266059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3267059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath unsigned int subsection_tag; 3268059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath get_uleb128 (subsection_tag, q); 3269059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3270059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (q >= p) 3271059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3272059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3273059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"), 3274059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (chunk)); 3275059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath break; 3276059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3277059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3278059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath uint32_t subsection_len; 3279059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (p - q < (ptrdiff_t) sizeof subsection_len) 3280059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3281059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3282059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: truncated attribute section\n"), 3283059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (q)); 3284059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath break; 3285059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3286059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3287059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath memcpy (&subsection_len, q, sizeof subsection_len); 3288059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (subsection_len == 0) 3289059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3290059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3291059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: zero length field in attribute subsection\n"), 3292059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (q)); 3293059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3294059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath q += sizeof subsection_len; 3295059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath continue; 3296059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3297059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3298059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 3299059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath CONVERT (subsection_len); 3300059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 330147c5c35de6bc548dff7577e3dae38d183b719232Roland McGrath if (p - chunk < (ptrdiff_t) subsection_len) 3302059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3303059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3304059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: invalid length in attribute subsection\n"), 3305059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (q)); 3306059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath break; 3307059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3308059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3309059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath const unsigned char *subsection_end = chunk + subsection_len; 3310059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath chunk = q; 3311059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath q = subsection_end; 3312059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3313059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (subsection_tag != 1) /* Tag_File */ 3314059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3315059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"), 3316059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (chunk), subsection_tag); 3317059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath else 3318059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3319059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath chunk += sizeof subsection_len; 3320059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath while (chunk < q) 3321059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3322059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath unsigned int tag; 3323059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath get_uleb128 (tag, chunk); 3324059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3325059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath uint64_t value = 0; 3326059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath const unsigned char *r = chunk; 3327059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (tag == 32 || (tag & 1) == 0) 3328059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3329059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath get_uleb128 (value, r); 3330059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (r > q) 3331059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3332059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3333059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"), 3334059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (chunk)); 3335059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath break; 3336059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3337059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3338059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (tag == 32 || (tag & 1) != 0) 3339059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3340059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath r = memchr (r, '\0', q - r); 3341059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (r == NULL) 3342059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { 3343059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3344059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: unterminated string in attribute\n"), 3345059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (chunk)); 3346059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath break; 3347059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3348059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ++r; 3349059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3350059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3351059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath const char *tag_name = NULL; 3352059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath const char *value_name = NULL; 3353059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (!ebl_check_object_attribute (ebl, (const char *) name, 3354059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath tag, value, 3355059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath &tag_name, &value_name)) 3356059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3357059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"), 3358059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (chunk), tag); 3359059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath else if ((tag & 1) == 0 && value_name == NULL) 3360059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3361059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: unrecognized %s attribute value %" PRIu64 "\n"), 3362059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (chunk), 3363059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath tag_name, value); 3364059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3365059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath chunk = r; 3366059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3367059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3368059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3369059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath else 3370059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3371059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: vendor '%s' unknown\n"), 3372059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (p), name); 3373059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath } 3374059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3375059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath if (left () != 0) 3376059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath ERROR (gettext ("\ 3377059c83e5db89955913a39fe6705acca571c32c3fRoland McGrathsection [%2d] '%s': offset %zu: extra bytes after last attribute section\n"), 3378059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath idx, section_name (ebl, idx), pos (p)); 3379059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath} 3380acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3381637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic bool has_loadable_segment; 3382637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic bool has_interp_segment; 3383637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 3384637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic const struct 3385637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper{ 3386637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper const char *name; 3387637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper size_t namelen; 3388637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word type; 3389b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper enum { unused, exact, atleast, exact_or_gnuld } attrflag; 3390637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word attr; 3391637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word attr2; 3392637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper} special_sections[] = 3393637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { 3394637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper /* See figure 4-14 in the gABI. */ 3395637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3396c49d00afc4bda21181cd4237e67930f3f5228adfMark Wielaard { ".comment", 8, SHT_PROGBITS, atleast, 0, SHF_MERGE | SHF_STRINGS }, 3397637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3398637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3399b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { ".debug_str", 11, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 }, 3400b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper { ".debug", 6, SHT_PROGBITS, exact, 0, 0 }, 3401637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE }, 3402637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 }, 3403637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 }, 3404637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3405637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3406637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info? 3407637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 }, 3408637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3409637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3410637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests? 3411637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".line", 6, SHT_PROGBITS, exact, 0, 0 }, 3412099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath { ".note", 6, SHT_NOTE, atleast, 0, SHF_ALLOC }, 3413637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests 3414637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3415738c18312e0db36dce5e1cd2cddaf66eb8947f1aRoland McGrath { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests 3416738c18312e0db36dce5e1cd2cddaf66eb8947f1aRoland McGrath { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests 3417637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 3418637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 3419637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 }, 3420637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 3421637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 3422637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests 3423637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3424637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3425637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3426637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3427637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 3428637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper /* The following are GNU extensions. */ 3429637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 }, 3430637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 }, 3431059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 }, 3432059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath { ".gnu.attributes", 16, SHT_GNU_ATTRIBUTES, exact, 0, 0 }, 3433637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper }; 3434637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper#define nspecial_sections \ 3435637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper (sizeof (special_sections) / sizeof (special_sections[0])) 3436637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 3437b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper#define IS_KNOWN_SPECIAL(idx, string, prefix) \ 3438b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper (special_sections[idx].namelen == sizeof string - (prefix ? 1 : 0) \ 3439b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper && !memcmp (special_sections[idx].name, string, \ 3440b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper sizeof string - (prefix ? 1 : 0))) 3441637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 3442978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 3443978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper/* Indeces of some sections we need later. */ 3444978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepperstatic size_t eh_frame_hdr_scnndx; 3445978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepperstatic size_t eh_frame_scnndx; 3446978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepperstatic size_t gcc_except_table_scnndx; 3447978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 3448978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 3449acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic void 3450acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_sections (Ebl *ebl, GElf_Ehdr *ehdr) 3451acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper{ 3452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shoff == 0) 3453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No section header. */ 3454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 3455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate array to count references in section groups. */ 3457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scnref = (int *) xcalloc (shnum, sizeof (int)); 3458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the zeroth section first. It must not have any contents 3460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper and the section header must contain nonzero value at most in the 3461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sh_size and sh_link fields. */ 3462acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr shdr_mem; 3463acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 3464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 3465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get section header of zeroth section\n")); 3466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_name != 0) 3469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero name\n")); 3470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type != 0) 3471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero type\n")); 3472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags != 0) 3473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero flags\n")); 3474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addr != 0) 3475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero address\n")); 3476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_offset != 0) 3477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero offset\n")); 3478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addralign != 0) 3479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero align value\n")); 3480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != 0) 3481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero entry size value\n")); 3482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size != 0 && ehdr->e_shnum != 0) 3484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero size value while ELF header has nonzero shnum value\n")); 3486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX) 3488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n")); 3490bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath 3491bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (shdr->sh_info != 0 && ehdr->e_phnum != PN_XNUM) 3492bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath ERROR (gettext ("\ 3493bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrathzeroth section has nonzero link value while ELF header does not signal overflow in phnum\n")); 3494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3496bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath int *segment_flags = xcalloc (phnum, sizeof segment_flags[0]); 349713b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 3498acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper bool dot_interp_section = false; 3499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 35007c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper size_t hash_idx = 0; 35017c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper size_t gnu_hash_idx = 0; 35027c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 3503dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper size_t versym_scnndx = 0; 3504acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 1; cnt < shnum; ++cnt) 3505acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 3506acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem); 3507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 3508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercannot get section header for section [%2zu] '%s': %s\n"), 3511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), elf_errmsg (-1)); 3512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 3513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 3516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnname == NULL) 3518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2zu]: invalid name\n"), cnt); 3519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether it is one of the special sections defined in 3522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the gABI. */ 3523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t s; 3524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (s = 0; s < nspecial_sections; ++s) 3525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strncmp (scnname, special_sections[s].name, 3526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper special_sections[s].namelen) == 0) 3527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf1[100]; 3529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf2[100]; 3530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf3[100]; 3531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3532653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Word good_type = special_sections[s].type; 3533b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (IS_KNOWN_SPECIAL (s, ".plt", false) 3534c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper && ebl_bss_plt_p (ebl, ehdr)) 3535653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath good_type = SHT_NOBITS; 3536653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 3537b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper /* In a debuginfo file, any normal section can be SHT_NOBITS. 3538b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper This is only invalid for DWARF sections and .shstrtab. */ 3539653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (shdr->sh_type != good_type 3540b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper && (shdr->sh_type != SHT_NOBITS 3541b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper || !is_debuginfo 3542b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper || IS_KNOWN_SPECIAL (s, ".debug_str", false) 3543b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper || IS_KNOWN_SPECIAL (s, ".debug", true) 3544b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper || IS_KNOWN_SPECIAL (s, ".shstrtab", false))) 3545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' has wrong type: expected %s, is %s\n"), 3547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) cnt, scnname, 3548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_type_name (ebl, special_sections[s].type, 3549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_type_name (ebl, shdr->sh_type, 3551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2))); 3552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3553b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (special_sections[s].attrflag == exact 3554b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper || special_sections[s].attrflag == exact_or_gnuld) 3555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Except for the link order and group bit all the 3557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper other bits should match exactly. */ 3558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP)) 3559b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper != special_sections[s].attr 3560b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper && (special_sections[s].attrflag == exact || !gnuld)) 3561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s, is %s\n"), 3563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname, 3564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr, 3565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (shdr->sh_flags 3567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~SHF_LINK_ORDER, 3568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2))); 3569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (special_sections[s].attrflag == atleast) 3571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & special_sections[s].attr) 3573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != special_sections[s].attr 3574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP 3575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | special_sections[s].attr 3576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | special_sections[s].attr2)) 3577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != 0)) 3578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"), 3580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname, 3581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr, 3582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr2, 3584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2)), 3585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (shdr->sh_flags 3586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~(SHF_LINK_ORDER 3587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_GROUP), 3588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf3, sizeof (stbuf3))); 3589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (scnname, ".interp") == 0) 3592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper dot_interp_section = true; 3594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL) 3596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' present in object file\n"), 3598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) != 0 3601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !has_loadable_segment) 3602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 3604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((shdr->sh_flags & SHF_ALLOC) == 0 3606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && has_loadable_segment) 3607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 3609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (scnname, ".symtab_shndx") == 0 3614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_REL) 3615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' is extension section index table in non-object file\n"), 3617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* These sections must have the SHF_ALLOC flag set iff 3620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper a loadable segment is available. 3621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .relxxx 3623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .strtab 3624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .symtab 3625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .symtab_shndx 3626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Check that if there is a reference from the 3628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loaded section these sections also have the 3629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ALLOC flag set. */ 3630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if 0 3631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX TODO 3632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) != 0 3633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !has_loadable_segment) 3634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 3636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((shdr->sh_flags & SHF_ALLOC) == 0 3638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && has_loadable_segment) 3639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 3641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 3643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3647978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 3648978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper /* Remember a few special sections for later. */ 3649978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper if (strcmp (scnname, ".eh_frame_hdr") == 0) 3650978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper eh_frame_hdr_scnndx = cnt; 3651978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper else if (strcmp (scnname, ".eh_frame") == 0) 3652978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper eh_frame_scnndx = cnt; 3653978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper else if (strcmp (scnname, ".gcc_except_table") == 0) 3654978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper gcc_except_table_scnndx = cnt; 3655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize) 3658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': size not multiple of entry size\n"), 3660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL) 3663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get section header\n")); 3664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type >= SHT_NUM 3666059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath && shdr->sh_type != SHT_GNU_ATTRIBUTES 3667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_LIBLIST 3668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_CHECKSUM 3669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_verdef 3670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_verneed 367118e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath && shdr->sh_type != SHT_GNU_versym 367218e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL) 367318e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"), 367418e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath cnt, section_name (ebl, cnt), 367518e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath (int) shdr->sh_type); 3676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ 3678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ 3679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) 3680aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS) 3681aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper { 3682aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS; 3683aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (sh_flags & SHF_MASKPROC) 3684aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper { 3685aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (!ebl_machine_section_flag_check (ebl, 3686aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper sh_flags & SHF_MASKPROC)) 3687aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper ERROR (gettext ("section [%2zu] '%s'" 3688aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper " contains invalid processor-specific flag(s)" 3689aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper " %#" PRIx64 "\n"), 3690aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC); 3691aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper sh_flags &= ~(GElf_Xword) SHF_MASKPROC; 3692aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper } 3693aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (sh_flags != 0) 3694aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" 3695aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper " %#" PRIx64 "\n"), 3696aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper cnt, section_name (ebl, cnt), sh_flags); 3697aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper } 3698aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (shdr->sh_flags & SHF_TLS) 3699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX Correct? 3701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addr != 0 && !gnuld) 3702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': thread-local data sections address not zero\n"), 3704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX TODO more tests!? 3707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_link >= shnum) 3710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': invalid section reference in link value\n"), 3712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum) 3715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': invalid section reference in info value\n"), 3717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_MERGE) == 0 3720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_STRINGS) != 0 3721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && be_strict) 3722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': strings flag set without merge flag\n"), 3724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0) 3727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': merge flag set but entry size is zero\n"), 3729b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags & SHF_GROUP) 3732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_scn_group (ebl, cnt); 3733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 373413b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if (shdr->sh_flags & SHF_EXECINSTR) 373513b69609bcd5638e6194d940855fea3dd0519605Roland McGrath { 373613b69609bcd5638e6194d940855fea3dd0519605Roland McGrath switch (shdr->sh_type) 373713b69609bcd5638e6194d940855fea3dd0519605Roland McGrath { 373813b69609bcd5638e6194d940855fea3dd0519605Roland McGrath case SHT_PROGBITS: 373913b69609bcd5638e6194d940855fea3dd0519605Roland McGrath break; 374013b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 374113b69609bcd5638e6194d940855fea3dd0519605Roland McGrath case SHT_NOBITS: 374213b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if (is_debuginfo) 374313b69609bcd5638e6194d940855fea3dd0519605Roland McGrath break; 374413b69609bcd5638e6194d940855fea3dd0519605Roland McGrath default: 374513b69609bcd5638e6194d940855fea3dd0519605Roland McGrath ERROR (gettext ("\ 374613b69609bcd5638e6194d940855fea3dd0519605Roland McGrathsection [%2zu] '%s' has unexpected type %d for an executable section\n"), 374713b69609bcd5638e6194d940855fea3dd0519605Roland McGrath cnt, section_name (ebl, cnt), shdr->sh_type); 374813b69609bcd5638e6194d940855fea3dd0519605Roland McGrath break; 374913b69609bcd5638e6194d940855fea3dd0519605Roland McGrath } 375013b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 375113b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if ((shdr->sh_flags & SHF_WRITE) 375213b69609bcd5638e6194d940855fea3dd0519605Roland McGrath && !ebl_check_special_section (ebl, cnt, shdr, 375313b69609bcd5638e6194d940855fea3dd0519605Roland McGrath section_name (ebl, cnt))) 375413b69609bcd5638e6194d940855fea3dd0519605Roland McGrath ERROR (gettext ("\ 375513b69609bcd5638e6194d940855fea3dd0519605Roland McGrathsection [%2zu] '%s' is both executable and writable\n"), 375613b69609bcd5638e6194d940855fea3dd0519605Roland McGrath cnt, section_name (ebl, cnt)); 375713b69609bcd5638e6194d940855fea3dd0519605Roland McGrath } 375813b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 3759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0) 3760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the section is contained in a loaded segment 3762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper and that the initialization part matches NOBITS sections. */ 3763bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath unsigned int pcnt; 3764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 3765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr; 3766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3767bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (pcnt = 0; pcnt < phnum; ++pcnt) 3768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL 3769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ((phdr->p_type == PT_LOAD 3770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_TLS) == 0) 3771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (phdr->p_type == PT_TLS 3772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_TLS) != 0)) 3773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && phdr->p_offset <= shdr->sh_offset 377436aa5987df20c340fdfc584e04f4b3931a89abbdMark Wielaard && ((shdr->sh_offset - phdr->p_offset <= phdr->p_filesz 377536aa5987df20c340fdfc584e04f4b3931a89abbdMark Wielaard && (shdr->sh_offset - phdr->p_offset < phdr->p_filesz 377636aa5987df20c340fdfc584e04f4b3931a89abbdMark Wielaard || shdr->sh_size == 0)) 377736aa5987df20c340fdfc584e04f4b3931a89abbdMark Wielaard || (shdr->sh_offset - phdr->p_offset < phdr->p_memsz 37789aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath && shdr->sh_type == SHT_NOBITS))) 3779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found the segment. */ 3781b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_offset + phdr->p_memsz 3782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < shdr->sh_offset + shdr->sh_size) 3783b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3784b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' not fully contained in segment of program header entry %d\n"), 3785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type == SHT_NOBITS) 3788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz 3790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !is_debuginfo) 3791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"), 3793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3797653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const GElf_Off end = phdr->p_offset + phdr->p_filesz; 3798653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (shdr->sh_offset > end || 3799653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath (shdr->sh_offset == end && shdr->sh_size != 0)) 3800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"), 3802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 380513b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if (shdr->sh_type != SHT_NOBITS) 380613b69609bcd5638e6194d940855fea3dd0519605Roland McGrath { 380713b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if ((shdr->sh_flags & SHF_EXECINSTR) != 0) 380813b69609bcd5638e6194d940855fea3dd0519605Roland McGrath { 380913b69609bcd5638e6194d940855fea3dd0519605Roland McGrath segment_flags[pcnt] |= PF_X; 381013b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if ((phdr->p_flags & PF_X) == 0) 381113b69609bcd5638e6194d940855fea3dd0519605Roland McGrath ERROR (gettext ("\ 381213b69609bcd5638e6194d940855fea3dd0519605Roland McGrathsection [%2zu] '%s' is executable in nonexecutable segment %d\n"), 381313b69609bcd5638e6194d940855fea3dd0519605Roland McGrath cnt, section_name (ebl, cnt), pcnt); 381413b69609bcd5638e6194d940855fea3dd0519605Roland McGrath } 381513b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 381613b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if ((shdr->sh_flags & SHF_WRITE) != 0) 381713b69609bcd5638e6194d940855fea3dd0519605Roland McGrath { 381813b69609bcd5638e6194d940855fea3dd0519605Roland McGrath segment_flags[pcnt] |= PF_W; 381913b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if (0 /* XXX vdso images have this */ 382013b69609bcd5638e6194d940855fea3dd0519605Roland McGrath && (phdr->p_flags & PF_W) == 0) 382113b69609bcd5638e6194d940855fea3dd0519605Roland McGrath ERROR (gettext ("\ 382213b69609bcd5638e6194d940855fea3dd0519605Roland McGrathsection [%2zu] '%s' is writable in unwritable segment %d\n"), 382313b69609bcd5638e6194d940855fea3dd0519605Roland McGrath cnt, section_name (ebl, cnt), pcnt); 382413b69609bcd5638e6194d940855fea3dd0519605Roland McGrath } 382513b69609bcd5638e6194d940855fea3dd0519605Roland McGrath } 382613b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 3827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3828b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3830bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (pcnt == phnum) 3831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': alloc flag set but section not in any loaded segment\n"), 3833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3834b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB) 3837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"), 3839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (shdr->sh_type) 3842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_DYNSYM: 3844acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type == ET_REL) 3845acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 3846acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), 3847acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper cnt, section_name (ebl, cnt)); 3848acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper /* FALLTHROUGH */ 3849acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_SYMTAB: 3850dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_symtab (ebl, ehdr, shdr, cnt); 3851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_RELA: 3854c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper check_rela (ebl, ehdr, shdr, cnt); 3855b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3856b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3857b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_REL: 3858c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper check_rel (ebl, ehdr, shdr, cnt); 3859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3860b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3861b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_DYNAMIC: 3862607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_dynamic (ebl, ehdr, shdr, cnt); 3863b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3864b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3865b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_SYMTAB_SHNDX: 3866acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper check_symtab_shndx (ebl, ehdr, shdr, cnt); 3867b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3869b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_HASH: 38707c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); 38717c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper hash_idx = cnt; 38727c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper break; 38737c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 387428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_GNU_HASH: 387528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); 38767c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gnu_hash_idx = cnt; 3877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_NULL: 3880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_null (ebl, shdr, cnt); 3881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3882b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3883b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GROUP: 3884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_group (ebl, ehdr, shdr, cnt); 3885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 388759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case SHT_NOTE: 388859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath check_note_section (ebl, ehdr, shdr, cnt); 388959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath break; 389059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 3891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GNU_versym: 3892dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* We cannot process this section now since we have no guarantee 3893dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper that the verneed and verdef sections have already been read. 3894dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Just remember the section index. */ 3895dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym_scnndx != 0) 3896dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("more than one version symbol table present\n")); 3897dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper versym_scnndx = cnt; 3898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3900acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_GNU_verneed: 3901bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath check_verneed (ebl, shdr, cnt); 3902acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper break; 3903acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3904acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_GNU_verdef: 3905acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper check_verdef (ebl, shdr, cnt); 3906acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper break; 3907acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3908059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath case SHT_GNU_ATTRIBUTES: 3909059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath check_attributes (ebl, ehdr, shdr, cnt); 3910059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath break; 3911059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath 3912b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 3913b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Nothing. */ 3914b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_interp_segment && !dot_interp_section) 3919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("INTERP program header entry but no .interp section\n")); 3920b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 392113b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if (!is_debuginfo) 3922bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt) 392313b69609bcd5638e6194d940855fea3dd0519605Roland McGrath { 392413b69609bcd5638e6194d940855fea3dd0519605Roland McGrath GElf_Phdr phdr_mem; 392513b69609bcd5638e6194d940855fea3dd0519605Roland McGrath GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 392613b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if (phdr != NULL && (phdr->p_type == PT_LOAD || phdr->p_type == PT_TLS)) 392713b69609bcd5638e6194d940855fea3dd0519605Roland McGrath { 392813b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if ((phdr->p_flags & PF_X) != 0 392913b69609bcd5638e6194d940855fea3dd0519605Roland McGrath && (segment_flags[pcnt] & PF_X) == 0) 393013b69609bcd5638e6194d940855fea3dd0519605Roland McGrath ERROR (gettext ("\ 393113b69609bcd5638e6194d940855fea3dd0519605Roland McGrathloadable segment [%u] is executable but contains no executable sections\n"), 393213b69609bcd5638e6194d940855fea3dd0519605Roland McGrath pcnt); 393313b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 393413b69609bcd5638e6194d940855fea3dd0519605Roland McGrath if ((phdr->p_flags & PF_W) != 0 393513b69609bcd5638e6194d940855fea3dd0519605Roland McGrath && (segment_flags[pcnt] & PF_W) == 0) 393613b69609bcd5638e6194d940855fea3dd0519605Roland McGrath ERROR (gettext ("\ 393713b69609bcd5638e6194d940855fea3dd0519605Roland McGrathloadable segment [%u] is writable but contains no writable sections\n"), 393813b69609bcd5638e6194d940855fea3dd0519605Roland McGrath pcnt); 393913b69609bcd5638e6194d940855fea3dd0519605Roland McGrath } 394013b69609bcd5638e6194d940855fea3dd0519605Roland McGrath } 394113b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 394213b69609bcd5638e6194d940855fea3dd0519605Roland McGrath free (segment_flags); 394313b69609bcd5638e6194d940855fea3dd0519605Roland McGrath 3944dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (version_namelist != NULL) 3945dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3946dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym_scnndx == 0) 3947dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3948dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperno .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n")); 3949dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 3950dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_versym (ebl, versym_scnndx); 3951dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3952dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check for duplicate index numbers. */ 3953dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper do 3954dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3955dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist->next; 3956dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 3957dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3958dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (version_namelist->ndx == runp->ndx) 3959dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3960dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("duplicate version index %d\n"), 3961dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper (int) version_namelist->ndx); 3962dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3963dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3964dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 3965dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3966dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3967dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *old = version_namelist; 3968dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper version_namelist = version_namelist->next; 3969dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper free (old); 3970dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3971dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (version_namelist != NULL); 3972dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3973dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (versym_scnndx != 0) 3974dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3975dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n")); 3976dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 39777c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (hash_idx != 0 && gnu_hash_idx != 0) 39787c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper compare_hash_gnu_hash (ebl, ehdr, hash_idx, gnu_hash_idx); 39797c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 3980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (scnref); 3981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 398459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathstatic GElf_Off 398559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathcheck_note_data (Ebl *ebl, const GElf_Ehdr *ehdr, 398659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath Elf_Data *data, int shndx, int phndx, GElf_Off start) 3987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 398859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath size_t offset = 0; 398959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath size_t last_offset = 0; 399059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath GElf_Nhdr nhdr; 399159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath size_t name_offset; 399259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath size_t desc_offset; 399359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath while (offset < data->d_size 399459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath && (offset = gelf_getnote (data, offset, 399559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath &nhdr, &name_offset, &desc_offset)) > 0) 3996b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 399759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath last_offset = offset; 3998b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure it is one of the note types we know about. */ 4000b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_CORE) 400159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath switch (nhdr.n_type) 400259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath { 400359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_PRSTATUS: 400459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_FPREGSET: 400559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_PRPSINFO: 400659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_TASKSTRUCT: /* NT_PRXREG on Solaris. */ 400759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_PLATFORM: 400859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_AUXV: 400959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_GWINDOWS: 401059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_ASRS: 401159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_PSTATUS: 401259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_PSINFO: 401359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_PRCRED: 401459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_UTSNAME: 401559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_LWPSTATUS: 401659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_LWPSINFO: 401759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_PRFPXREG: 401859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath /* Known type. */ 401959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath break; 4020b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 402159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath default: 402259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (shndx == 0) 4023b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 402459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathphdr[%d]: unknown core file note type %" PRIu32 " at offset %" PRIu64 "\n"), 402559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath phndx, (uint32_t) nhdr.n_type, start + offset); 402659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath else 402759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("\ 402859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathsection [%2d] '%s': unknown core file note type %" PRIu32 402959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath " at offset %Zu\n"), 403059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath shndx, section_name (ebl, shndx), 403159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath (uint32_t) nhdr.n_type, offset); 403259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath } 4033b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 403459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath switch (nhdr.n_type) 4035d82217264c4ac9108dbda1502a545ea25f6d22feRoland McGrath { 403659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath case NT_GNU_ABI_TAG: 4037d82217264c4ac9108dbda1502a545ea25f6d22feRoland McGrath case NT_GNU_HWCAP: 4038d82217264c4ac9108dbda1502a545ea25f6d22feRoland McGrath case NT_GNU_BUILD_ID: 4039bc1b92e9aff2595b078b7ffc354e5c2191a2c887Mark Wielaard case NT_GNU_GOLD_VERSION: 4040d82217264c4ac9108dbda1502a545ea25f6d22feRoland McGrath break; 4041d82217264c4ac9108dbda1502a545ea25f6d22feRoland McGrath 4042099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath case 0: 4043099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath /* Linux vDSOs use a type 0 note for the kernel version word. */ 404459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (nhdr.n_namesz == sizeof "Linux" 404559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath && !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux")) 4046099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath break; 4047099dd52727f2ce1a2c73cde82af8cd5e06368aecRoland McGrath 4048d82217264c4ac9108dbda1502a545ea25f6d22feRoland McGrath default: 404959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (shndx == 0) 405059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("\ 405159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathphdr[%d]: unknown object file note type %" PRIu32 " at offset %Zu\n"), 405259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath phndx, (uint32_t) nhdr.n_type, offset); 405359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath else 405459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("\ 405559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathsection [%2d] '%s': unknown object file note type %" PRIu32 405659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath " at offset %Zu\n"), 405759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath shndx, section_name (ebl, shndx), 405859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath (uint32_t) nhdr.n_type, offset); 4059d82217264c4ac9108dbda1502a545ea25f6d22feRoland McGrath } 4060b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4061b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 406259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath return last_offset; 406359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath} 406459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 4065978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 406659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathstatic void 406759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathcheck_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt) 406859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath{ 406959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL 407059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 407159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("\ 407259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathphdr[%d]: no note entries defined for the type of file\n"), 407359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath cnt); 407459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 407559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (is_debuginfo) 407659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath /* The p_offset values in a separate debug file are bogus. */ 407759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath return; 407859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 4079b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (phdr->p_filesz == 0) 4080b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return; 4081b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 408259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath GElf_Off notes_size = 0; 408359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath Elf_Data *data = elf_getdata_rawchunk (ebl->elf, 408459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath phdr->p_offset, phdr->p_filesz, 408559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ELF_T_NHDR); 408659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (data != NULL) 408759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath notes_size = check_note_data (ebl, ehdr, data, 0, cnt, phdr->p_offset); 408859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 408959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (notes_size == 0) 409059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("phdr[%d]: cannot get content of note section: %s\n"), 409159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath cnt, elf_errmsg (-1)); 409259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath else if (notes_size != phdr->p_filesz) 409359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("phdr[%d]: extra %" PRIu64 " bytes after last note\n"), 409459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath cnt, phdr->p_filesz - notes_size); 4095b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 4096b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4097978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 409859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathstatic void 409959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathcheck_note_section (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 410059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath{ 4101b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper if (shdr->sh_size == 0) 4102b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper return; 4103b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper 410459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 410559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (data == NULL) 410659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath { 410759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 410859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath idx, section_name (ebl, idx)); 410959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath return; 411059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath } 411159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 411259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL 411359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 411459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("\ 411559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrathsection [%2d] '%s': no note entries defined for the type of file\n"), 411659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath idx, section_name (ebl, idx)); 411759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 411859ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath GElf_Off notes_size = check_note_data (ebl, ehdr, data, idx, 0, 0); 411959ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath 412059ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath if (notes_size == 0) 412159ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("section [%2d] '%s': cannot get content of note section\n"), 412259ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath idx, section_name (ebl, idx)); 412359ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath else if (notes_size != shdr->sh_size) 412459ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath ERROR (gettext ("section [%2d] '%s': extra %" PRIu64 412559ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath " bytes after last note\n"), 412659ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath idx, section_name (ebl, idx), shdr->sh_size - notes_size); 412759ea7f33f781e6e3f8c9d81d457e5d99eee8f1ceRoland McGrath} 4128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4129978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 4130978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper/* Index of the PT_GNU_EH_FRAME program eader entry. */ 4131978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepperstatic int pt_gnu_eh_frame_pndx; 4132978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 4133978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 4134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 4135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_program_header (Ebl *ebl, GElf_Ehdr *ehdr) 4136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 4137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phoff == 0) 4138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 4139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 4141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_CORE) 4142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperonly executables, shared objects, and core files can have program headers\n")); 4144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_interp = 0; 4146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_tls = 0; 4147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_relro = 0; 4148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4149bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (unsigned int cnt = 0; cnt < phnum; ++cnt) 4150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 4152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr; 4153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 4155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr == NULL) 4156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get program header entry %d: %s\n"), 4158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, elf_errmsg (-1)); 4159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 4160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME 4163f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO 4164f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath /* Check for a known machine-specific type. */ 4165f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL) 4166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4167f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrathprogram header entry %d: unknown program header entry type %#" PRIx64 "\n"), 4168f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath cnt, (uint64_t) phdr->p_type); 4169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_type == PT_LOAD) 4171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_loadable_segment = true; 4172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_INTERP) 4173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_interp != 1) 4175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (num_pt_interp == 2) 4177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermore than one INTERP entry in program header\n")); 4179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_interp_segment = true; 4181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_TLS) 4183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_tls == 2) 4185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("more than one TLS entry in program header\n")); 4186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_NOTE) 4188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_note (ebl, ehdr, phdr, cnt); 418941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else if (phdr->p_type == PT_DYNAMIC) 419041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 419141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (ehdr->e_type == ET_EXEC && ! has_interp_segment) 419241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 419341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic executable cannot have dynamic sections\n")); 419441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else 419541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 419641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Check that the .dynamic section, if it exists, has 419741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper the same address. */ 419841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Scn *scn = NULL; 419941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 420041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 420141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr shdr_mem; 420241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 420341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 420441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 420541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_offset != shdr->sh_offset) 420641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 420741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperdynamic section reference in program header has wrong offset\n")); 420841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_memsz != shdr->sh_size) 420941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 421041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperdynamic section size mismatch in program and section header\n")); 421141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 421241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 421341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 421441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 421541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 4216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_GNU_RELRO) 4217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_relro == 2) 4219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermore than one GNU_RELRO entry in program header\n")); 4221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 4222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check that the region is in a writable segment. */ 4224bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath unsigned int inner; 4225bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (inner = 0; inner < phnum; ++inner) 4226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr2_mem; 4228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr2; 4229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 4231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr2 == NULL) 4232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 4233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr2->p_type == PT_LOAD 4235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && phdr->p_vaddr >= phdr2->p_vaddr 4236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (phdr->p_vaddr + phdr->p_memsz 4237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper <= phdr2->p_vaddr + phdr2->p_memsz)) 4238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((phdr2->p_flags & PF_W) == 0) 4240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloadable segment GNU_RELRO applies to is not writable\n")); 42423a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper if ((phdr2->p_flags & ~PF_W) != (phdr->p_flags & ~PF_W)) 4243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4244d11f9cbecac4a5ac3848a68597028d1924f3ff6bRoland McGrathloadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"), 4245d11f9cbecac4a5ac3848a68597028d1924f3ff6bRoland McGrath cnt, inner); 4246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 4247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4250bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (inner >= phnum) 4251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4252607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper%s segment not contained in a loaded segment\n"), "GNU_RELRO"); 4253607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 4254607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 4255607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper else if (phdr->p_type == PT_PHDR) 4256607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 4257607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that the region is in a writable segment. */ 4258bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath unsigned int inner; 4259bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (inner = 0; inner < phnum; ++inner) 4260607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 4261607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr phdr2_mem; 4262607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr *phdr2; 4263607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 4264607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 4265607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr2 != NULL 4266607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr2->p_type == PT_LOAD 4267607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr >= phdr2->p_vaddr 4268607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && (phdr->p_vaddr + phdr->p_memsz 4269607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper <= phdr2->p_vaddr + phdr2->p_memsz)) 4270607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 4271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4272607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 4273bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (inner >= phnum) 4274607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 4275607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper%s segment not contained in a loaded segment\n"), "PHDR"); 4276607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 4277607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that offset in segment corresponds to offset in ELF 4278607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper header. */ 4279607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr->p_offset != ehdr->e_phoff) 4280607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 4281607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepperprogram header offset in ELF header and PHDR entry do not match")); 4282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 42833a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper else if (phdr->p_type == PT_GNU_EH_FRAME) 42843a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper { 42853a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper /* If there is an .eh_frame_hdr section it must be 42863a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper referenced by this program header entry. */ 42873a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper Elf_Scn *scn = NULL; 4288935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Drepper GElf_Shdr shdr_mem; 4289935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Drepper GElf_Shdr *shdr = NULL; 4290f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper bool any = false; 42913a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 42923a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper { 4293f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper any = true; 4294935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Drepper shdr = gelf_getshdr (scn, &shdr_mem); 4295f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if (shdr != NULL 4296f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper && shdr->sh_type == (is_debuginfo 4297f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ? SHT_NOBITS : SHT_PROGBITS) 42983a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper && ! strcmp (".eh_frame_hdr", 42993a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper elf_strptr (ebl->elf, shstrndx, shdr->sh_name))) 43003a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper { 4301f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if (! is_debuginfo) 4302f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper { 4303f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if (phdr->p_offset != shdr->sh_offset) 4304f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 43053a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Dreppercall frame search table reference in program header has wrong offset\n")); 4306f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if (phdr->p_memsz != shdr->sh_size) 4307f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 43083a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Dreppercall frame search table size mismatch in program and section header\n")); 4309f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper } 43103a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper break; 43113a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper } 43123a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper } 43133a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper 4314f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if (scn == NULL) 4315f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper { 4316f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper /* If there is no section header table we don't 4317f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper complain. But if there is one there should be an 4318f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper entry for .eh_frame_hdr. */ 4319f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if (any) 4320f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 4321f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich DrepperPT_GNU_EH_FRAME present but no .eh_frame_hdr section\n")); 4322f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper } 4323f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper else 4324f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper { 4325f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper /* The section must be allocated and not be writable and 4326f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper executable. */ 4327f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if ((phdr->p_flags & PF_R) == 0) 4328f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 43293a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Dreppercall frame search table must be allocated\n")); 4330f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper else if (shdr != NULL && (shdr->sh_flags & SHF_ALLOC) == 0) 4331f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 4332935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Dreppersection [%2zu] '%s' must be allocated\n"), elf_ndxscn (scn), ".eh_frame_hdr"); 4333935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Drepper 4334f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if ((phdr->p_flags & PF_W) != 0) 4335f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 43363a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Dreppercall frame search table must not be writable\n")); 4337f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper else if (shdr != NULL && (shdr->sh_flags & SHF_WRITE) != 0) 4338f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 4339935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Dreppersection [%2zu] '%s' must not be writable\n"), 4340f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper elf_ndxscn (scn), ".eh_frame_hdr"); 4341935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Drepper 4342f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper if ((phdr->p_flags & PF_X) != 0) 4343f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 43443a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Dreppercall frame search table must not be executable\n")); 4345f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper else if (shdr != NULL && (shdr->sh_flags & SHF_EXECINSTR) != 0) 4346f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper ERROR (gettext ("\ 4347935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Dreppersection [%2zu] '%s' must not be executable\n"), 4348f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper elf_ndxscn (scn), ".eh_frame_hdr"); 4349f93ee8d7dcd0d58f7aab96773af084aca82d5798Ulrich Drepper } 4350978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 4351978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper /* Remember which entry this is. */ 4352978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper pt_gnu_eh_frame_pndx = cnt; 43533a52c7a528e41cc28e69e68ef817f0b2d7f130e5Ulrich Drepper } 4354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 43558190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath if (phdr->p_filesz > phdr->p_memsz 435656bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE)) 4357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: file size greater than memory size\n"), 4359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt); 4360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_align > 1) 4362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!powerof2 (phdr->p_align)) 4364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: alignment not a power of 2\n"), cnt); 4366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0) 4367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 4368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: file offset and virtual address not module of alignment\n"), cnt); 4369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 4372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4374978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepperstatic void 4375935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Dreppercheck_exception_data (Ebl *ebl __attribute__ ((unused)), 4376935eddef3db5cc2fdc317fa943f93502281d3a42Ulrich Drepper GElf_Ehdr *ehdr __attribute__ ((unused))) 4377978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper{ 4378daf0fda7c0e6dcdcc6d011c89a7c6e94ecd238e1Ulrich Drepper if ((ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) 4379daf0fda7c0e6dcdcc6d011c89a7c6e94ecd238e1Ulrich Drepper && pt_gnu_eh_frame_pndx == 0 && eh_frame_hdr_scnndx != 0) 4380daf0fda7c0e6dcdcc6d011c89a7c6e94ecd238e1Ulrich Drepper ERROR (gettext ("executable/DSO with .eh_frame_hdr section does not have " 4381daf0fda7c0e6dcdcc6d011c89a7c6e94ecd238e1Ulrich Drepper "a PT_GNU_EH_FRAME program header entry")); 4382978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper} 4383978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 4384978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 4385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Process one file. */ 4386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 4387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_elf_file (Elf *elf, const char *prefix, const char *suffix, 4388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one) 4389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 4390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Reset variables. */ 4391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ndynamic = 0; 4392acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper nverneed = 0; 4393acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper nverdef = 0; 439441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper textrel = false; 439541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper needed_textrel = false; 4396acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper has_loadable_segment = false; 4397acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper has_interp_segment = false; 4398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr ehdr_mem; 4400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 4401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl; 4402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Print the file name. */ 4404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!only_one) 4405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 4407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("\n%s(%s)%s:\n", prefix, fname, suffix); 4408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 4409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("\n%s:\n", fname); 4410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr == NULL) 4413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 4414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1)); 4415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 4416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 4417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl = ebl_openbackend (elf); 4419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If there is no appropriate backend library we cannot test 4420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper architecture and OS specific features. Any encountered extension 4421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is an error. */ 4422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Go straight by the gABI, check all the parts in turn. */ 4424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_elf_header (ebl, ehdr, size); 4425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the program header. */ 4427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_program_header (ebl, ehdr); 4428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Next the section headers. It is OK if there are no section 4430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper headers at all. */ 4431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_sections (ebl, ehdr); 4432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4433978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper /* Check the exception handling data, if it exists. */ 4434978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper if (pt_gnu_eh_frame_pndx != 0 || eh_frame_hdr_scnndx != 0 4435978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper || eh_frame_scnndx != 0 || gcc_except_table_scnndx != 0) 4436978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper check_exception_data (ebl, ehdr); 4437978360c6ec51192ab7f1333ae9f1c105bcdb5ecdUlrich Drepper 443841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Report if no relocation section needed the text relocation flag. */ 443941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (textrel && !needed_textrel) 444041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("text relocation flag set but not needed\n")); 444141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 4442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Free the resources. */ 4443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_closebackend (ebl); 4444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 44453cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 44463cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 44473cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper#include "debugpred.h" 4448