elflint.c revision b0243863149acde9e42b25688c7c2959830e69a9
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Pedantic checking of ELF files compliance with gABI/psABI spec. 2b770cf9d1045bde04a1d89c63f4d7eb261ff78daUlrich Drepper Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. 3361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper This file is part of Red Hat elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2001. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is free software; you can redistribute it and/or modify 7361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper it under the terms of the GNU General Public License as published by the 8361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Free Software Foundation; version 2 of the License. 9b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 10361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is distributed in the hope that it will be useful, but 11361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 14361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper You should have received a copy of the GNU General Public License along 16361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper with Red Hat elfutils; if not, write to the Free Software Foundation, 171e9ef50681e20ef14c2ba38aef37a71ff148be08Ulrich Drepper Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 18361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 19361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Red Hat elfutils is an included package of the Open Invention Network. 20361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper An included package of the Open Invention Network is a package for which 21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Open Invention Network licensees cross-license their patents. No patent 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper license is granted, either expressly or impliedly, by designation as an 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper included package. Should you wish to participate in the Open Invention 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper Network licensing program, please visit www.openinventionnetwork.com 25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper <http://www.openinventionnetwork.com>. */ 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <byteswap.h> 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <endian.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <gelf.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <inttypes.h> 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h> 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <locale.h> 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/param.h> 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <elf-knowledge.h> 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <system.h> 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "../libebl/libeblP.h" 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program. */ 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state); 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppervoid (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address. */ 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperconst char *argp_program_bug_address = PACKAGE_BUGREPORT; 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ARGP_strict 300 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ARGP_gnuld 301 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions. */ 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] = 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "strict", ARGP_strict, NULL, 0, 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Be extremely strict, flag level 2 features."), 0 }, 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 }, 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 }, 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "gnu-ld", ARGP_gnuld, NULL, 0, 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Binary has been created with GNU ld and is therefore known to be \ 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperbroken in certain ways"), 0 }, 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, NULL, 0 } 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program. */ 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("\ 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperPedantic checking of ELF files compliance with gABI/psABI spec."); 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts. */ 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("FILE..."); 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler. */ 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions. */ 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp = 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper options, parse_opt, args_doc, doc, NULL, NULL, NULL 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Declarations of local functions. */ 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void process_file (int fd, Elf *elf, const char *prefix, 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *suffix, const char *fname, size_t size, 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool only_one); 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void process_elf_file (Elf *elf, const char *prefix, const char *suffix, 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one); 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 126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[]) 129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set locale. */ 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper setlocale (LC_ALL, ""); 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Initialize the message catalog. */ 134b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper textdomain (PACKAGE_TARNAME); 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Parse and process arguments. */ 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int remaining; 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_parse (&argp, argc, argv, 0, &remaining, NULL); 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Before we start tell the ELF library which version we are using. */ 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_version (EV_CURRENT); 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now process all the files given at the command line. */ 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool only_one = remaining + 1 == argc; 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Open the file. */ 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fd = open (argv[remaining], O_RDONLY); 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fd == -1) 150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("cannot open input file")); 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create an `Elf' descriptor. */ 156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf == NULL) 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot generate Elf descriptor: %s\n"), 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int prev_error_count = error_count; 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct stat64 st; 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fstat64 (fd, &st) != 0) 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("cannot stat '%s': %m\n", argv[remaining]); 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size, 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper only_one); 174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now we can close the descriptor. */ 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (elf) != 0) 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("error while closing Elf descriptor: %s\n"), 178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prev_error_count == error_count && !be_quiet) 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper puts (gettext ("No errors")); 182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (++remaining < argc); 187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return error_count != 0; 189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments. */ 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt (int key, char *arg __attribute__ ((unused)), 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct argp_state *state __attribute__ ((unused))) 196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_strict: 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper be_strict = true; 201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'q': 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper be_quiet = true; 205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'd': 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is_debuginfo = true; 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_gnuld: 211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gnuld = true; 212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_KEY_NO_ARGS: 215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fputs (gettext ("Missing file name.\n"), stderr); 216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, 217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper program_invocation_short_name); 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper exit (1); 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information. */ 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 231b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("\ 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCopyright (C) %s Red Hat, Inc.\n\ 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions. There is NO\n\ 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 236b770cf9d1045bde04a1d89c63f4d7eb261ff78daUlrich Drepper"), "2007"); 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Process one file. */ 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_file (int fd, Elf *elf, const char *prefix, const char *suffix, 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one) 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We can handle two types of files: ELF files and archives. */ 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Kind kind = elf_kind (elf); 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (kind) 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_ELF: 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Yes! It's an ELF file. */ 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_elf_file (elf, prefix, suffix, fname, size, only_one); 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_AR: 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *subelf; 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Cmd cmd = ELF_C_READ_MMAP; 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t fname_len = strlen (fname) + 1; 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_prefix[prefix_len + 1 + fname_len]; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2]; 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = new_prefix; 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the full name of the file. */ 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, prefix, prefix_len); 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = '('; 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper strcpy (stpcpy (new_suffix, suffix), ")"); 272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper new_suffix[0] = '\0'; 275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (cp, fname, fname_len); 276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* It's an archive. We process each file in it. */ 278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper kind = elf_kind (subelf); 281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Call this function recursively. */ 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (kind == ELF_K_ELF || kind == ELF_K_AR) 284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Arhdr *arhdr = elf_getarhdr (subelf); 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (arhdr != NULL); 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper process_file (fd, subelf, new_prefix, new_suffix, 289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arhdr->ar_name, arhdr->ar_size, false); 290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get next archive element. */ 293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cmd = elf_next (subelf); 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (subelf) != 0) 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"), 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We cannot do anything. */ 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 30441de488a0ad6679e816dbab960351e5f62ab8eadUlrich DrepperNot an ELF file - it has the wrong magic bytes at the start\n")); 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char * 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_name (Ebl *ebl, int idx) 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr; 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem); 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const int valid_e_machine[] = 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370, 325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC, 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM, 327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300, 328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE, 329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16, 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7, 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX, 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM, 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300, 334c373d850ec9ca342f4c71d5e287c8d8bf0723cd6Roland McGrath EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define nvalid_e_machine \ 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Number of sections. */ 341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic unsigned int shnum; 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size) 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[512]; 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check e_ident field. */ 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG0] != ELFMAG0) 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0); 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG1] != ELFMAG1) 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1); 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG2] != ELFMAG2) 356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2); 357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_MAG3] != ELFMAG3) 358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3); 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_CLASS] != ELFCLASS32 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_CLASS] != ELFCLASS64) 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%d] == %d is no known class\n"), 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_CLASS, ehdr->e_ident[EI_CLASS]); 364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] != ELFDATA2MSB) 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"), 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_DATA, ehdr->e_ident[EI_DATA]); 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"), 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_VERSION, ehdr->e_ident[EI_VERSION]); 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We currently don't handle any OS ABIs. */ 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE) 376e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"), 377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_OSABI, 378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No ABI versions other than zero supported either. */ 381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_ABIVERSION] != 0) 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unsupport ABI version e_ident[%d] == %d\n"), 383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]); 384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt) 386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[cnt] != 0) 387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt); 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_type field. */ 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE) 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type); 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_machine field. */ 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 0; cnt < nvalid_e_machine; ++cnt) 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (valid_e_machine[cnt] == ehdr->e_machine) 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == nvalid_e_machine) 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine); 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_version field. */ 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_version != EV_CURRENT) 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("unknown object file version\n")); 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_phoff and e_phnum fields. */ 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phoff == 0) 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phnum != 0) 409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header offset\n")); 410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) 411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperexecutables and DSOs cannot have zero program header offset\n")); 413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_phnum == 0) 415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid number of program header entries\n")); 416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_shoff field. */ 418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shnum = ehdr->e_shnum; 419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shstrndx = ehdr->e_shstrndx; 420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shoff == 0) 421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shnum != 0) 423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header table offset\n")); 424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_CORE) 426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section header table must be present\n")); 427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shnum == 0) 431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the header of the zeroth section. The sh_size field 433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might contain the section number. */ 434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 435acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr != NULL) 437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The error will be reported later. */ 439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size == 0) 440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperinvalid number of section header table entries\n")); 442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shnum = shdr->sh_size; 444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shstrndx == SHN_XINDEX) 448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the header of the zeroth section. The sh_size field 450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might contain the section number. */ 451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 452acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 453acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (shdr != NULL && shdr->sh_link < shnum) 454acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper shstrndx = shdr->sh_link; 455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (shstrndx >= shnum) 457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header index\n")); 458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the e_flags field. */ 461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!ebl_machine_flag_check (ebl, ehdr->e_flags)) 462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid machine flags: %s\n"), 463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check e_ehsize, e_phentsize, and e_shentsize fields. */ 466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gelf_getclass (ebl->elf) == ELFCLASS32) 467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr)) 469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr)) 472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header size: %hd\n"), 473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_phentsize); 474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size) 475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header position or size\n")); 476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr)) 478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header size: %hd\n"), 479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_shentsize); 480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header position or size\n")); 482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (gelf_getclass (ebl->elf) == ELFCLASS64) 484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr)) 486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr)) 489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header size: %hd\n"), 490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_phentsize); 491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size) 492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid program header position or size\n")); 493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr)) 495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header size: %hd\n"), 496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr->e_shentsize); 497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("invalid section header position or size\n")); 499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check that there is a section group section with index < IDX which 504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper contains section IDX and that there is exactly one. */ 505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_scn_group (Ebl *ebl, int idx) 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnref[idx] == 0) 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No reference so far. Search following sections, maybe the 511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper order is wrong. */ 512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = idx + 1; cnt < shnum; ++cnt) 515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 516acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Scn *scn = elf_getscn (ebl->elf, cnt); 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 518acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We cannot get the section header so we cannot check it. 521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper The error to get the section header will be shown 522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper somewhere else. */ 523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type != SHT_GROUP) 526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 528acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL || data->d_size < sizeof (Elf32_Word)) 530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cannot check the section. */ 531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 533acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf32_Word *grpdata = (Elf32_Word *) data->d_buf; 534acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word); 535acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ++inner) 536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (grpdata[inner] == (Elf32_Word) idx) 537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto out; 538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out: 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == shnum) 542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"), 544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group [%2zu] '%s' does not preceed group member\n"), 548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 555dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool no_xndx_warned = false; 558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int no_pt_tls = 0; 559dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 567dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr strshdr_mem; 568dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 569dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper &strshdr_mem); 570dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (strshdr == NULL) 571dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 572dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link), 576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Search for an extended section index table section. */ 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *xndxdata = NULL; 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndxscnidx = 0; 582acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper bool found_xndx = false; 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < shnum; ++cnt) 584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt != (size_t) idx) 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt); 587acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr xndxshdr_mem; 588acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); 589acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (xndxshdr == NULL) 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && xndxshdr->sh_link == (GElf_Word) idx) 594acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 595acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (found_xndx) 596acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 597acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': symbol table cannot have more than one extended index section\n"), 598acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 599acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 600acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper xndxdata = elf_getdata (xndxscn, NULL); 601acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper xndxscnidx = elf_ndxscn (xndxscn); 602acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper found_xndx = true; 603acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)) 607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': entry size is does not match ElfXX_Sym\n"), 609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Test the zeroth entry. */ 612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym_mem; 613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndx; 614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx); 615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"), 617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 0, elf_errmsg (-1)); 618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_name != 0) 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_name"); 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value != 0) 624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_value"); 626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_size != 0) 627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_size"); 629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_info != 0) 630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_info"); 632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_other != 0) 633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_other"); 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != 0) 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), "st_shndx"); 638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxdata != NULL && xndx != 0) 639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': XINDEX for zeroth entry not zero\n"), 641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndxscnidx, section_name (ebl, xndxscnidx)); 642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx); 647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"), 650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name = NULL; 655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_name >= strshdr->sh_size) 656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: invalid name value\n"), 658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name); 662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (name != NULL); 663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx == SHN_XINDEX) 666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndxdata == NULL) 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"), 671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper no_xndx_warned = true; 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (xndx < SHN_LORESERVE) 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"), 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndxscnidx, section_name (ebl, xndxscnidx), cnt, 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndx); 679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((sym->st_shndx >= SHN_LORESERVE 681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // && sym->st_shndx <= SHN_HIRESERVE always true 682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym->st_shndx != SHN_ABS 683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym->st_shndx != SHN_COMMON) 684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (sym->st_shndx >= shnum 685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (sym->st_shndx < SHN_LORESERVE 686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* || sym->st_shndx > SHN_HIRESERVE always false */))) 687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: invalid section index\n"), 689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xndx = sym->st_shndx; 692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 69318e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath if (GELF_ST_TYPE (sym->st_info) >= STT_NUM 69418e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0)) 695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"), 696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_BIND (sym->st_info) >= STB_NUM) 699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: unknown symbol binding\n"), 701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndx == SHN_COMMON) 704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Common symbols can only appear in relocatable files. */ 706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"), 709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt < shdr->sh_info) 711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"), 713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_R_TYPE (sym->st_info) == STT_FUNC) 715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"), 717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (xndx > 0 && xndx < shnum) 720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr destshdr_mem; 722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *destshdr; 723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem); 725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (destshdr != NULL) 726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_TYPE (sym->st_info) != STT_TLS) 728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 729c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (! ebl_check_special_symbol (ebl, ehdr, sym, name, 730c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper destshdr)) 731c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper { 732c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if ((sym->st_value - destshdr->sh_addr) 733c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper > destshdr->sh_size) 734ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper { 735ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper /* GNU ld has severe bugs. When it decides to remove 736ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper empty sections it leaves symbols referencing them 737ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper behind. These are symbols in .symtab. */ 738ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper if (!gnuld 739ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper || strcmp (section_name (ebl, idx), ".symtab") 740ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper || (strcmp (name, "__preinit_array_start") != 0 741ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__preinit_array_end") != 0 742ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__init_array_start") != 0 743ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__init_array_end") != 0 744ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__fini_array_start") != 0 745ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper && strcmp (name, "__fini_array_end") != 0)) 746ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper ERROR (gettext ("\ 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds\n"), 748ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper idx, section_name (ebl, idx), cnt); 749ce0bdb6ee5f977af9e565f2871ba2b1b37d162a5Ulrich Drepper } 750c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper else if ((sym->st_value - destshdr->sh_addr 751c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper + sym->st_size) > destshdr->sh_size) 752c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 754c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), cnt, 755c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (int) xndx, section_name (ebl, xndx)); 756c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((destshdr->sh_flags & SHF_TLS) == 0) 761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"), 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL) 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* For object files the symbol value must fall 769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper into the section. */ 770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value > destshdr->sh_size) 771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (sym->st_value + sym->st_size 776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > destshdr->sh_size) 777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 781b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 783b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 784b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr = NULL; 786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int pcnt; 787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr != NULL && phdr->p_type == PT_TLS) 792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (pcnt == ehdr->e_phnum) 796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (no_pt_tls++ == 0) 798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"), 800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value 805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < destshdr->sh_offset - phdr->p_offset) 806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"), 808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (sym->st_value 811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > (destshdr->sh_offset - phdr->p_offset 812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + destshdr->sh_size)) 813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 814b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 815b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (sym->st_value + sym->st_size 818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > (destshdr->sh_offset - phdr->p_offset 819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + destshdr->sh_size)) 820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 828b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt >= shdr->sh_info) 833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 834b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"), 835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt < shdr->sh_info) 840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"), 842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 845b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_TYPE (sym->st_info) == STT_SECTION 846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 847b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local section symbol\n"), 849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (name != NULL) 852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 855653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* Check that address and size match the global offset table. */ 856653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 857653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Shdr destshdr_mem; 858653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), 859653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath &destshdr_mem); 860653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 861653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr == NULL && xndx == SHN_ABS) 862b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 863653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* In a DSO, we have to find the GOT section by name. */ 864653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath Elf_Scn *gotscn = NULL; 865c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper Elf_Scn *gscn = NULL; 866653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL) 867b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 868653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = gelf_getshdr (gscn, &destshdr_mem); 869653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath assert (destshdr != NULL); 870653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const char *sname = elf_strptr (ebl->elf, 871653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ehdr->e_shstrndx, 872653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr->sh_name); 873653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (sname != NULL) 874b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 875c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (sname, ".got.plt") == 0) 876653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath break; 877c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (sname, ".got") == 0) 878653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* Do not stop looking. 879653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath There might be a .got.plt section. */ 880653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath gotscn = gscn; 881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 882653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 883653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = NULL; 884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 885653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 886653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr == NULL && gotscn != NULL) 887653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = gelf_getshdr (gotscn, &destshdr_mem); 888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 890653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const char *sname = (destshdr == NULL ? NULL 891653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath : elf_strptr (ebl->elf, ehdr->e_shstrndx, 892653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr->sh_name)); 893653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (sname == NULL) 894653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ERROR (gettext ("\ 895653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section\n"), 896653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath idx, section_name (ebl, idx)); 897653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath else if (strcmp (sname, ".got.plt") != 0 898653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath && strcmp (sname, ".got") != 0) 899653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ERROR (gettext ("\ 900653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to '%s' section\n"), 901653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath idx, section_name (ebl, idx), sname); 902653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 903653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr != NULL) 904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found it. */ 906c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (!ebl_check_special_symbol (ebl, ehdr, sym, name, 907c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper destshdr)) 908c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper { 909c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (sym->st_value != destshdr->sh_addr) 910c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper /* This test is more strict than the psABIs which 911c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper usually allow the symbol to be in the middle of 912c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper the .got section, allowing negative offsets. */ 913c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 914653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"), 915c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), 916c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (uint64_t) sym->st_value, 917c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper sname, (uint64_t) destshdr->sh_addr); 918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 919c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (!gnuld && sym->st_size != destshdr->sh_size) 920c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 921653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"), 922c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), 923c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (uint64_t) sym->st_size, 924c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper sname, (uint64_t) destshdr->sh_size); 925c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 928b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 929b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"), 930b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (strcmp (name, "_DYNAMIC") == 0) 93341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Check that address and size match the dynamic section. 93441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper We locate the dynamic section via the program header 93541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper entry. */ 93641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper for (int pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 93741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 93841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr phdr_mem; 93941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 940b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 94141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 94241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 94341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (sym->st_value != phdr->p_vaddr) 94441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 945b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"), 94641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), 94741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) sym->st_value, 94841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) phdr->p_vaddr); 949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 95041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (!gnuld && sym->st_size != phdr->p_memsz) 95141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"), 95341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), 95441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) sym->st_size, 95541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) phdr->p_memsz); 956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 95741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 95841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 960b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 961b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 962b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 963b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 964b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 965b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool 966c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperis_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr, 96728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper bool is_rela) 968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If this is no executable or DSO it cannot be a .rel.dyn section. */ 970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 971b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the section name. Unfortunately necessary. */ 97428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn")) 975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 977b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section 978b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper entry can be present as well. */ 979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr rcshdr_mem; 983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem); 984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (rcshdr != NULL); 985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rcshdr->sh_type == SHT_DYNAMIC) 987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 988b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found the dynamic section. Look through it. */ 989b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *d = elf_getdata (scn, NULL); 990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 991b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 992b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt) 993b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 994b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn dyn_mem; 995b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem); 996b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (dyn != NULL); 997b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 998b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_RELCOUNT) 999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 100028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Found it. Does the type match. */ 100128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (is_rela) 1002b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 100328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELCOUNT used for this RELA section\n"), 100428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 100528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 100628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 100728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Does the number specified number of relative 100828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations exceed the total number of 100928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations? */ 101028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 101128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 1012b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 101328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 101428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 101528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 101628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Make sure the specified number of relocations are 101728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relative. */ 101828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, 101928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx), NULL); 102028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (reldata != NULL) 102128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (size_t inner = 0; 102228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner < shdr->sh_size / shdr->sh_entsize; 102328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++inner) 102428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 102528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rel rel_mem; 102628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rel *rel = gelf_getrel (reldata, inner, 102728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper &rel_mem); 102828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (rel == NULL) 102928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The problem will be reported elsewhere. */ 103028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 103128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 103228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_relative_reloc_p (ebl, 103328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GELF_R_TYPE (rel->r_info))) 103428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 103528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (inner >= dyn->d_un.d_val) 103628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 103728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), 103828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 103928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 104028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 104128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (inner < dyn->d_un.d_val) 104228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 104328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), 104428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 104528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner, (int) dyn->d_un.d_val); 104628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 104728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 104828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 104928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 105028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn->d_tag == DT_RELACOUNT) 105128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 105228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Found it. Does the type match. */ 105328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (!is_rela) 105428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 105528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELACOUNT used for this REL section\n"), 105628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 105728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 105828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 105928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Does the number specified number of relative 106028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations exceed the total number of 106128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations? */ 106228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 106328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 106428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 106528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 106628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 106728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 106828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Make sure the specified number of relocations are 106928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relative. */ 107028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, 107128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx), NULL); 107228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (reldata != NULL) 107328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (size_t inner = 0; 107428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner < shdr->sh_size / shdr->sh_entsize; 107528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++inner) 107628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 107728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rela rela_mem; 107828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rela *rela = gelf_getrela (reldata, inner, 107928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper &rela_mem); 108028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (rela == NULL) 108128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The problem will be reported elsewhere. */ 108228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 108328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 108428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_relative_reloc_p (ebl, 108528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GELF_R_TYPE (rela->r_info))) 108628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 108728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (inner >= dyn->d_un.d_val) 108828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 108928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), 109028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 109128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 109228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 109328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (inner < dyn->d_un.d_val) 109428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 109528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), 109628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 109728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner, (int) dyn->d_un.d_val); 109828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 109928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 1100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 1108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 111141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstruct loaded_segment 111241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper{ 111341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Addr from; 111441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Addr to; 111541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper bool read_only; 111641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *next; 111741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper}; 111841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 111941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 112041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper/* Check whether binary has text relocation flag set. */ 112141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool textrel; 112241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 112341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper/* Keep track of whether text relocation flag is needed. */ 112441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool needed_textrel; 112541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 112641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1127c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic bool 1128c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr, 1129c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper int idx, int reltype, GElf_Shdr **destshdrp, 113041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp) 1131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool reldyn = false; 1133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether the link to the section we relocate is reasonable. */ 1135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info >= shnum) 1136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), 1137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1138c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper else if (shdr->sh_info != 0) 1139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1140c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1141c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper destshdr_memp); 1142c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (*destshdrp != NULL) 1143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1144c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if((*destshdrp)->sh_type != SHT_PROGBITS 1145c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && (*destshdrp)->sh_type != SHT_NOBITS) 1146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); 1148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!reldyn) 1149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': invalid destination section type\n"), 1151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1154c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* There is no standard, but we require that .rel{,a}.dyn 1155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sections have a sh_info value of zero. */ 1156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': sh_info should be zero\n"), 1159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1163c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) 1164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': no relocations for merge-able sections possible\n"), 1166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1170c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT)) 1171c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext (reltype == ELF_T_RELA ? "\ 1172c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ 1173c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rel\n"), 1174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 117641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* In preparation of checking whether relocations are text 117741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper relocations or not we need to determine whether the file is 117841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper flagged to have text relocation and we need to determine a) what 117941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper the loaded segments are and b) which are read-only. This will 118041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper also allow us to determine whether the same reloc section is 118141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper modifying loaded and not loaded segments. */ 118241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper for (int i = 0; i < ehdr->e_phnum; ++i) 118341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 118441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr phdr_mem; 118541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 118641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr == NULL) 118741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper continue; 118841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 118941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_type == PT_LOAD) 119041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 119141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *newp = xmalloc (sizeof (*newp)); 119241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->from = phdr->p_vaddr; 119341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->to = phdr->p_vaddr + phdr->p_memsz; 119441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->read_only = (phdr->p_flags & PF_W) == 0; 119541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->next = *loadedp; 119641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper *loadedp = newp; 119741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 119841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else if (phdr->p_type == PT_DYNAMIC) 119941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 120041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset); 120141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr dynshdr_mem; 120241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem); 120341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Data *dyndata = elf_getdata (dynscn, NULL); 120441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC 120541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && dyndata != NULL) 120641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j) 120741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 120841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Dyn dyn_mem; 120941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem); 121041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (dyn != NULL 121141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && (dyn->d_tag == DT_TEXTREL 121241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper || (dyn->d_tag == DT_FLAGS 121341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && (dyn->d_un.d_val & DF_TEXTREL) != 0))) 121441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 121541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper textrel = true; 121641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 121741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 121841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 121941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 122041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 122141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 122241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* A quick test which can be easily done here (although it is a bit 122341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper out of place): the text relocation flag makes only sense if there 122441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper is a segment which is not writable. */ 122541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (textrel) 122641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 122741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *seg = *loadedp; 122841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (seg != NULL && !seg->read_only) 122941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper seg = seg->next; 123041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (seg == NULL) 123141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 123241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppertext relocation flag set but there is no read-only segment\n")); 123341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 123441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1235c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper return reldyn; 1236c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper} 1237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 123941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperenum load_state 124041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 124141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_undecided, 124241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_loaded, 124341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_unloaded, 124441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_error 124541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper }; 124641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 124741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1248c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic void 1249607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppercheck_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx, 1250607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata, 1251607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Addr r_offset, GElf_Xword r_info, 125241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper const GElf_Shdr *destshdr, bool reldyn, 125341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded, enum load_state *statep) 1254c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper{ 1255c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool known_broken = gnuld; 1256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1257c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info))) 1258c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), 1259c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1260607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1261607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* The executable/DSO can contain relocation sections with 1262607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper all the relocations the linker has applied. Those sections 1263607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper are marked non-loaded, though. */ 1264607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper || (relshdr->sh_flags & SHF_ALLOC) != 0) 1265607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info))) 1266c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), 1268c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1270c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (symshdr != NULL 1271c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && ((GELF_R_SYM (r_info) + 1) 1272c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) 1273c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper > symshdr->sh_size)) 1274c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: invalid symbol index\n"), 1276c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 12786ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper /* No more tests if this is a no-op relocation. */ 12796ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper if (ebl_none_reloc_p (ebl, GELF_R_TYPE (r_info))) 12806ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper return; 12816ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper 1282c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info))) 1283c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1284c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper const char *name; 1285c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper char buf[64]; 1286c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Sym sym_mem; 1287c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 1288c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (sym != NULL 1289c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Get the name for the symbol. */ 1290c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) 1291c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) 1292c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), 1294c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt, 1295c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ebl_reloc_type_name (ebl, GELF_R_SYM (r_info), 1296c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper buf, sizeof (buf))); 1297c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1299c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (reldyn) 1300c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1301c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper // XXX TODO Check .rel.dyn section addresses. 1302c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1303c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper else if (!known_broken) 1304c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1305c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (destshdr != NULL 1306c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && GELF_R_TYPE (r_info) != 0 1307c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && (r_offset - destshdr->sh_addr) >= destshdr->sh_size) 1308c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: offset out of bounds\n"), 1310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1311c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 131341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Sym sym_mem; 131441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 131541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 131641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info)) 1317c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Make sure the referenced symbol is an object or unspecified. */ 131841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && sym != NULL 131941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE 132041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) 132141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 132241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper char buf[64]; 132341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), 132441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), cnt, 132541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 132641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper buf, sizeof (buf))); 132741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 132841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1329038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1330038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper || (relshdr->sh_flags & SHF_ALLOC) != 0) 133141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 1332038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper bool in_loaded_seg = false; 1333038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper while (loaded != NULL) 1334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1335038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (r_offset < loaded->to 1336038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from) 133741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 1338038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper /* The symbol is in this segment. */ 1339038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (loaded->read_only) 1340038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1341038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (textrel) 1342038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper needed_textrel = true; 1343038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper else 1344038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"), 1345038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx), cnt); 1346038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper } 1347038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper 1348038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper in_loaded_seg = true; 134941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 135041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1351038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper loaded = loaded->next; 1352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 135341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1354038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (*statep == state_undecided) 1355038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper *statep = in_loaded_seg ? state_loaded : state_unloaded; 1356038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper else if ((*statep == state_unloaded && in_loaded_seg) 1357038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper || (*statep == state_loaded && !in_loaded_seg)) 1358038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1359038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("\ 136041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': relocations are against loaded and unloaded data\n"), 1361038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx)); 1362038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper *statep = state_error; 1363038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper } 1364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1369c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1371c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1379c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Check the fields of the section header. */ 1380c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr destshdr_mem; 1381c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *destshdr = NULL; 138241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded = NULL; 1383c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr, 138441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper &destshdr_mem, &loaded); 1385c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1386c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1387c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr symshdr_mem; 1388c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1389c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 139041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper enum load_state state = state_undecided; 1391c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1392c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1394c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rela rela_mem; 1395c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem); 1396c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (rela == NULL) 1397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1398c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1399c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"), 1400c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1401c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper continue; 1402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1403c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1404607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1405607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper rela->r_offset, rela->r_info, destshdr, reldyn, loaded, 1406607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper &state); 140741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 140841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 140941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 141041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 141141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *old = loaded; 141241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper loaded = loaded->next; 141341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper free (old); 1414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1415c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper} 1416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1417c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1418c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic void 1419c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1420c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper{ 1421c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1422c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (data == NULL) 1423c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1424c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1425c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx)); 1426c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper return; 1427c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1428c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1429c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Check the fields of the section header. */ 1430c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr destshdr_mem; 1431c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *destshdr = NULL; 143241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded = NULL; 1433c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr, 143441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper &destshdr_mem, &loaded); 1435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 1438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 144041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper enum load_state state = state_undecided; 1441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1442c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel rel_mem; 1445c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem); 1446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rel == NULL) 1447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"), 1450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1454607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1455607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper rel->r_offset, rel->r_info, destshdr, reldyn, loaded, 1456607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper &state); 145741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 145841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 145941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 146041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 146141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *old = loaded; 146241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper loaded = loaded->next; 146341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper free (old); 1464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Number of dynamic sections. */ 1469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int ndynamic; 1470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1473607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppercheck_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data; 1476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr strshdr_mem; 1477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *strshdr; 1478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 1479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool dependencies[DT_NUM][DT_NUM] = 1480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_NEEDED] = { [DT_STRTAB] = true }, 1482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_PLTRELSZ] = { [DT_JMPREL] = true }, 1483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_HASH] = { [DT_SYMTAB] = true }, 1484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRTAB] = { [DT_STRSZ] = true }, 1485231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_SYMENT] = true }, 1486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true }, 1487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELASZ] = { [DT_RELA] = true }, 1488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELAENT] = { [DT_RELA] = true }, 1489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRSZ] = { [DT_STRTAB] = true }, 1490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMENT] = { [DT_SYMTAB] = true }, 1491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SONAME] = { [DT_STRTAB] = true }, 1492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RPATH] = { [DT_STRTAB] = true }, 1493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true }, 1494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELSZ] = { [DT_REL] = true }, 1495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELENT] = { [DT_REL] = true }, 1496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true }, 1497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RUNPATH] = { [DT_STRTAB] = true }, 1498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_PLTREL] = { [DT_JMPREL] = true }, 1499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_PLTRELSZ] = { [DT_JMPREL] = true } 1500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool has_dt[DT_NUM]; 1502231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper bool has_val_dt[DT_VALNUM]; 1503231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper bool has_addr_dt[DT_ADDRNUM]; 1504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool level2[DT_NUM] = 1505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RPATH] = true, 1507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMBOLIC] = true, 1508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_TEXTREL] = true, 1509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_BIND_NOW] = true 1510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool mandatory[DT_NUM] = 1512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_NULL] = true, 1514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRTAB] = true, 1515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMTAB] = true, 1516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRSZ] = true, 1517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMENT] = true 1518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Addr reladdr = 0; 1520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word relsz = 0; 1521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Addr pltreladdr = 0; 1522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word pltrelsz = 0; 1523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memset (has_dt, '\0', sizeof (has_dt)); 1525231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper memset (has_val_dt, '\0', sizeof (has_val_dt)); 1526231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper memset (has_addr_dt, '\0', sizeof (has_addr_dt)); 1527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++ndynamic == 2) 1529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("more than one dynamic section present\n")); 1530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 153141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem); 1540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB) 1541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 1543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link), 1544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT)) 1547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Dyn\n"), 1549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool non_null_warned = false; 1556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn dyn_mem; 1559acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem); 1560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn == NULL) 1561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get dynamic section entry %zu: %s\n"), 1564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned) 1569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"), 1572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper non_null_warned = true; 1574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!ebl_dynamic_tag_check (ebl, dyn->d_tag)) 1577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"), 1578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM) 1581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[dyn->d_tag] 1583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_NEEDED 1584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_NULL 1585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_POSFLAG_1) 1586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: more than one entry with tag %s\n"), 1590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, 1592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf, sizeof (buf))); 1593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (be_strict && level2[dyn->d_tag]) 1596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: level 2 tag %s used\n"), 1600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, 1602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf, sizeof (buf))); 1603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_dt[dyn->d_tag] = true; 1606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1607231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper else if (dyn->d_tag <= DT_VALRNGHI 1608231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper && DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) 1609231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper has_val_dt[DT_VALTAGIDX (dyn->d_tag)] = true; 1610231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper else if (dyn->d_tag <= DT_ADDRRNGHI 1611231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper && DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) 1612231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper has_addr_dt[DT_ADDRTAGIDX (dyn->d_tag)] = true; 1613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL 1615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_un.d_val != DT_RELA) 1616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"), 1618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_REL) 1621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reladdr = dyn->d_un.d_ptr; 1622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_RELSZ) 1623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper relsz = dyn->d_un.d_val; 1624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_JMPREL) 1625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper pltreladdr = dyn->d_un.d_ptr; 1626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_PLTRELSZ) 1627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper pltrelsz = dyn->d_un.d_val; 1628607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1629607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that addresses for entries are in loaded segments. */ 1630607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper switch (dyn->d_tag) 1631607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1632607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper size_t n; 1633cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_STRTAB: 1634cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper /* We require the referenced section is the same as the one 1635cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper specified in sh_link. */ 1636cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (strshdr->sh_addr != dyn->d_un.d_val) 1637cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper { 1638cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("\ 1639cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '%s' referenced by sh_link\n"), 1640cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), cnt, 1641cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 1642cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1643cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper } 1644cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper goto check_addr; 1645cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1646607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper default: 1647607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI) 1648607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Value is no pointer. */ 1649607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 1650607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* FALLTHROUGH */ 1651607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1652cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_AUXILIARY: 1653cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FILTER: 1654cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FINI: 1655cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FINI_ARRAY: 1656607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_HASH: 1657607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_INIT: 1658607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_INIT_ARRAY: 1659cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_JMPREL: 1660cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_PLTGOT: 1661cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_REL: 1662cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RELA: 1663cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SYMBOLIC: 1664cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SYMTAB: 1665607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_VERDEF: 1666607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_VERNEED: 1667cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_VERSYM: 1668cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper check_addr: 1669607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper for (n = 0; n < ehdr->e_phnum; ++n) 1670607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1671607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr phdr_mem; 1672607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem); 1673607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr != NULL && phdr->p_type == PT_LOAD 1674607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr <= dyn->d_un.d_ptr 1675607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr) 1676607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 1677607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1678607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (unlikely (n >= ehdr->e_phnum)) 1679607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1680607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper char buf[50]; 1681607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 1682607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': entry %zu: %s value must point into loaded segment\n"), 1683607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper idx, section_name (ebl, idx), cnt, 1684607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1685607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper sizeof (buf))); 1686607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1687cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1688cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1689cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_NEEDED: 1690cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RPATH: 1691cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RUNPATH: 1692cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SONAME: 1693cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (dyn->d_un.d_ptr >= strshdr->sh_size) 1694cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper { 1695cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper char buf[50]; 1696cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("\ 1697cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': entry %zu: %s value must be valid offset in section [%2d] '%s'\n"), 1698cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), cnt, 1699cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1700cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper sizeof (buf)), 1701cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 1702cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper } 1703cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1704607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < DT_NUM; ++cnt) 1708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[cnt]) 1709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1710acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (int inner = 0; inner < DT_NUM; ++inner) 1711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dependencies[cnt][inner] && ! has_dt[inner]) 1712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf1[50]; 1714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf2[50]; 1715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': contains %s entry but not %s\n"), 1718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)), 1720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2))); 1721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (mandatory[cnt]) 1726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1729b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': mandatory tag %s not present\n"), 1730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf))); 1732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1735231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* Make sure we have an hash table. */ 1736231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_dt[DT_HASH] && !has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)]) 1737231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1738231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': no hash section present\n"), 1739231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1740231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1741231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* The GNU-style hash table also needs a symbol table. */ 1742231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_dt[DT_HASH] && has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)] 1743231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper && !has_dt[DT_SYMTAB]) 1744231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1745231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': contains %s entry but not %s\n"), 1746231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), 1747231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper "DT_GNU_HASH", "DT_SYMTAB"); 1748231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the rel/rela tags. At least one group must be available. */ 1750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT]) 1751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT])) 1752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper "DT_RELA", "DT_RELASZ", "DT_RELAENT"); 1756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT]) 1758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT])) 1759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper "DT_REL", "DT_RELSZ", "DT_RELENT"); 1763231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1764231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* Check that all prelink sections are present if any of them is. */ 1765231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)] 1766231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper || has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)]) 1767231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper { 1768231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)]) 1769231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1770231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in DSO marked during prelinking\n"), 1771231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_PRELINKED"); 1772231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)]) 1773231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1774231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in DSO marked during prelinking\n"), 1775231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_CHECKSUM"); 1776231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1777231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper /* Only DSOs can be marked like this. */ 1778231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (ehdr->e_type != ET_DYN) 1779231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1780231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': non-DSO file marked as dependency during prelink\n"), 1781231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx)); 1782231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1783231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper 1784231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)] 1785231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper || has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)] 1786231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)] 1787231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)]) 1788231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper { 1789231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)]) 1790231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1791231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in prelinked executable\n"), 1792231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_CONFLICTSZ"); 1793231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)]) 1794231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1795231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in prelinked executable\n"), 1796231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_LIBLISTSZ"); 1797231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)]) 1798231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1799231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in prelinked executable\n"), 1800231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_CONFLICT"); 1801231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)]) 1802231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper ERROR (gettext ("\ 1803231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Dreppersection [%2d] '%s': %s tag missing in prelinked executable\n"), 1804231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper idx, section_name (ebl, idx), "DT_GNU_LIBLIST"); 1805231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper } 1806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1810acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1812acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type != ET_REL) 1813acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 1814acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 1815acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': only relocatable files can have extended section index\n"), 1816acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 1817acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 1818acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 1819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1820acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1821acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr symshdr_mem; 1822acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB) 1824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended section index section not for symbol table\n"), 1826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1827acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 1828b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symdata == NULL) 1829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get data for symbol section\n")); 1830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != sizeof (Elf32_Word)) 1832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry size does not match Elf32_Word\n"), 1834b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL 1837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_size / shdr->sh_entsize 1838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < symshdr->sh_size / symshdr->sh_entsize)) 1839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended index table too small for symbol table\n"), 1841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1845b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1847acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = idx + 1; cnt < shnum; ++cnt) 1848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr rshdr_mem; 1850acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem); 1851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX 1852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && rshdr->sh_link == shdr->sh_link) 1853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1855b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"), 1856b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1857b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 1858b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1860b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1861b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1862acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1863b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1864b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (*((Elf32_Word *) data->d_buf) != 0) 1865b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("symbol 0 should have zero extended section index\n")); 1866b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1867acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1869b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt]; 1870b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndx != 0) 1872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1873b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym_data; 1874b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data); 1875b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 1876b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get data for symbol %zu\n"), cnt); 1878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != SHN_XINDEX) 1882b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1883b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperextended section index is %" PRIu32 " but symbol index is not XINDEX\n"), 1884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (uint32_t) xndx); 1885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1887b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 189128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 189228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 189328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 189428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 189528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 189628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 189728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 189828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 189928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 190028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 190128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 190228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 190328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t maxidx = nchain; 190428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 190528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL) 190628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 190728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 190828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 190928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (nchain > symshdr->sh_size / symshdr->sh_entsize) 191028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("section [%2d] '%s': chain array too large\n"), 191128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 191228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 191328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = symsize; 191428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 191528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 191628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 191728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (cnt = 2; cnt < 2 + nbucket; ++cnt) 191828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx) 191928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 192028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash bucket reference %zu out of bounds\n"), 192128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2); 192228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 192328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (; cnt < 2 + nbucket + nchain; ++cnt) 192428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx) 192528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 192628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain reference %zu out of bounds\n"), 192728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2 - nbucket); 192828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 192928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 193028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 193128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 193228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 193328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 193428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 193528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; 193628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; 193728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 193828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 193928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 194028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 194128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 194228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 194328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 194428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t maxidx = nchain; 194528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 194628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL) 194728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 194828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 194928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 195028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (nchain > symshdr->sh_size / symshdr->sh_entsize) 195128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("section [%2d] '%s': chain array too large\n"), 195228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 195328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 195428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = symsize; 195528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 195628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 195728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 195828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (cnt = 2; cnt < 2 + nbucket; ++cnt) 195928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx) 196028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 196128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash bucket reference %zu out of bounds\n"), 196228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2); 196328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 196428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (; cnt < 2 + nbucket + nchain; ++cnt) 196528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx) 196628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 1967dcf6160602985e6eb70c96c6546ed9614a414d98Ulrich Dreppersection [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"), 1968dcf6160602985e6eb70c96c6546ed9614a414d98Ulrich Drepper idx, section_name (ebl, idx), (uint64_t) (cnt - 2 - nbucket)); 196928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 197028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 197128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 197228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 197328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 197428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 197528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 197628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0]; 197728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; 19788ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; 197928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 19808ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (!powerof2 (bitmask_words)) 19818ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 19828ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': bitmask size not power of 2: %u\n"), 19838ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), bitmask_words); 19848ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 19858ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t bitmask_idxmask = bitmask_words - 1; 19868ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (gelf_getclass (ebl->elf) == ELFCLASS64) 19878ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper bitmask_words *= 2; 19888ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; 19898ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 19908ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shdr->sh_size < (4 + bitmask_words + nbuckets) * sizeof (Elf32_Word)) 199128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 199228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 199328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected at least%ld)\n"), 199428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 19958ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper (long int) ((4 + bitmask_words + nbuckets) * sizeof (Elf32_Word))); 199628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return; 199728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 199828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 19998ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shift > 31) 20008ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 20018ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': 2nd hash function shift too big: %u\n"), 20028ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), shift); 20038ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 20048ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words 20058ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + nbuckets); 200628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 200728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL) 200828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize); 200928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 201028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* We need the symbol section data. */ 201128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL); 201228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 20138ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper union 20148ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 20158ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word *p32; 20168ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf64_Xword *p64; 20178ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } bitmask = { .p32 = &((Elf32_Word *) data->d_buf)[4] }, 20188ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected = { .p32 = xcalloc (bitmask_words, sizeof (Elf32_Word)) }; 20198ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 20208ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t classbits = gelf_getclass (ebl->elf) == ELFCLASS32 ? 32 : 64; 20218ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 202228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 20238ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper for (cnt = 4 + bitmask_words; cnt < 4 + bitmask_words + nbuckets; ++cnt) 202428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 20258ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt]; 202628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 202728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx == 0) 20288ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper continue; 202928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 203028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx < symbias) 203128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 203228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 203328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"), 20348ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); 203528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper continue; 203628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 203728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 203828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper while (symidx - symbias < maxidx) 203928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 20408ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[4 20418ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + bitmask_words 20428ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + nbuckets 204328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper + symidx 204428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper - symbias]; 204528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 204628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symdata != NULL) 204728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 204828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Check that the referenced symbol is not undefined. */ 204928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym sym_mem; 205028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem); 2051231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper if (sym != NULL && sym->st_shndx == SHN_UNDEF 2052231c590fbe9d6f3a8e22796ded9c6a378628eb09Ulrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_FUNC) 205328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 205428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"), 205528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), symidx, cnt / 2 - 1); 205628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 205728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper const char *symname = elf_strptr (ebl->elf, symshdr->sh_link, 205828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper sym->st_name); 205928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symname != NULL) 206028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 206128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word hval = elf_gnu_hash (symname); 206228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if ((hval & ~1u) != (chainhash & ~1u)) 206328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 206428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"), 206528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), symidx, cnt / 2 - 1); 20668ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 20678ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper /* Set the bits in the bitmask. */ 20688ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t maskidx = (hval / classbits) & bitmask_idxmask; 20698ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (classbits == 32) 20708ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 20718ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p32[maskidx] 20728ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT32_C (1) << (hval & (classbits - 1)); 20738ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p32[maskidx] 20748ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT32_C (1) << ((hval >> shift) & (classbits - 1)); 20758ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 20768ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper else 20778ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 20788ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p64[maskidx] 20798ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT64_C (1) << (hval & (classbits - 1)); 20808ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p64[maskidx] 20818ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT64_C (1) << ((hval >> shift) & (classbits - 1)); 20828ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 208328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 208428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 208528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 208628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if ((chainhash & 1) != 0) 208728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 208828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 208928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++symidx; 209028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 209128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 209228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx - symbias >= maxidx) 209328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 209428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain for bucket %zu out of bounds\n"), 209528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt / 2 - 1); 209628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (symshdr != NULL 209728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && symidx > symshdr->sh_size / symshdr->sh_entsize) 209828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 209928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"), 210028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt / 2 - 1); 210128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 21028ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 21038ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (memcmp (collected.p32, bitmask.p32, bitmask_words * sizeof (Elf32_Word))) 21048ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 21058ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': bitmask does not match names in the hash table\n"), 21068ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx)); 21078ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 21088ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper free (collected.p32); 210928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 211028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 211128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 211228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 211328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2115acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type == ET_REL) 2116acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 2117acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2118acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': relocatable files cannot have hash tables\n"), 2119acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 2120acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 2121acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 2122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2123acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 2125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2131acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr symshdr_mem; 2132acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2133acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &symshdr_mem); 2134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM) 2135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': hash table not for dynamic symbol table\n"), 2137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 213928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_entsize != (tag == SHT_GNU_HASH 21408ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ? (gelf_getclass (ebl->elf) == ELFCLASS32 21418ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ? sizeof (Elf32_Word) : 0) 214228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper : (size_t) ebl_sysvhash_entrysize (ebl))) 2143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 214428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table entry size incorrect\n"), 2145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) == 0) 2148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"), 2149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 21518ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shdr->sh_size < (tag == SHT_GNU_HASH ? 4 : 2) * (shdr->sh_entsize ?: 4)) 2152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 21548ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': hash table has not even room for initial administrative entries\n"), 2155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 215928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper switch (tag) 2160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 216128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_HASH: 216228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) 216328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_sysv_hash64 (ebl, shdr, data, idx, symshdr); 216428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 216528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_sysv_hash (ebl, shdr, data, idx, symshdr); 216628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 2167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 216828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_GNU_HASH: 216928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_gnu_hash (ebl, shdr, data, idx, symshdr); 217028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 2171ee4b927bae351b21787355e00a3d28371bf78e8fUlrich Drepper 217228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper default: 21738ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper assert (! "should not happen"); 2174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 21787c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper/* Compare content of both hash tables, it must be identical. */ 21797c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepperstatic void 21807c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppercompare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx, 21817c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper size_t gnu_hash_idx) 21827c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper{ 21837c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Scn *hash_scn = elf_getscn (ebl->elf, hash_idx); 21847c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Data *hash_data = elf_getdata (hash_scn, NULL); 21857c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr hash_shdr_mem; 21867c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr *hash_shdr = gelf_getshdr (hash_scn, &hash_shdr_mem); 21877c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Scn *gnu_hash_scn = elf_getscn (ebl->elf, gnu_hash_idx); 21887c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Data *gnu_hash_data = elf_getdata (gnu_hash_scn, NULL); 21897c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr gnu_hash_shdr_mem; 21907c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr *gnu_hash_shdr = gelf_getshdr (gnu_hash_scn, &gnu_hash_shdr_mem); 21917c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 21927c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (hash_shdr == NULL || gnu_hash_shdr == NULL 21937c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper || hash_data == NULL || gnu_hash_data == NULL) 21947c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* None of these pointers should be NULL since we used the 21957c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper sections already. We are careful nonetheless. */ 21967c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper return; 21977c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 21987c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* The link must point to the same symbol table. */ 21997c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (hash_shdr->sh_link != gnu_hash_shdr->sh_link) 22007c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22017c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 22027c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"), 22037c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name), 22047c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gnu_hash_idx, 22057c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 22067c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper return; 22077c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 22087c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22097c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Scn *sym_scn = elf_getscn (ebl->elf, hash_shdr->sh_link); 22107c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf_Data *sym_data = elf_getdata (sym_scn, NULL); 22117c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr sym_shdr_mem; 22127c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Shdr *sym_shdr = gelf_getshdr (sym_scn, &sym_shdr_mem); 22137c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22147c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (sym_data == NULL || sym_shdr == NULL) 22157c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper return; 22167c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22177c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper int nentries = sym_shdr->sh_size / sym_shdr->sh_entsize; 22187c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper char *used = alloca (nentries); 22197c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper memset (used, '\0', nentries); 22207c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22217c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* First go over the GNU_HASH table and mark the entries as used. */ 22227c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf; 22237c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf32_Word gnu_nbucket = gnu_hasharr[0]; 22247c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const int bitmap_factor = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 1 : 2; 22257c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *gnu_bucket = (gnu_hasharr 22267c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper + (4 + gnu_hasharr[2] * bitmap_factor)); 22277c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0] - gnu_hasharr[1]; 22287c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22297c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt) 22307c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22317c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf32_Word symidx = gnu_bucket[cnt]; 22327c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (symidx != STN_UNDEF) 22337c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper do 22347c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper used[symidx] |= 1; 22357c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper while ((gnu_chain[symidx++] & 1u) == 0); 22367c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 22377c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22387c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* Now go over the old hash table and check that we cover the same 22397c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper entries. */ 22407c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (hash_shdr->sh_entsize == sizeof (Elf32_Word)) 22417c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22427c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *hasharr = (Elf32_Word *) hash_data->d_buf; 22437c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf32_Word nbucket = hasharr[0]; 22447c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *bucket = &hasharr[2]; 22457c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf32_Word *chain = &hasharr[2 + nbucket]; 22467c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22477c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 22487c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22497c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf32_Word symidx = bucket[cnt]; 22507c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper while (symidx != STN_UNDEF) 22517c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22527c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper used[symidx] |= 2; 22537c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper symidx = chain[symidx]; 22547c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 22557c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 22567c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 22577c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper else 22587c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22597c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf64_Xword *hasharr = (Elf64_Xword *) hash_data->d_buf; 22607c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf64_Xword nbucket = hasharr[0]; 22617c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf64_Xword *bucket = &hasharr[2]; 22627c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper const Elf64_Xword *chain = &hasharr[2 + nbucket]; 22637c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22647c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) 22657c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22667c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper Elf64_Xword symidx = bucket[cnt]; 22677c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper while (symidx != STN_UNDEF) 22687c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22697c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper used[symidx] |= 2; 22707c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper symidx = chain[symidx]; 22717c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 22727c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 22737c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 22747c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22757c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper /* Now see which entries are not set in one or both hash tables 22767c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper (unless the symbol is undefined in which case it can be omitted 22777c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper in the new table format). */ 22787c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if ((used[0] & 1) != 0) 22797c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"), 22807c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gnu_hash_idx, 22817c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 22827c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if ((used[0] & 2) != 0) 22837c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"), 22847c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name)); 22857c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 22867c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper for (int cnt = 1; cnt < nentries; ++cnt) 22877c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (used[cnt] != 0 && used[cnt] != 3) 22887c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22897c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (used[cnt] == 1) 22907c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 22917c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersymbol %d referenced in new hash table in [%2zu] '%s' but not in old hash table in [%2zu] '%s'\n"), 22927c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper cnt, gnu_hash_idx, 22937c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name), 22947c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper hash_idx, 22957c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name)); 22967c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper else 22977c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper { 22987c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Sym sym_mem; 22997c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper GElf_Sym *sym = gelf_getsym (sym_data, cnt, &sym_mem); 23007c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23017c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (sym != NULL && sym->st_shndx != STN_UNDEF) 23027c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper ERROR (gettext ("\ 23037c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Dreppersymbol %d referenced in old hash table in [%2zu] '%s' but not in new hash table in [%2zu] '%s'\n"), 23047c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper cnt, hash_idx, 23057c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name), 23067c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gnu_hash_idx, 23077c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 23087c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23097c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper } 23107c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper} 23117c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 23127c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 2313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_null (Ebl *ebl, GElf_Shdr *shdr, int idx) 2315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define TEST(name, extra) \ 2317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (extra && shdr->sh_##name != 0) \ 2318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"), \ 2319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), #name) 2320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (name, 1); 2322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (flags, 1); 2323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (addr, 1); 2324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (offset, 1); 2325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (size, idx != 0); 2326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (link, idx != 0); 2327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (info, 1); 2328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (addralign, 1); 2329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (entsize, 1); 2330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 2337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section groups only allowed in relocatable object files\n"), 2340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check that sh_link is an index of a symbol table. */ 2345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 2346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &symshdr_mem); 2348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr == NULL) 2349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"), 2350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), elf_errmsg (-1)); 2351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr->sh_type != SHT_SYMTAB) 2354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section reference in sh_link is no symbol table\n"), 2356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM, 2359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1, EV_CURRENT)) 2360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': invalid symbol index in sh_info\n"), 2362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags != 0) 2365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"), 2366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (be_strict 2369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT)) 2370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"), 2371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 2376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"), 2377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), elf_errmsg (-1)); 2378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT); 2381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 2382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word val; 2383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size % elsize != 0) 2385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"), 2387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size < elsize) 2390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group without flags word\n"), 2392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (be_strict) 2394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size < 2 * elsize) 2396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group without member\n"), 2398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (data->d_size < 3 * elsize) 2400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group with only one member\n"), 2402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED 2406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val = *((Elf32_Word *) data->d_buf); 2407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#else 2408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (&val, data->d_buf, elsize); 2409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 2410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((val & ~GRP_COMDAT) != 0) 2411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"), 2412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = elsize; cnt < data->d_size; cnt += elsize) 2415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED 2417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val = *((Elf32_Word *) ((char *) data->d_buf + cnt)); 2418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#else 2419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (&val, (char *) data->d_buf + cnt, elsize); 2420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 2421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (val > shnum) 2423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section index %Zu out of range\n"), 2425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize); 2426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr refshdr_mem; 2429acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val), 2430acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &refshdr_mem); 2431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (refshdr == NULL) 2432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get section header for element %zu: %s\n"), 2434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize, 2435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 2436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (refshdr->sh_type == SHT_GROUP) 2439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group contains another group [%2d] '%s'\n"), 2441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((refshdr->sh_flags & SHF_GROUP) == 0) 2445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP flag set\n"), 2447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize, 2448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++scnref[val] == 2) 2452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' is contained in more than one section group\n"), 2454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char * 2462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_flags_string (GElf_Word flags, char *buf, size_t len) 2463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const struct 2465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word flag; 2467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name; 2468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } known_flags[] = 2469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define NEWFLAG(name) { SHF_##name, #name } 2471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (WRITE), 2472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (ALLOC), 2473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (EXECINSTR), 2474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (MERGE), 2475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (STRINGS), 2476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (INFO_LINK), 2477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (LINK_ORDER), 2478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (OS_NONCONFORMING), 2479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (GROUP), 2480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (TLS) 2481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 2482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#undef NEWFLAG 2483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]); 2484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = buf; 2486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2487acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 0; cnt < nknown_flags; ++cnt) 2488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags & known_flags[cnt].flag) 2489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cp != buf && len > 1) 2491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = '|'; 2493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper --len; 2494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name)); 2497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, known_flags[cnt].name, ncopy); 2498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper len -= ncopy; 2499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper flags ^= known_flags[cnt].flag; 2501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags != 0 || cp == buf) 2504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags); 2505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp = '\0'; 2507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return buf; 2509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2512dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2513dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperhas_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx) 2514dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2515dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* First find the relocation section for the symbol table. */ 2516dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = NULL; 2517dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2518dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = NULL; 2519dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2520dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2521dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper shdr = gelf_getshdr (scn, &shdr_mem); 2522dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr != NULL 2523dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) 2524dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && shdr->sh_link == symscnndx) 2525dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Found the section. */ 2526dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2527dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2528dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2529dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (scn == NULL) 2530dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2531dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2532dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2533dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2534dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2535dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2536dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr->sh_type == SHT_REL) 2537dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 2538dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2539dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rel rel_mem; 2540dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rel *rel = gelf_getrel (data, i, &rel_mem); 2541dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (rel == NULL) 2542dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2543dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2544dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_R_SYM (rel->r_info) == symndx 2545dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) 2546dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2547dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2548dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2549dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 2550dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2551dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rela rela_mem; 2552dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rela *rela = gelf_getrela (data, i, &rela_mem); 2553dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (rela == NULL) 2554dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2555dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2556dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_R_SYM (rela->r_info) == symndx 2557dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) 2558dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2559dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2560dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2561dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2562dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2563dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2564dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2565637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic int 2566637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperin_nobits_scn (Ebl *ebl, unsigned int shndx) 2567637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper{ 2568637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Shdr shdr_mem; 2569637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem); 2570637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper return shdr != NULL && shdr->sh_type == SHT_NOBITS; 2571637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper} 2572637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2573637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2574dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic struct version_namelist 2575dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2576dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *objname; 2577dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name; 2578858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath GElf_Versym ndx; 2579dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper enum { ver_def, ver_need } type; 2580dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *next; 2581dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} *version_namelist; 2582dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2583dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2584dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2585858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrathadd_version (const char *objname, const char *name, GElf_Versym ndx, int type) 2586dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2587dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that there are no duplications. */ 2588dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *nlp = version_namelist; 2589dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (nlp != NULL) 2590dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2591dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (((nlp->objname == NULL && objname == NULL) 2592dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper || (nlp->objname != NULL && objname != NULL 2593dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (nlp->objname, objname) == 0)) 2594dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (nlp->name, name) == 0) 2595dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return nlp->type == ver_def ? 1 : -1; 2596dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp = nlp->next; 2597dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2598dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2599dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp = xmalloc (sizeof (*nlp)); 2600dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->objname = objname; 2601dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->name = name; 2602dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->ndx = ndx; 2603dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->type = type; 2604dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->next = version_namelist; 2605dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper version_namelist = nlp; 2606dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2607dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2608dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2609dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2610dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2612dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_versym (Ebl *ebl, int idx) 2613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2614dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = elf_getscn (ebl->elf, idx); 2615dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2616dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2617dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr == NULL) 2618dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The error has already been reported. */ 2619dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2620dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2621dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2622dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2623dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2624dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2625dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2626dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2627dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2628dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2629dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 2630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 2631dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 2632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr == NULL) 2633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The error has already been reported. */ 2634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr->sh_type != SHT_DYNSYM) 2637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"), 2640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 2642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2645dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The number of elements in the version symbol table must be the 2646dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper same as the number of symbols. */ 2647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size / shdr->sh_entsize 2648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != symshdr->sh_size / symshdr->sh_entsize) 2649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"), 2651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 2653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2654dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 2655dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (symdata == NULL) 2656dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The error has already been reported. */ 2657dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2658dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2659dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 2660dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2661dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Versym versym_mem; 2662dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem); 2663dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym == NULL) 2664dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2665dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2666dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: cannot read version data\n"), 2667dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2668dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2669dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2670dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2671dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Sym sym_mem; 2672dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem); 2673dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (sym == NULL) 2674dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Already reported elsewhere. */ 2675dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2676dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 267761655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper if (*versym == VER_NDX_GLOBAL) 2678dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2679dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Global symbol. Make sure it is not defined as local. */ 2680dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2681dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2682dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: local symbol with global scope\n"), 2683dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2684dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 268561655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper else if (*versym != VER_NDX_LOCAL) 2686dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2687c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper /* Versioned symbol. Make sure it is not defined as local. */ 2688c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2689c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper ERROR (gettext ("\ 2690c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Dreppersection [%2d] '%s': symbol %d: local symbol with version\n"), 2691c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper idx, section_name (ebl, idx), cnt); 2692c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper 2693dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Look through the list of defined versions and locate the 2694dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper index we need for this symbol. */ 2695dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist; 2696dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 2697858b189f82ecc32ca7042e74ccb022f794a9f83bRoland McGrath if (runp->ndx == (*versym & (GElf_Versym) 0x7fff)) 2698dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2699dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2700dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 2701dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2702dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp == NULL) 2703dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2704dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: invalid version index %d\n"), 2705dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2706dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (sym->st_shndx == SHN_UNDEF 2707dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && runp->type == ver_def) 2708dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2709dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for defined version\n"), 2710dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2711dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (sym->st_shndx != SHN_UNDEF 2712dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && runp->type == ver_need) 2713dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2714dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Unless this symbol has a copy relocation associated 2715dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper this must not happen. */ 2716637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper if (!has_copy_reloc (ebl, shdr->sh_link, cnt) 2717637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper && !in_nobits_scn (ebl, sym->st_shndx)) 2718dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2719dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for requested version\n"), 2720dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2721dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2722dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2723dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2724dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2725dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2726dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2727dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2728dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperunknown_dependency_p (Elf *elf, GElf_Ehdr *ehdr, const char *fname) 2729dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2730dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr phdr_mem; 2731dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr *phdr = NULL; 2732dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2733dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int i; 2734dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (i = 0; i < ehdr->e_phnum; ++i) 2735dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL 2736dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr->p_type == PT_DYNAMIC) 2737dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2738dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2739dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (i == ehdr->e_phnum) 2740dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2741dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (phdr != NULL); 2742dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); 2743dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2744dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2745dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2746dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL) 2747dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) 2748dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2749dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Dyn dyn_mem; 2750dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); 2751dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (dyn != NULL && dyn->d_tag == DT_NEEDED) 2752dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2753dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val); 2754dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (str != NULL && strcmp (str, fname) == 0) 2755dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Found it. */ 2756dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2757dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2758dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2759dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2760dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2764acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic unsigned int nverneed; 2765acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2767dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_verneed (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2769acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (++nverneed == 2) 2770acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("more than one version reference section present\n")); 2771acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2772acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr strshdr_mem; 2773acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2774acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &strshdr_mem); 2775acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr == NULL) 2776acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 2777acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 2778acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2779acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': sh_link does not link to string table\n"), 2780acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 2781dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2782dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2783dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2784dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2785dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2786dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2787dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2788dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2789dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int offset = 0; 2790dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = shdr->sh_info; --cnt >= 0; ) 2791dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2792dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Get the data at the next offset. */ 2793dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verneed needmem; 2794dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 2795dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need == NULL) 2796dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2797dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2798dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int auxoffset = offset + need->vn_aux; 2799dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2800dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need->vn_version != EV_CURRENT) 2801dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2802dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"), 2803dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) need->vn_version); 2804dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2805dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED, 2806dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 1, EV_CURRENT)) 2807dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2808dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 2809dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2810dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2811dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *libname = elf_strptr (ebl->elf, shdr->sh_link, 2812dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper need->vn_file); 2813dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (libname == NULL) 2814dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2815dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2816dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid file reference\n"), 2817dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2818dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto next_need; 2819dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2820dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2821dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that there is a DT_NEEDED entry for the referenced library. */ 2822dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (unknown_dependency_p (ebl->elf, ehdr, libname)) 2823dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2824dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d references unknown dependency\n"), 2825dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2826dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2827dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2828dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2829dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Vernaux auxmem; 2830dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 2831dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 2832dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2833dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2834dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vna_flags & ~VER_FLG_WEAK) != 0) 2835dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2836dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"), 2837dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2838dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2839dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *verstr = elf_strptr (ebl->elf, shdr->sh_link, 2840dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper aux->vna_name); 2841dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (verstr == NULL) 2842dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2843dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"), 2844dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2845dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2846dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2847dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Word hashval = elf_hash (verstr); 2848dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (hashval != aux->vna_hash) 2849dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2850dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"), 2851dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2852dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, (int) hashval, (int) aux->vna_hash); 2853dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2854dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int res = add_version (libname, verstr, aux->vna_other, 2855dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ver_need); 2856dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (unlikely (res !=0)) 2857dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2858dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (res > 0); 2859dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2860dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"), 2861dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2862dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, verstr); 2863dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2864dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2865dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2866dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vna_next != 0 || cnt2 > 0) 2867dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, 2868dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper EV_CURRENT)) 2869dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2870dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2871dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"), 2872dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2873dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2874dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2875dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2876dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += MAX (aux->vna_next, 2877dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT)); 2878dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2879dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2880dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Find the next offset. */ 2881dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper next_need: 2882dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper offset += need->vn_next; 2883dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2884dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((need->vn_next != 0 || cnt > 0) 2885dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && offset < auxoffset) 2886dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2887dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid offset to next entry\n"), 2888dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2889dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2890acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper} 2891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2892acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2893acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic unsigned int nverdef; 2894acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2895acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic void 2896acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx) 2897acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper{ 2898acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (++nverdef == 2) 2899acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("more than one version definition section present\n")); 2900acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2901acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr strshdr_mem; 2902acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2903acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &strshdr_mem); 2904acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr == NULL) 2905acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 2906acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 2907acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2908acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': sh_link does not link to string table\n"), 2909acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 2910dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2911dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2912dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2913dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2914dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper no_data: 2915dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2916dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2917dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2918dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2919dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2920dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Iterate over all version definition entries. We check that there 2921dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper is a BASE entry and that each index is unique. To do the later 2922dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper we collection the information in a list which is later 2923dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper examined. */ 2924dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist 2925dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2926dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name; 2927dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *next; 2928dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } *namelist = NULL; 2929dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *refnamelist = NULL; 2930dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2931dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper bool has_base = false; 2932dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int offset = 0; 2933dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = shdr->sh_info; --cnt >= 0; ) 2934dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2935dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Get the data at the next offset. */ 2936dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdef defmem; 2937dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 2938dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def == NULL) 2939dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 2940dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2941dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_flags & VER_FLG_BASE) != 0) 2942dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2943dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (has_base) 2944dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2945dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': more than one BASE definition\n"), 2946dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2947dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_ndx != VER_NDX_GLOBAL) 2948dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2949dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"), 2950dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2951dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper has_base = true; 2952dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2953dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0) 2954dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2955dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has unknown flag\n"), 2956dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2957dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2958dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_version != EV_CURRENT) 2959dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2960dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"), 2961dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) def->vd_version); 2962dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2963dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF, 2964dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 1, EV_CURRENT)) 2965dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2966dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 2967dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2968dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2969dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int auxoffset = offset + def->vd_aux; 2970dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdaux auxmem; 2971dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 2972dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 2973dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 2974dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2975dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 2976dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (name == NULL) 2977dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2978dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2979dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid name reference\n"), 2980dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2981dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto next_def; 2982dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2983dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Word hashval = elf_hash (name); 2984dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_hash != hashval) 2985dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2986dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"), 2987dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) hashval, 2988dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper (int) def->vd_hash); 2989dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2990dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int res = add_version (NULL, name, def->vd_ndx, ver_def); 2991dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (unlikely (res !=0)) 2992dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2993dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (res > 0); 2994dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2995dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has duplicate version name '%s'\n"), 2996dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, name); 2997dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2998dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2999dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *newname = alloca (sizeof (*newname)); 30006247d634c33be4c9ee4bfc650bb8f06f5add41e5Ulrich Drepper newname->name = name; 3001dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper newname->next = namelist; 3002dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper namelist = newname; 3003dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3004dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += aux->vda_next; 3005dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 3006dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3007dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper aux = gelf_getverdaux (data, auxoffset, &auxmem); 3008dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 3009dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 3010dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3011c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 3012c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper if (name == NULL) 3013c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper ERROR (gettext ("\ 3014c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Dreppersection [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"), 3015c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper idx, section_name (ebl, idx), cnt); 3016c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper else 3017c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper { 3018c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname = alloca (sizeof (*newname)); 3019c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname->name = name; 3020c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname->next = refnamelist; 3021c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper refnamelist = newname; 3022c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper } 3023dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3024dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt) 3025dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, 3026dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper EV_CURRENT)) 3027dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3028dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3029dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong next field in auxiliary data\n"), 3030dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 3031dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3032dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3033dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3034dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += MAX (aux->vda_next, 3035dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT)); 3036dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3037dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3038dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Find the next offset. */ 3039dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper next_def: 3040dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper offset += def->vd_next; 3041dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3042dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_next != 0 || cnt > 0) 3043dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && offset < auxoffset) 3044dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3045dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid offset to next entry\n"), 3046dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 3047dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3048dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3049dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (!has_base) 3050dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': no BASE definition\n"), 3051dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 3052dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3053dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check whether the referenced names are available. */ 3054dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (namelist != NULL) 3055dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3056dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist; 3057dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 3058dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3059dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp->type == ver_def 3060dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (runp->name, namelist->name) == 0) 3061dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3062dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 3063dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3064dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3065dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp == NULL) 3066dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3067dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': unknown parent version '%s'\n"), 3068dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), namelist->name); 3069dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3070dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper namelist = namelist->next; 3071dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3072acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper} 3073acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3074acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3075637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic bool has_loadable_segment; 3076637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic bool has_interp_segment; 3077637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 3078637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic const struct 3079637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper{ 3080637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper const char *name; 3081637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper size_t namelen; 3082637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word type; 3083637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper enum { unused, exact, atleast } attrflag; 3084637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word attr; 3085637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word attr2; 3086637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper} special_sections[] = 3087637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { 3088637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper /* See figure 4-14 in the gABI. */ 3089637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3090637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".comment", 8, SHT_PROGBITS, exact, 0, 0 }, 3091637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3092637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3093637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".debug", 7, SHT_PROGBITS, exact, 0, 0 }, 3094637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE }, 3095637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 }, 3096637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 }, 3097637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3098637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3099637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info? 3100637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 }, 3101637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3102637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3103637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests? 3104637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".line", 6, SHT_PROGBITS, exact, 0, 0 }, 3105637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".note", 6, SHT_NOTE, exact, 0, 0 }, 3106637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests 3107637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3108637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC }, // XXX more tests 3109637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests 3110637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 3111637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 3112637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 }, 3113637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 3114637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 3115637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests 3116637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3117637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3118637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3119637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3120637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 3121637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper /* The following are GNU extensions. */ 3122637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 }, 3123637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 }, 3124637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 } 3125637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper }; 3126637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper#define nspecial_sections \ 3127637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper (sizeof (special_sections) / sizeof (special_sections[0])) 3128637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 3129637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 3130acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic void 3131acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_sections (Ebl *ebl, GElf_Ehdr *ehdr) 3132acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper{ 3133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shoff == 0) 3134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No section header. */ 3135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 3136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate array to count references in section groups. */ 3138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scnref = (int *) xcalloc (shnum, sizeof (int)); 3139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the zeroth section first. It must not have any contents 3141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper and the section header must contain nonzero value at most in the 3142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sh_size and sh_link fields. */ 3143acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr shdr_mem; 3144acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 3145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 3146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get section header of zeroth section\n")); 3147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_name != 0) 3150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero name\n")); 3151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type != 0) 3152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero type\n")); 3153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags != 0) 3154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero flags\n")); 3155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addr != 0) 3156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero address\n")); 3157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_offset != 0) 3158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero offset\n")); 3159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 3160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero info field\n")); 3161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addralign != 0) 3162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero align value\n")); 3163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != 0) 3164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero entry size value\n")); 3165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size != 0 && ehdr->e_shnum != 0) 3167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero size value while ELF header has nonzero shnum value\n")); 3169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX) 3171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n")); 3173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3175acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper bool dot_interp_section = false; 3176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 31777c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper size_t hash_idx = 0; 31787c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper size_t gnu_hash_idx = 0; 31797c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 3180dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper size_t versym_scnndx = 0; 3181acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 1; cnt < shnum; ++cnt) 3182acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 3183acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem); 3184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 3185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercannot get section header for section [%2zu] '%s': %s\n"), 3188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), elf_errmsg (-1)); 3189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 3190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 3193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnname == NULL) 3195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2zu]: invalid name\n"), cnt); 3196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether it is one of the special sections defined in 3199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the gABI. */ 3200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t s; 3201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (s = 0; s < nspecial_sections; ++s) 3202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strncmp (scnname, special_sections[s].name, 3203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper special_sections[s].namelen) == 0) 3204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf1[100]; 3206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf2[100]; 3207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf3[100]; 3208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3209653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Word good_type = special_sections[s].type; 3210653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (special_sections[s].namelen == sizeof ".plt" && 3211653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath !memcmp (special_sections[s].name, ".plt", sizeof ".plt") 3212c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper && ebl_bss_plt_p (ebl, ehdr)) 3213653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath good_type = SHT_NOBITS; 3214653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 3215653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (shdr->sh_type != good_type 3216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !(is_debuginfo && shdr->sh_type == SHT_NOBITS)) 3217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' has wrong type: expected %s, is %s\n"), 3219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) cnt, scnname, 3220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_type_name (ebl, special_sections[s].type, 3221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_type_name (ebl, shdr->sh_type, 3223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2))); 3224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (special_sections[s].attrflag == exact) 3226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Except for the link order and group bit all the 3228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper other bits should match exactly. */ 3229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP)) 3230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != special_sections[s].attr) 3231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s, is %s\n"), 3233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname, 3234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr, 3235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (shdr->sh_flags 3237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~SHF_LINK_ORDER, 3238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2))); 3239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (special_sections[s].attrflag == atleast) 3241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & special_sections[s].attr) 3243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != special_sections[s].attr 3244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP 3245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | special_sections[s].attr 3246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | special_sections[s].attr2)) 3247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != 0)) 3248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"), 3250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname, 3251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr, 3252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr2, 3254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2)), 3255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (shdr->sh_flags 3256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~(SHF_LINK_ORDER 3257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_GROUP), 3258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf3, sizeof (stbuf3))); 3259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (scnname, ".interp") == 0) 3262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper dot_interp_section = true; 3264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL) 3266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' present in object file\n"), 3268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) != 0 3271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !has_loadable_segment) 3272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 3274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((shdr->sh_flags & SHF_ALLOC) == 0 3276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && has_loadable_segment) 3277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 3279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (scnname, ".symtab_shndx") == 0 3284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_REL) 3285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' is extension section index table in non-object file\n"), 3287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* These sections must have the SHF_ALLOC flag set iff 3290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper a loadable segment is available. 3291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .relxxx 3293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .strtab 3294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .symtab 3295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .symtab_shndx 3296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Check that if there is a reference from the 3298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loaded section these sections also have the 3299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ALLOC flag set. */ 3300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if 0 3301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX TODO 3302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) != 0 3303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !has_loadable_segment) 3304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 3306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((shdr->sh_flags & SHF_ALLOC) == 0 3308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && has_loadable_segment) 3309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 3311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 3313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize) 3320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': size not multiple of entry size\n"), 3322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL) 3325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get section header\n")); 3326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type >= SHT_NUM 3328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_LIBLIST 3329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_CHECKSUM 3330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_verdef 3331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_verneed 333218e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath && shdr->sh_type != SHT_GNU_versym 333318e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL) 333418e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"), 333518e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath cnt, section_name (ebl, cnt), 333618e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath (int) shdr->sh_type); 3337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ 3339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ 3340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) 3341aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS) 3342aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper { 3343aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS; 3344aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (sh_flags & SHF_MASKPROC) 3345aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper { 3346aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (!ebl_machine_section_flag_check (ebl, 3347aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper sh_flags & SHF_MASKPROC)) 3348aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper ERROR (gettext ("section [%2zu] '%s'" 3349aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper " contains invalid processor-specific flag(s)" 3350aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper " %#" PRIx64 "\n"), 3351aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC); 3352aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper sh_flags &= ~(GElf_Xword) SHF_MASKPROC; 3353aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper } 3354aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (sh_flags != 0) 3355aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" 3356aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper " %#" PRIx64 "\n"), 3357aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper cnt, section_name (ebl, cnt), sh_flags); 3358aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper } 3359aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper if (shdr->sh_flags & SHF_TLS) 3360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX Correct? 3362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addr != 0 && !gnuld) 3363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': thread-local data sections address not zero\n"), 3365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX TODO more tests!? 3368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_link >= shnum) 3371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': invalid section reference in link value\n"), 3373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum) 3376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': invalid section reference in info value\n"), 3378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_MERGE) == 0 3381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_STRINGS) != 0 3382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && be_strict) 3383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': strings flag set without merge flag\n"), 3385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0) 3388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': merge flag set but entry size is zero\n"), 3390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags & SHF_GROUP) 3393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_scn_group (ebl, cnt); 3394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0) 3396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the section is contained in a loaded segment 3398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper and that the initialization part matches NOBITS sections. */ 3399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int pcnt; 3400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 3401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr; 3402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 3404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL 3405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ((phdr->p_type == PT_LOAD 3406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_TLS) == 0) 3407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (phdr->p_type == PT_TLS 3408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_TLS) != 0)) 3409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && phdr->p_offset <= shdr->sh_offset 34109aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath && (phdr->p_offset + phdr->p_filesz > shdr->sh_offset 34119aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath || (phdr->p_offset + phdr->p_memsz > shdr->sh_offset 34129aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath && shdr->sh_type == SHT_NOBITS))) 3413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found the segment. */ 3415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_offset + phdr->p_memsz 3416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < shdr->sh_offset + shdr->sh_size) 3417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' not fully contained in segment of program header entry %d\n"), 3419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type == SHT_NOBITS) 3422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz 3424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !is_debuginfo) 3425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"), 3427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3431653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const GElf_Off end = phdr->p_offset + phdr->p_filesz; 3432653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (shdr->sh_offset > end || 3433653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath (shdr->sh_offset == end && shdr->sh_size != 0)) 3434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"), 3436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (pcnt == ehdr->e_phnum) 3443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': alloc flag set but section not in any loaded segment\n"), 3445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB) 3449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"), 3451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (shdr->sh_type) 3454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_DYNSYM: 3456acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type == ET_REL) 3457acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 3458acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), 3459acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper cnt, section_name (ebl, cnt)); 3460acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper /* FALLTHROUGH */ 3461acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_SYMTAB: 3462dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_symtab (ebl, ehdr, shdr, cnt); 3463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_RELA: 3466c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper check_rela (ebl, ehdr, shdr, cnt); 3467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_REL: 3470c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper check_rel (ebl, ehdr, shdr, cnt); 3471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_DYNAMIC: 3474607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_dynamic (ebl, ehdr, shdr, cnt); 3475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_SYMTAB_SHNDX: 3478acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper check_symtab_shndx (ebl, ehdr, shdr, cnt); 3479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_HASH: 34827c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); 34837c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper hash_idx = cnt; 34847c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper break; 34857c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 348628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_GNU_HASH: 348728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); 34887c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper gnu_hash_idx = cnt; 3489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_NULL: 3492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_null (ebl, shdr, cnt); 3493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GROUP: 3496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_group (ebl, ehdr, shdr, cnt); 3497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GNU_versym: 3500dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* We cannot process this section now since we have no guarantee 3501dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper that the verneed and verdef sections have already been read. 3502dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Just remember the section index. */ 3503dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym_scnndx != 0) 3504dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("more than one version symbol table present\n")); 3505dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper versym_scnndx = cnt; 3506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3508acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_GNU_verneed: 3509dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_verneed (ebl, ehdr, shdr, cnt); 3510acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper break; 3511acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3512acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_GNU_verdef: 3513acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper check_verdef (ebl, shdr, cnt); 3514acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper break; 3515acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 3517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Nothing. */ 3518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_interp_segment && !dot_interp_section) 3523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("INTERP program header entry but no .interp section\n")); 3524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3525dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (version_namelist != NULL) 3526dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3527dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym_scnndx == 0) 3528dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3529dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperno .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n")); 3530dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 3531dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_versym (ebl, versym_scnndx); 3532dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3533dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check for duplicate index numbers. */ 3534dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper do 3535dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3536dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist->next; 3537dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 3538dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3539dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (version_namelist->ndx == runp->ndx) 3540dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3541dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("duplicate version index %d\n"), 3542dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper (int) version_namelist->ndx); 3543dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3544dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3545dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 3546dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3547dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3548dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *old = version_namelist; 3549dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper version_namelist = version_namelist->next; 3550dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper free (old); 3551dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3552dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (version_namelist != NULL); 3553dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3554dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (versym_scnndx != 0) 3555dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3556dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n")); 3557dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 35587c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper if (hash_idx != 0 && gnu_hash_idx != 0) 35597c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper compare_hash_gnu_hash (ebl, ehdr, hash_idx, gnu_hash_idx); 35607c0e79ffc201e4828a050b35f2c9d96e3001cb48Ulrich Drepper 3561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (scnref); 3562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 3566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt) 3567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 3568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL 3569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 3570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperphdr[%d]: no note entries defined for the type of file\n"), 3572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt); 3573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (is_debuginfo) 3575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The p_offset values in a separate debug file are bogus. */ 3576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 3577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *notemem = gelf_rawchunk (ebl->elf, phdr->p_offset, phdr->p_filesz); 3579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* ELF64 files often use note section entries in the 32-bit format. 3581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper The p_align field is set to 8 in case the 64-bit format is used. 3582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper In case the p_align value is 0 or 4 the 32-bit format is 3583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper used. */ 3584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Xword align = phdr->p_align == 0 || phdr->p_align == 4 ? 4 : 8; 3585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1)) 3586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Xword idx = 0; 3588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (idx < phdr->p_filesz) 3589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint64_t namesz; 3591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint64_t descsz; 3592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint64_t type; 3593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t namesz32; 3594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t descsz32; 3595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (align == 4) 3597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t *ptr = (uint32_t *) (notemem + idx); 3599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((__BYTE_ORDER == __LITTLE_ENDIAN 3601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 3602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (__BYTE_ORDER == __BIG_ENDIAN 3603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 3604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz32 = namesz = bswap_32 (*ptr); 3606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr; 3607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz32 = descsz = bswap_32 (*ptr); 3608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr; 3609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper type = bswap_32 (*ptr); 3610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz32 = namesz = *ptr++; 3614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz32 = descsz = *ptr++; 3615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper type = *ptr; 3616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint64_t *ptr = (uint64_t *) (notemem + idx); 3621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t *ptr32 = (uint32_t *) (notemem + idx); 3622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((__BYTE_ORDER == __LITTLE_ENDIAN 3624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 3625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (__BYTE_ORDER == __BIG_ENDIAN 3626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 3627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz = bswap_64 (*ptr); 3629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr; 3630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz = bswap_64 (*ptr); 3631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr; 3632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper type = bswap_64 (*ptr); 3633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz32 = bswap_32 (*ptr32); 3635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr32; 3636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz32 = bswap_32 (*ptr32); 3637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz = *ptr++; 3641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz = *ptr++; 3642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper type = *ptr; 3643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz32 = *ptr32++; 3645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz32 = *ptr32; 3646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (idx + 3 * align > phdr->p_filesz 3650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (idx + 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz) 3651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > phdr->p_filesz)) 3652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_CLASS] == ELFCLASS64 3654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && idx + 3 * 4 <= phdr->p_filesz 3655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (idx + 3 * 4 + ALIGNED_LEN (namesz32) + ALIGNED_LEN (descsz32) 3656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper <= phdr->p_filesz)) 3657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperphdr[%d]: note entries probably in form of a 32-bit ELF file\n"), cnt); 3659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("phdr[%d]: extra %zu bytes after last note\n"), 3661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, (size_t) (phdr->p_filesz - idx)); 3662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure it is one of the note types we know about. */ 3666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_CORE) 3667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (type) 3669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PRSTATUS: 3671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_FPREGSET: 3672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PRPSINFO: 3673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_TASKSTRUCT: /* NT_PRXREG on Solaris. */ 3674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PLATFORM: 3675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_AUXV: 3676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_GWINDOWS: 3677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_ASRS: 3678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PSTATUS: 3679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PSINFO: 3680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PRCRED: 3681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_UTSNAME: 3682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_LWPSTATUS: 3683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_LWPSINFO: 3684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PRFPXREG: 3685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Known type. */ 3686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 3689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperphdr[%d]: unknown core file note type %" PRIu64 " at offset %" PRIu64 "\n"), 3691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, type, idx); 3692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (type != NT_VERSION) 3697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperphdr[%d]: unknown object file note type %" PRIu64 " at offset %" PRIu64 "\n"), 3699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, type, idx); 3700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Move to the next entry. */ 3703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx += 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz); 3704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gelf_freechunk (ebl->elf, notemem); 3708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 3712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_program_header (Ebl *ebl, GElf_Ehdr *ehdr) 3713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 3714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phoff == 0) 3715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 3716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 3718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_CORE) 3719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperonly executables, shared objects, and core files can have program headers\n")); 3721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_interp = 0; 3723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_tls = 0; 3724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_relro = 0; 3725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int cnt = 0; cnt < ehdr->e_phnum; ++cnt) 3727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 3729b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr; 3730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 3732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr == NULL) 3733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get program header entry %d: %s\n"), 3735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, elf_errmsg (-1)); 3736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 3737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME 3740f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO 3741f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath /* Check for a known machine-specific type. */ 3742f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL) 3743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3744f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrathprogram header entry %d: unknown program header entry type %#" PRIx64 "\n"), 3745f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath cnt, (uint64_t) phdr->p_type); 3746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_type == PT_LOAD) 3748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_loadable_segment = true; 3749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_INTERP) 3750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_interp != 1) 3752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (num_pt_interp == 2) 3754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermore than one INTERP entry in program header\n")); 3756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_interp_segment = true; 3758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_TLS) 3760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_tls == 2) 3762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("more than one TLS entry in program header\n")); 3763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_NOTE) 3765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_note (ebl, ehdr, phdr, cnt); 376641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else if (phdr->p_type == PT_DYNAMIC) 376741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 376841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (ehdr->e_type == ET_EXEC && ! has_interp_segment) 376941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 377041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic executable cannot have dynamic sections\n")); 377141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else 377241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 377341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Check that the .dynamic section, if it exists, has 377441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper the same address. */ 377541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Scn *scn = NULL; 377641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 377741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 377841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr shdr_mem; 377941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 378041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 378141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 378241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_offset != shdr->sh_offset) 378341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 378441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperdynamic section reference in program header has wrong offset\n")); 378541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_memsz != shdr->sh_size) 378641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 378741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperdynamic section size mismatch in program and section header\n")); 378841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 378941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 379041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 379141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 379241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 3793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_GNU_RELRO) 3794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_relro == 2) 3796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermore than one GNU_RELRO entry in program header\n")); 3798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check that the region is in a writable segment. */ 3801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int inner; 3802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (inner = 0; inner < ehdr->e_phnum; ++inner) 3803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr2_mem; 3805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr2; 3806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 3808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr2 == NULL) 3809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 3810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr2->p_type == PT_LOAD 3812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && phdr->p_vaddr >= phdr2->p_vaddr 3813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (phdr->p_vaddr + phdr->p_memsz 3814b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper <= phdr2->p_vaddr + phdr2->p_memsz)) 3815b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((phdr2->p_flags & PF_W) == 0) 3817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloadable segment GNU_RELRO applies to is not writable\n")); 3819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((phdr2->p_flags & PF_X) != 0) 3820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloadable segment GNU_RELRO applies to is executable\n")); 3822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (inner >= ehdr->e_phnum) 3827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3828607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper%s segment not contained in a loaded segment\n"), "GNU_RELRO"); 3829607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 3830607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 3831607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper else if (phdr->p_type == PT_PHDR) 3832607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 3833607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that the region is in a writable segment. */ 3834607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper int inner; 3835607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper for (inner = 0; inner < ehdr->e_phnum; ++inner) 3836607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 3837607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr phdr2_mem; 3838607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr *phdr2; 3839607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 3840607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 3841607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr2 != NULL 3842607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr2->p_type == PT_LOAD 3843607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr >= phdr2->p_vaddr 3844607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && (phdr->p_vaddr + phdr->p_memsz 3845607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper <= phdr2->p_vaddr + phdr2->p_memsz)) 3846607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 3847b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3848607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 3849607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (inner >= ehdr->e_phnum) 3850607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 3851607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper%s segment not contained in a loaded segment\n"), "PHDR"); 3852607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 3853607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that offset in segment corresponds to offset in ELF 3854607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper header. */ 3855607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr->p_offset != ehdr->e_phoff) 3856607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 3857607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepperprogram header offset in ELF header and PHDR entry do not match")); 3858b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 38608190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath if (phdr->p_filesz > phdr->p_memsz 386156bc0b83ea81b7e959aaa4e1d01f8b36f2804a52Ulrich Drepper && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE)) 3862b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3863b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: file size greater than memory size\n"), 3864b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt); 3865b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3866b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_align > 1) 3867b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!powerof2 (phdr->p_align)) 3869b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3870b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: alignment not a power of 2\n"), cnt); 3871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0) 3872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3873b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: file offset and virtual address not module of alignment\n"), cnt); 3874b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3875b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3876b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Process one file. */ 3880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 3881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_elf_file (Elf *elf, const char *prefix, const char *suffix, 3882b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one) 3883b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 3884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Reset variables. */ 3885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ndynamic = 0; 3886acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper nverneed = 0; 3887acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper nverdef = 0; 388841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper textrel = false; 388941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper needed_textrel = false; 3890acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper has_loadable_segment = false; 3891acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper has_interp_segment = false; 3892b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3893b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr ehdr_mem; 3894b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 3895b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl; 3896b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3897b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Print the file name. */ 3898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!only_one) 3899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 3901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("\n%s(%s)%s:\n", prefix, fname, suffix); 3902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("\n%s:\n", fname); 3904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3906b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr == NULL) 3907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3908b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1)); 3909b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 3910b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3912b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl = ebl_openbackend (elf); 3913b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If there is no appropriate backend library we cannot test 3914b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper architecture and OS specific features. Any encountered extension 3915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is an error. */ 3916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Go straight by the gABI, check all the parts in turn. */ 3918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_elf_header (ebl, ehdr, size); 3919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3920b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the program header. */ 3921b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_program_header (ebl, ehdr); 3922b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3923b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Next the section headers. It is OK if there are no section 3924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper headers at all. */ 3925b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_sections (ebl, ehdr); 3926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 392741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Report if no relocation section needed the text relocation flag. */ 392841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (textrel && !needed_textrel) 392941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("text relocation flag set but not needed\n")); 393041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 3931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Free the resources. */ 3932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_closebackend (ebl); 3933b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3934