elflint.c revision 8ae5814209558f51c93b583c9ae6fdd482f0cbb2
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Pedantic checking of ELF files compliance with gABI/psABI spec. 282c345d92531e2577f16928efe62c14d19d5fc47Ulrich Drepper Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 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. */ 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper textdomain (PACKAGE); 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{ 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, 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\ 23682c345d92531e2577f16928efe62c14d19d5fc47Ulrich Drepper"), "2006"); 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, 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA 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) 734c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds\n"), 736c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), cnt); 737c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper else if ((sym->st_value - destshdr->sh_addr 738c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper + sym->st_size) > destshdr->sh_size) 739c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 740b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 741c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), cnt, 742c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (int) xndx, section_name (ebl, xndx)); 743c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((destshdr->sh_flags & SHF_TLS) == 0) 748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"), 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL) 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* For object files the symbol value must fall 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper into the section. */ 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value > destshdr->sh_size) 758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (sym->st_value + sym->st_size 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > destshdr->sh_size) 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr = NULL; 773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int pcnt; 774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr != NULL && phdr->p_type == PT_TLS) 779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 781b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (pcnt == ehdr->e_phnum) 783b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 784b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (no_pt_tls++ == 0) 785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"), 787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_value 792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < destshdr->sh_offset - phdr->p_offset) 793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"), 795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (sym->st_value 798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > (destshdr->sh_offset - phdr->p_offset 799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + destshdr->sh_size)) 800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (sym->st_value + sym->st_size 805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > (destshdr->sh_offset - phdr->p_offset 806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + destshdr->sh_size)) 807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) xndx, section_name (ebl, xndx)); 811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 814b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 815b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt >= shdr->sh_info) 820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"), 822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt < shdr->sh_info) 827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 828b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"), 829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (GELF_ST_TYPE (sym->st_info) == STT_SECTION 833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 834b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': symbol %zu: non-local section symbol\n"), 836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (name != NULL) 839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 842653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* Check that address and size match the global offset table. */ 843653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 844653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Shdr destshdr_mem; 845653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), 846653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath &destshdr_mem); 847653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 848653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr == NULL && xndx == SHN_ABS) 849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 850653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* In a DSO, we have to find the GOT section by name. */ 851653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath Elf_Scn *gotscn = NULL; 852c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper Elf_Scn *gscn = NULL; 853653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL) 854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 855653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = gelf_getshdr (gscn, &destshdr_mem); 856653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath assert (destshdr != NULL); 857653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const char *sname = elf_strptr (ebl->elf, 858653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ehdr->e_shstrndx, 859653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr->sh_name); 860653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (sname != NULL) 861b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 862c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (sname, ".got.plt") == 0) 863653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath break; 864c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (sname, ".got") == 0) 865653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath /* Do not stop looking. 866653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath There might be a .got.plt section. */ 867653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath gotscn = gscn; 868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 869653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 870653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = NULL; 871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 872653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 873653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr == NULL && gotscn != NULL) 874653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr = gelf_getshdr (gotscn, &destshdr_mem); 875b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 876b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 877653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const char *sname = (destshdr == NULL ? NULL 878653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath : elf_strptr (ebl->elf, ehdr->e_shstrndx, 879653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath destshdr->sh_name)); 880653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (sname == NULL) 881653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ERROR (gettext ("\ 882653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section\n"), 883653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath idx, section_name (ebl, idx)); 884653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath else if (strcmp (sname, ".got.plt") != 0 885653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath && strcmp (sname, ".got") != 0) 886653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath ERROR (gettext ("\ 887653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to '%s' section\n"), 888653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath idx, section_name (ebl, idx), sname); 889653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 890653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (destshdr != NULL) 891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 892b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found it. */ 893c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (!ebl_check_special_symbol (ebl, ehdr, sym, name, 894c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper destshdr)) 895c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper { 896c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (sym->st_value != destshdr->sh_addr) 897c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper /* This test is more strict than the psABIs which 898c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper usually allow the symbol to be in the middle of 899c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper the .got section, allowing negative offsets. */ 900c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 901653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"), 902c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), 903c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (uint64_t) sym->st_value, 904c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper sname, (uint64_t) destshdr->sh_addr); 905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 906c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (!gnuld && sym->st_size != destshdr->sh_size) 907c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper ERROR (gettext ("\ 908653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathsection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"), 909c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper idx, section_name (ebl, idx), 910c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper (uint64_t) sym->st_size, 911c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper sname, (uint64_t) destshdr->sh_size); 912c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 913b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 914b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"), 917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (strcmp (name, "_DYNAMIC") == 0) 92041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Check that address and size match the dynamic section. 92141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper We locate the dynamic section via the program header 92241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper entry. */ 92341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper for (int pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 92441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 92541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr phdr_mem; 92641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 92841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 92941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 93041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (sym->st_value != phdr->p_vaddr) 93141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"), 93341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), 93441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) sym->st_value, 93541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) phdr->p_vaddr); 936b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 93741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (!gnuld && sym->st_size != phdr->p_memsz) 93841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"), 94041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), 94141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) sym->st_size, 94241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper (uint64_t) phdr->p_memsz); 943b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 94441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 94541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 947b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 948b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 950b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 951b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool 953c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperis_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr, 95428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper bool is_rela) 955b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If this is no executable or DSO it cannot be a .rel.dyn section. */ 957b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 958b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 960b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the section name. Unfortunately necessary. */ 96128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn")) 962b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 963b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 964b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section 965b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper entry can be present as well. */ 966b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr rcshdr_mem; 970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem); 971b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (rcshdr != NULL); 972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rcshdr->sh_type == SHT_DYNAMIC) 974b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found the dynamic section. Look through it. */ 976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *d = elf_getdata (scn, NULL); 977b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 978b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt) 980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn dyn_mem; 982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem); 983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (dyn != NULL); 984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_RELCOUNT) 986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 98728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Found it. Does the type match. */ 98828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (is_rela) 989b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 99028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELCOUNT used for this RELA section\n"), 99128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 99228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 99328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 99428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Does the number specified number of relative 99528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations exceed the total number of 99628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations? */ 99728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 99828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 100028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 100128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 100228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 100328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Make sure the specified number of relocations are 100428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relative. */ 100528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, 100628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx), NULL); 100728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (reldata != NULL) 100828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (size_t inner = 0; 100928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner < shdr->sh_size / shdr->sh_entsize; 101028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++inner) 101128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 101228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rel rel_mem; 101328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rel *rel = gelf_getrel (reldata, inner, 101428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper &rel_mem); 101528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (rel == NULL) 101628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The problem will be reported elsewhere. */ 101728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 101828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 101928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_relative_reloc_p (ebl, 102028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GELF_R_TYPE (rel->r_info))) 102128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 102228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (inner >= dyn->d_un.d_val) 102328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 102428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), 102528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 102628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 102728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 102828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (inner < dyn->d_un.d_val) 102928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 103028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), 103128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 103228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner, (int) dyn->d_un.d_val); 103328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 103428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 103528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 103628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 103728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn->d_tag == DT_RELACOUNT) 103828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 103928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Found it. Does the type match. */ 104028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (!is_rela) 104128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 104228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELACOUNT used for this REL section\n"), 104328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 104428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 104528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 104628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Does the number specified number of relative 104728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations exceed the total number of 104828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relocations? */ 104928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 105028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 105128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 105228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 105328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 105428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 105528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Make sure the specified number of relocations are 105628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper relative. */ 105728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, 105828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx), NULL); 105928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (reldata != NULL) 106028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (size_t inner = 0; 106128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner < shdr->sh_size / shdr->sh_entsize; 106228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++inner) 106328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 106428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rela rela_mem; 106528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Rela *rela = gelf_getrela (reldata, inner, 106628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper &rela_mem); 106728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (rela == NULL) 106828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* The problem will be reported elsewhere. */ 106928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 107028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 107128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_relative_reloc_p (ebl, 107228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GELF_R_TYPE (rela->r_info))) 107328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 107428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (inner >= dyn->d_un.d_val) 107528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 107628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), 107728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 107828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (int) dyn->d_un.d_val); 107928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 108028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (inner < dyn->d_un.d_val) 108128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 108228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), 108328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), 108428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper inner, (int) dyn->d_un.d_val); 108528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 108628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 1087b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1088b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1089b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1090b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1091b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1092b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1093b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1094b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 1095b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1096b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1097b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 109841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstruct loaded_segment 109941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper{ 110041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Addr from; 110141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Addr to; 110241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper bool read_only; 110341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *next; 110441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper}; 110541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 110641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 110741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper/* Check whether binary has text relocation flag set. */ 110841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool textrel; 110941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 111041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper/* Keep track of whether text relocation flag is needed. */ 111141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic bool needed_textrel; 111241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 111341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1114c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic bool 1115c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr, 1116c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper int idx, int reltype, GElf_Shdr **destshdrp, 111741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp) 1118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool reldyn = false; 1120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether the link to the section we relocate is reasonable. */ 1122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info >= shnum) 1123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), 1124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1125c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper else if (shdr->sh_info != 0) 1126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1127c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1128c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper destshdr_memp); 1129c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (*destshdrp != NULL) 1130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1131c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if((*destshdrp)->sh_type != SHT_PROGBITS 1132c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && (*destshdrp)->sh_type != SHT_NOBITS) 1133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); 1135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!reldyn) 1136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': invalid destination section type\n"), 1138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1141c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* There is no standard, but we require that .rel{,a}.dyn 1142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sections have a sh_info value of zero. */ 1143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': sh_info should be zero\n"), 1146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1150c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) 1151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': no relocations for merge-able sections possible\n"), 1153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1157c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT)) 1158c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext (reltype == ELF_T_RELA ? "\ 1159c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ 1160c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Rel\n"), 1161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 116341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* In preparation of checking whether relocations are text 116441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper relocations or not we need to determine whether the file is 116541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper flagged to have text relocation and we need to determine a) what 116641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper the loaded segments are and b) which are read-only. This will 116741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper also allow us to determine whether the same reloc section is 116841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper modifying loaded and not loaded segments. */ 116941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper for (int i = 0; i < ehdr->e_phnum; ++i) 117041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 117141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr phdr_mem; 117241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 117341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr == NULL) 117441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper continue; 117541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 117641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_type == PT_LOAD) 117741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 117841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *newp = xmalloc (sizeof (*newp)); 117941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->from = phdr->p_vaddr; 118041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->to = phdr->p_vaddr + phdr->p_memsz; 118141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->read_only = (phdr->p_flags & PF_W) == 0; 118241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper newp->next = *loadedp; 118341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper *loadedp = newp; 118441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 118541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else if (phdr->p_type == PT_DYNAMIC) 118641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 118741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset); 118841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr dynshdr_mem; 118941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem); 119041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Data *dyndata = elf_getdata (dynscn, NULL); 119141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC 119241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && dyndata != NULL) 119341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j) 119441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 119541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Dyn dyn_mem; 119641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem); 119741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (dyn != NULL 119841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && (dyn->d_tag == DT_TEXTREL 119941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper || (dyn->d_tag == DT_FLAGS 120041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && (dyn->d_un.d_val & DF_TEXTREL) != 0))) 120141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 120241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper textrel = true; 120341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 120441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 120541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 120641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 120741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 120841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 120941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* A quick test which can be easily done here (although it is a bit 121041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper out of place): the text relocation flag makes only sense if there 121141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper is a segment which is not writable. */ 121241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (textrel) 121341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 121441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *seg = *loadedp; 121541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (seg != NULL && !seg->read_only) 121641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper seg = seg->next; 121741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (seg == NULL) 121841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 121941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppertext relocation flag set but there is no read-only segment\n")); 122041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 122141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1222c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper return reldyn; 1223c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper} 1224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 122641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperenum load_state 122741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 122841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_undecided, 122941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_loaded, 123041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_unloaded, 123141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper state_error 123241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper }; 123341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 123441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1235c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic void 1236607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppercheck_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx, 1237607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata, 1238607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Addr r_offset, GElf_Xword r_info, 123941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper const GElf_Shdr *destshdr, bool reldyn, 124041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded, enum load_state *statep) 1241c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper{ 1242c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool known_broken = gnuld; 1243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1244c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info))) 1245c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), 1246c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1247607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1248607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* The executable/DSO can contain relocation sections with 1249607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper all the relocations the linker has applied. Those sections 1250607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper are marked non-loaded, though. */ 1251607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper || (relshdr->sh_flags & SHF_ALLOC) != 0) 1252607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info))) 1253c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), 1255c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1257c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (symshdr != NULL 1258c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && ((GELF_R_SYM (r_info) + 1) 1259c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) 1260c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper > symshdr->sh_size)) 1261c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: invalid symbol index\n"), 1263c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt); 1264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 12656ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper /* No more tests if this is a no-op relocation. */ 12666ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper if (ebl_none_reloc_p (ebl, GELF_R_TYPE (r_info))) 12676ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper return; 12686ca4600fb59d1e1ae3dfb872b184ac91f10c473fUlrich Drepper 1269c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info))) 1270c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1271c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper const char *name; 1272c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper char buf[64]; 1273c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Sym sym_mem; 1274c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 1275c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (sym != NULL 1276c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Get the name for the symbol. */ 1277c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) 1278c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) 1279c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), 1281c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt, 1282c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ebl_reloc_type_name (ebl, GELF_R_SYM (r_info), 1283c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper buf, sizeof (buf))); 1284c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1286c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (reldyn) 1287c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1288c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper // XXX TODO Check .rel.dyn section addresses. 1289c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1290c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper else if (!known_broken) 1291c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1292c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (destshdr != NULL 1293c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && GELF_R_TYPE (r_info) != 0 1294c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper && (r_offset - destshdr->sh_addr) >= destshdr->sh_size) 1295c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': relocation %zu: offset out of bounds\n"), 1297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1298c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 130041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Sym sym_mem; 130141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 130241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 130341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info)) 1304c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Make sure the referenced symbol is an object or unspecified. */ 130541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && sym != NULL 130641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE 130741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) 130841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 130941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper char buf[64]; 131041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), 131141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper idx, section_name (ebl, idx), cnt, 131241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 131341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper buf, sizeof (buf))); 131441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 131541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1316038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1317038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper || (relshdr->sh_flags & SHF_ALLOC) != 0) 131841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 1319038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper bool in_loaded_seg = false; 1320038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper while (loaded != NULL) 1321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1322038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (r_offset < loaded->to 1323038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from) 132441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 1325038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper /* The symbol is in this segment. */ 1326038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (loaded->read_only) 1327038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1328038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (textrel) 1329038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper needed_textrel = true; 1330038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper else 1331038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"), 1332038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx), cnt); 1333038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper } 1334038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper 1335038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper in_loaded_seg = true; 133641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 133741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1338038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper loaded = loaded->next; 1339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 134041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 1341038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper if (*statep == state_undecided) 1342038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper *statep = in_loaded_seg ? state_loaded : state_unloaded; 1343038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper else if ((*statep == state_unloaded && in_loaded_seg) 1344038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper || (*statep == state_loaded && !in_loaded_seg)) 1345038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper { 1346038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper ERROR (gettext ("\ 134741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Dreppersection [%2d] '%s': relocations are against loaded and unloaded data\n"), 1348038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper idx, section_name (ebl, idx)); 1349038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper *statep = state_error; 1350038129b11ac71a13ccaf9029122be86d6c532990Ulrich Drepper } 1351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1356c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1358c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1366c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Check the fields of the section header. */ 1367c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr destshdr_mem; 1368c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *destshdr = NULL; 136941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded = NULL; 1370c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr, 137141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper &destshdr_mem, &loaded); 1372c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1373c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1374c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr symshdr_mem; 1375c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1376c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 137741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper enum load_state state = state_undecided; 1378c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1379c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1381c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rela rela_mem; 1382c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem); 1383c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (rela == NULL) 1384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1385c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("\ 1386c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"), 1387c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1388c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper continue; 1389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1390c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1391607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1392607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper rela->r_offset, rela->r_info, destshdr, reldyn, loaded, 1393607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper &state); 139441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 139541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 139641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 139741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 139841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *old = loaded; 139941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper loaded = loaded->next; 140041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper free (old); 1401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1402c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper} 1403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1404c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1405c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepperstatic void 1406c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Dreppercheck_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1407c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper{ 1408c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1409c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper if (data == NULL) 1410c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper { 1411c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1412c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper idx, section_name (ebl, idx)); 1413c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper return; 1414c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper } 1415c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper 1416c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper /* Check the fields of the section header. */ 1417c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr destshdr_mem; 1418c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Shdr *destshdr = NULL; 141941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *loaded = NULL; 1420c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr, 142141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper &destshdr_mem, &loaded); 1422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 1425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 142741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper enum load_state state = state_undecided; 1428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1429c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel rel_mem; 1432c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem); 1433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rel == NULL) 1434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get relocation %zu: %s\n"), 1437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1441607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1442607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper rel->r_offset, rel->r_info, destshdr, reldyn, loaded, 1443607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper &state); 144441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 144541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 144641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while (loaded != NULL) 144741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 144841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper struct loaded_segment *old = loaded; 144941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper loaded = loaded->next; 145041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper free (old); 1451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Number of dynamic sections. */ 1456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int ndynamic; 1457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1460607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppercheck_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data; 1463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr strshdr_mem; 1464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *strshdr; 1465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 1466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool dependencies[DT_NUM][DT_NUM] = 1467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_NEEDED] = { [DT_STRTAB] = true }, 1469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_PLTRELSZ] = { [DT_JMPREL] = true }, 1470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_HASH] = { [DT_SYMTAB] = true }, 1471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRTAB] = { [DT_STRSZ] = true }, 1472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_HASH] = true, 1473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMENT] = true }, 1474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true }, 1475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELASZ] = { [DT_RELA] = true }, 1476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELAENT] = { [DT_RELA] = true }, 1477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRSZ] = { [DT_STRTAB] = true }, 1478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMENT] = { [DT_SYMTAB] = true }, 1479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SONAME] = { [DT_STRTAB] = true }, 1480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RPATH] = { [DT_STRTAB] = true }, 1481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true }, 1482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELSZ] = { [DT_REL] = true }, 1483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RELENT] = { [DT_REL] = true }, 1484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true }, 1485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RUNPATH] = { [DT_STRTAB] = true }, 1486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_PLTREL] = { [DT_JMPREL] = true }, 1487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_PLTRELSZ] = { [DT_JMPREL] = true } 1488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool has_dt[DT_NUM]; 1490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool level2[DT_NUM] = 1491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_RPATH] = true, 1493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMBOLIC] = true, 1494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_TEXTREL] = true, 1495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_BIND_NOW] = true 1496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const bool mandatory[DT_NUM] = 1498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_NULL] = true, 1500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_HASH] = true, 1501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRTAB] = true, 1502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMTAB] = true, 1503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_STRSZ] = true, 1504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [DT_SYMENT] = true 1505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 1506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Addr reladdr = 0; 1507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word relsz = 0; 1508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Addr pltreladdr = 0; 1509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word pltrelsz = 0; 1510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memset (has_dt, '\0', sizeof (has_dt)); 1512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++ndynamic == 2) 1514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("more than one dynamic section present\n")); 1515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 151641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 1518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 1522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem); 1525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB) 1526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 1528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link), 1529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT)) 1532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section entry size does not match ElfXX_Dyn\n"), 1534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool non_null_warned = false; 1541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Dyn dyn_mem; 1544acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem); 1545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn == NULL) 1546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get dynamic section entry %zu: %s\n"), 1549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned) 1554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"), 1557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper non_null_warned = true; 1559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!ebl_dynamic_tag_check (ebl, dyn->d_tag)) 1562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"), 1563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM) 1566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[dyn->d_tag] 1568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_NEEDED 1569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_NULL 1570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_tag != DT_POSFLAG_1) 1571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: more than one entry with tag %s\n"), 1575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, 1577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf, sizeof (buf))); 1578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (be_strict && level2[dyn->d_tag]) 1581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: level 2 tag %s used\n"), 1585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt, 1586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, 1587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf, sizeof (buf))); 1588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_dt[dyn->d_tag] = true; 1591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL 1594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && dyn->d_un.d_val != DT_RELA) 1595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"), 1597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt); 1598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_REL) 1600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reladdr = dyn->d_un.d_ptr; 1601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_RELSZ) 1602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper relsz = dyn->d_un.d_val; 1603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_JMPREL) 1604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper pltreladdr = dyn->d_un.d_ptr; 1605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dyn->d_tag == DT_PLTRELSZ) 1606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper pltrelsz = dyn->d_un.d_val; 1607607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1608607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that addresses for entries are in loaded segments. */ 1609607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper switch (dyn->d_tag) 1610607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1611607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper size_t n; 1612cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_STRTAB: 1613cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper /* We require the referenced section is the same as the one 1614cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper specified in sh_link. */ 1615cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (strshdr->sh_addr != dyn->d_un.d_val) 1616cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper { 1617cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("\ 1618cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '%s' referenced by sh_link\n"), 1619cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), cnt, 1620cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 1621cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1622cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper } 1623cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper goto check_addr; 1624cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1625607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper default: 1626607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI) 1627607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Value is no pointer. */ 1628607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 1629607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* FALLTHROUGH */ 1630607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 1631cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_AUXILIARY: 1632cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FILTER: 1633cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FINI: 1634cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_FINI_ARRAY: 1635607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_HASH: 1636607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_INIT: 1637607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_INIT_ARRAY: 1638cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_JMPREL: 1639cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_PLTGOT: 1640cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_REL: 1641cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RELA: 1642cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SYMBOLIC: 1643cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SYMTAB: 1644607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_VERDEF: 1645607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper case DT_VERNEED: 1646cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_VERSYM: 1647cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper check_addr: 1648607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper for (n = 0; n < ehdr->e_phnum; ++n) 1649607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1650607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr phdr_mem; 1651607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem); 1652607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr != NULL && phdr->p_type == PT_LOAD 1653607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr <= dyn->d_un.d_ptr 1654607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr) 1655607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 1656607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1657607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (unlikely (n >= ehdr->e_phnum)) 1658607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 1659607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper char buf[50]; 1660607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 1661607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Dreppersection [%2d] '%s': entry %zu: %s value must point into loaded segment\n"), 1662607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper idx, section_name (ebl, idx), cnt, 1663607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1664607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper sizeof (buf))); 1665607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1666cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1667cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper 1668cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_NEEDED: 1669cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RPATH: 1670cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_RUNPATH: 1671cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper case DT_SONAME: 1672cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper if (dyn->d_un.d_ptr >= strshdr->sh_size) 1673cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper { 1674cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper char buf[50]; 1675cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ERROR (gettext ("\ 1676cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Dreppersection [%2d] '%s': entry %zu: %s value must be valid offset in section [%2d] '%s'\n"), 1677cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper idx, section_name (ebl, idx), cnt, 1678cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1679cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper sizeof (buf)), 1680cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 1681cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper } 1682cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper break; 1683607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 1684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < DT_NUM; ++cnt) 1687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_dt[cnt]) 1688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1689acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (int inner = 0; inner < DT_NUM; ++inner) 1690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dependencies[cnt][inner] && ! has_dt[inner]) 1691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf1[50]; 1693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf2[50]; 1694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': contains %s entry but not %s\n"), 1697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)), 1699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2))); 1700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (mandatory[cnt]) 1705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[50]; 1707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': mandatory tag %s not present\n"), 1709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf))); 1711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the rel/rela tags. At least one group must be available. */ 1715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT]) 1716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT])) 1717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper "DT_RELA", "DT_RELASZ", "DT_RELAENT"); 1721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT]) 1723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT])) 1724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': not all of %s, %s, and %s are present\n"), 1726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper "DT_REL", "DT_RELSZ", "DT_RELENT"); 1728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1729b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 1732acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1734acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type != ET_REL) 1735acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 1736acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 1737acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': only relocatable files can have extended section index\n"), 1738acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 1739acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 1740acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 1741b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1742acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1743acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr symshdr_mem; 1744acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB) 1746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended section index section not for symbol table\n"), 1748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1749acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 1750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symdata == NULL) 1751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get data for symbol section\n")); 1752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != sizeof (Elf32_Word)) 1754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': entry size does not match Elf32_Word\n"), 1756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL 1759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_size / shdr->sh_entsize 1760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < symshdr->sh_size / symshdr->sh_entsize)) 1761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended index table too small for symbol table\n"), 1763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 1766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 1768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1769acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = idx + 1; cnt < shnum; ++cnt) 1770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr rshdr_mem; 1772acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem); 1773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX 1774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && rshdr->sh_link == shdr->sh_link) 1775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"), 1778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 1779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 1780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 1781b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1783b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1784acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (*((Elf32_Word *) data->d_buf) != 0) 1787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("symbol 0 should have zero extended section index\n")); 1788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1789acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt]; 1792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (xndx != 0) 1794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym_data; 1796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data); 1797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 1798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get data for symbol %zu\n"), cnt); 1800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != SHN_XINDEX) 1804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 1805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperextended section index is %" PRIu32 " but symbol index is not XINDEX\n"), 1806b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (uint32_t) xndx); 1807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 1810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 181328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 181428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 181528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 181628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 181728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 181828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 181928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 182028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 182128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 182228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 182328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 182428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 182528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t maxidx = nchain; 182628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 182728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL) 182828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 182928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 183028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 183128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (nchain > symshdr->sh_size / symshdr->sh_entsize) 183228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("section [%2d] '%s': chain array too large\n"), 183328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 183428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 183528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = symsize; 183628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 183728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 183828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 183928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (cnt = 2; cnt < 2 + nbucket; ++cnt) 184028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx) 184128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 184228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash bucket reference %zu out of bounds\n"), 184328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2); 184428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 184528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (; cnt < 2 + nbucket + nchain; ++cnt) 184628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx) 184728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 184828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain reference %zu out of bounds\n"), 184928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2 - nbucket); 185028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 185128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 185228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 185328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 185428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 185528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 185628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 185728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; 185828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; 185928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 186028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 186128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 186228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 186328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 186428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 186528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 186628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t maxidx = nchain; 186728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 186828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL) 186928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 187028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 187128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 187228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (nchain > symshdr->sh_size / symshdr->sh_entsize) 187328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("section [%2d] '%s': chain array too large\n"), 187428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx)); 187528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 187628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = symsize; 187728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 187828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 187928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 188028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (cnt = 2; cnt < 2 + nbucket; ++cnt) 188128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx) 188228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 188328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash bucket reference %zu out of bounds\n"), 188428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2); 188528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 188628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper for (; cnt < 2 + nbucket + nchain; ++cnt) 188728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx) 188828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 188928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain reference %zu out of bounds\n"), 189028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt - 2 - nbucket); 189128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 189228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 189328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 189428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 189528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 189628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Shdr *symshdr) 189728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper{ 189828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0]; 189928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; 19008ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; 190128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 19028ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (!powerof2 (bitmask_words)) 19038ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 19048ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': bitmask size not power of 2: %u\n"), 19058ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), bitmask_words); 19068ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 19078ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t bitmask_idxmask = bitmask_words - 1; 19088ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (gelf_getclass (ebl->elf) == ELFCLASS64) 19098ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper bitmask_words *= 2; 19108ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; 19118ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 19128ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shdr->sh_size < (4 + bitmask_words + nbuckets) * sizeof (Elf32_Word)) 191328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 191428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 191528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table section is too small (is %ld, expected at least%ld)\n"), 191628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), (long int) shdr->sh_size, 19178ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper (long int) ((4 + bitmask_words + nbuckets) * sizeof (Elf32_Word))); 191828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper return; 191928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 192028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 19218ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shift > 31) 19228ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 19238ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': 2nd hash function shift too big: %u\n"), 19248ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), shift); 19258ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 19268ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words 19278ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + nbuckets); 192828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 192928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symshdr != NULL) 193028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize); 193128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 193228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* We need the symbol section data. */ 193328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL); 193428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 19358ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper union 19368ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 19378ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word *p32; 19388ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf64_Xword *p64; 19398ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } bitmask = { .p32 = &((Elf32_Word *) data->d_buf)[4] }, 19408ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected = { .p32 = xcalloc (bitmask_words, sizeof (Elf32_Word)) }; 19418ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 19428ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t classbits = gelf_getclass (ebl->elf) == ELFCLASS32 ? 32 : 64; 19438ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 194428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper size_t cnt; 19458ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper for (cnt = 4 + bitmask_words; cnt < 4 + bitmask_words + nbuckets; ++cnt) 194628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 19478ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt]; 194828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 194928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx == 0) 19508ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper continue; 195128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 195228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx < symbias) 195328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 195428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 195528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"), 19568ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); 195728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper continue; 195828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 195928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 196028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper while (symidx - symbias < maxidx) 196128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 19628ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[4 19638ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + bitmask_words 19648ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper + nbuckets 196528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper + symidx 196628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper - symbias]; 196728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 196828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symdata != NULL) 196928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 197028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper /* Check that the referenced symbol is not undefined. */ 197128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym sym_mem; 197228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem); 197328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (sym != NULL && sym->st_shndx == SHN_UNDEF) 197428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 197528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"), 197628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), symidx, cnt / 2 - 1); 197728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 197828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper const char *symname = elf_strptr (ebl->elf, symshdr->sh_link, 197928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper sym->st_name); 198028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symname != NULL) 198128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper { 198228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper Elf32_Word hval = elf_gnu_hash (symname); 198328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if ((hval & ~1u) != (chainhash & ~1u)) 198428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 198528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"), 198628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), symidx, cnt / 2 - 1); 19878ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 19888ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper /* Set the bits in the bitmask. */ 19898ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper size_t maskidx = (hval / classbits) & bitmask_idxmask; 19908ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (classbits == 32) 19918ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 19928ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p32[maskidx] 19938ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT32_C (1) << (hval & (classbits - 1)); 19948ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p32[maskidx] 19958ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT32_C (1) << ((hval >> shift) & (classbits - 1)); 19968ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 19978ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper else 19988ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper { 19998ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p64[maskidx] 20008ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT64_C (1) << (hval & (classbits - 1)); 20018ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper collected.p64[maskidx] 20028ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper |= UINT64_C (1) << ((hval >> shift) & (classbits - 1)); 20038ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper } 200428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 200528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 200628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 200728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if ((chainhash & 1) != 0) 200828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 200928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 201028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ++symidx; 201128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 201228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 201328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (symidx - symbias >= maxidx) 201428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 201528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash chain for bucket %zu out of bounds\n"), 201628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt / 2 - 1); 201728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else if (symshdr != NULL 201828ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper && symidx > symshdr->sh_size / symshdr->sh_entsize) 201928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper ERROR (gettext ("\ 202028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"), 202128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper idx, section_name (ebl, idx), cnt / 2 - 1); 202228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper } 20238ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 20248ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (memcmp (collected.p32, bitmask.p32, bitmask_words * sizeof (Elf32_Word))) 20258ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ERROR (gettext ("\ 20268ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': bitmask does not match names in the hash table\n"), 20278ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper idx, section_name (ebl, idx)); 20288ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper 20298ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper free (collected.p32); 203028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper} 203128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 203228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper 203328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepperstatic void 203428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppercheck_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2035b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2036acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type == ET_REL) 2037acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 2038acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2039acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': relocatable files cannot have hash tables\n"), 2040acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 2041acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 2042acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper } 2043b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2044acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2045b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 2046b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2047b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2048b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2049b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2050b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2052acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr symshdr_mem; 2053acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2054acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &symshdr_mem); 2055b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM) 2056b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2057b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': hash table not for dynamic symbol table\n"), 2058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 206028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (shdr->sh_entsize != (tag == SHT_GNU_HASH 20618ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ? (gelf_getclass (ebl->elf) == ELFCLASS32 20628ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper ? sizeof (Elf32_Word) : 0) 206328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper : (size_t) ebl_sysvhash_entrysize (ebl))) 2064b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 206528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Dreppersection [%2d] '%s': hash table entry size incorrect\n"), 2066b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2067b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2068b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) == 0) 2069b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"), 2070b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2071b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 20728ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper if (shdr->sh_size < (tag == SHT_GNU_HASH ? 4 : 2) * (shdr->sh_entsize ?: 4)) 2073b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2074b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 20758ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Dreppersection [%2d] '%s': hash table has not even room for initial administrative entries\n"), 2076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2077b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2078b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2079b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 208028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper switch (tag) 2081b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 208228ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_HASH: 208328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) 208428ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_sysv_hash64 (ebl, shdr, data, idx, symshdr); 208528ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper else 208628ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_sysv_hash (ebl, shdr, data, idx, symshdr); 208728ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 2088b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 208928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_GNU_HASH: 209028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_gnu_hash (ebl, shdr, data, idx, symshdr); 209128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper break; 2092ee4b927bae351b21787355e00a3d28371bf78e8fUlrich Drepper 209328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper default: 20948ae5814209558f51c93b583c9ae6fdd482f0cbb2Ulrich Drepper assert (! "should not happen"); 2095b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2096b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2097b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2098b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2099b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_null (Ebl *ebl, GElf_Shdr *shdr, int idx) 2101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define TEST(name, extra) \ 2103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (extra && shdr->sh_##name != 0) \ 2104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"), \ 2105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), #name) 2106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (name, 1); 2108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (flags, 1); 2109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (addr, 1); 2110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (offset, 1); 2111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (size, idx != 0); 2112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (link, idx != 0); 2113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (info, 1); 2114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (addralign, 1); 2115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper TEST (entsize, 1); 2116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 2123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section groups only allowed in relocatable object files\n"), 2126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check that sh_link is an index of a symbol table. */ 2131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 2132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &symshdr_mem); 2134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr == NULL) 2135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"), 2136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), elf_errmsg (-1)); 2137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr->sh_type != SHT_SYMTAB) 2140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section reference in sh_link is no symbol table\n"), 2142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM, 2145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1, EV_CURRENT)) 2146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': invalid symbol index in sh_info\n"), 2148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags != 0) 2151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"), 2152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (be_strict 2155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT)) 2156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"), 2157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 2162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"), 2163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), elf_errmsg (-1)); 2164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT); 2167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 2168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word val; 2169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size % elsize != 0) 2171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"), 2173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size < elsize) 2176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group without flags word\n"), 2178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (be_strict) 2180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data->d_size < 2 * elsize) 2182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group without member\n"), 2184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (data->d_size < 3 * elsize) 2186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group with only one member\n"), 2188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED 2192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val = *((Elf32_Word *) data->d_buf); 2193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#else 2194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (&val, data->d_buf, elsize); 2195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 2196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((val & ~GRP_COMDAT) != 0) 2197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"), 2198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx)); 2199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = elsize; cnt < data->d_size; cnt += elsize) 2201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if ALLOW_UNALIGNED 2203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val = *((Elf32_Word *) ((char *) data->d_buf + cnt)); 2204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#else 2205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (&val, (char *) data->d_buf + cnt, elsize); 2206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 2207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (val > shnum) 2209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section index %Zu out of range\n"), 2211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize); 2212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr refshdr_mem; 2215acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val), 2216acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &refshdr_mem); 2217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (refshdr == NULL) 2218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': cannot get section header for element %zu: %s\n"), 2220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize, 2221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 2222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (refshdr->sh_type == SHT_GROUP) 2225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': section group contains another group [%2d] '%s'\n"), 2227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((refshdr->sh_flags & SHF_GROUP) == 0) 2231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP flag set\n"), 2233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), cnt / elsize, 2234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++scnref[val] == 2) 2238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' is contained in more than one section group\n"), 2240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper val, section_name (ebl, val)); 2241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char * 2248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection_flags_string (GElf_Word flags, char *buf, size_t len) 2249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper static const struct 2251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Word flag; 2253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name; 2254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } known_flags[] = 2255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define NEWFLAG(name) { SHF_##name, #name } 2257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (WRITE), 2258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (ALLOC), 2259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (EXECINSTR), 2260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (MERGE), 2261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (STRINGS), 2262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (INFO_LINK), 2263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (LINK_ORDER), 2264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (OS_NONCONFORMING), 2265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (GROUP), 2266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NEWFLAG (TLS) 2267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 2268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#undef NEWFLAG 2269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]); 2270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = buf; 2272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2273acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 0; cnt < nknown_flags; ++cnt) 2274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags & known_flags[cnt].flag) 2275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cp != buf && len > 1) 2277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = '|'; 2279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper --len; 2280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name)); 2283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, known_flags[cnt].name, ncopy); 2284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper len -= ncopy; 2285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper flags ^= known_flags[cnt].flag; 2287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags != 0 || cp == buf) 2290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags); 2291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp = '\0'; 2293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return buf; 2295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2298dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2299dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperhas_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx) 2300dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2301dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* First find the relocation section for the symbol table. */ 2302dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = NULL; 2303dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2304dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = NULL; 2305dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2306dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2307dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper shdr = gelf_getshdr (scn, &shdr_mem); 2308dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr != NULL 2309dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) 2310dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && shdr->sh_link == symscnndx) 2311dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Found the section. */ 2312dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2313dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2314dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2315dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (scn == NULL) 2316dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2317dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2318dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2319dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2320dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2321dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2322dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr->sh_type == SHT_REL) 2323dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 2324dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2325dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rel rel_mem; 2326dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rel *rel = gelf_getrel (data, i, &rel_mem); 2327dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (rel == NULL) 2328dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2329dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2330dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_R_SYM (rel->r_info) == symndx 2331dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) 2332dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2333dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2334dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2335dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 2336dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2337dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rela rela_mem; 2338dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Rela *rela = gelf_getrela (data, i, &rela_mem); 2339dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (rela == NULL) 2340dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2341dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2342dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_R_SYM (rela->r_info) == symndx 2343dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) 2344dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2345dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2346dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2347dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2348dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2349dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2350dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2351637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic int 2352637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperin_nobits_scn (Ebl *ebl, unsigned int shndx) 2353637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper{ 2354637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Shdr shdr_mem; 2355637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem); 2356637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper return shdr != NULL && shdr->sh_type == SHT_NOBITS; 2357637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper} 2358637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2359637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2360dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic struct version_namelist 2361dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2362dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *objname; 2363dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name; 2364dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Word ndx; 2365dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper enum { ver_def, ver_need } type; 2366dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *next; 2367dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} *version_namelist; 2368dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2369dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2370dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2371dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperadd_version (const char *objname, const char *name, GElf_Word ndx, int type) 2372dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2373dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that there are no duplications. */ 2374dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *nlp = version_namelist; 2375dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (nlp != NULL) 2376dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2377dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (((nlp->objname == NULL && objname == NULL) 2378dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper || (nlp->objname != NULL && objname != NULL 2379dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (nlp->objname, objname) == 0)) 2380dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (nlp->name, name) == 0) 2381dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return nlp->type == ver_def ? 1 : -1; 2382dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp = nlp->next; 2383dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2384dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2385dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp = xmalloc (sizeof (*nlp)); 2386dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->objname = objname; 2387dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->name = name; 2388dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->ndx = ndx; 2389dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->type = type; 2390dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper nlp->next = version_namelist; 2391dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper version_namelist = nlp; 2392dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2393dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2394dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2395dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2396dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2398dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_versym (Ebl *ebl, int idx) 2399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2400dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = elf_getscn (ebl->elf, idx); 2401dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2402dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2403dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr == NULL) 2404dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The error has already been reported. */ 2405dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2406dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2407dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2408dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2409dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2410dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2411dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2412dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2413dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2414dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2415dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 2416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr symshdr_mem; 2417dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 2418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr == NULL) 2419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The error has already been reported. */ 2420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (symshdr->sh_type != SHT_DYNSYM) 2423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"), 2426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 2428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2431dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The number of elements in the version symbol table must be the 2432dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper same as the number of symbols. */ 2433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size / shdr->sh_entsize 2434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != symshdr->sh_size / symshdr->sh_entsize) 2435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"), 2437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx, section_name (ebl, idx), 2438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr->sh_link, section_name (ebl, shdr->sh_link)); 2439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2440dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *symdata = elf_getdata (symscn, NULL); 2441dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (symdata == NULL) 2442dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* The error has already been reported. */ 2443dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2444dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2445dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 2446dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2447dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Versym versym_mem; 2448dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem); 2449dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym == NULL) 2450dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2451dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2452dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: cannot read version data\n"), 2453dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2454dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2455dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2456dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2457dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Sym sym_mem; 2458dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem); 2459dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (sym == NULL) 2460dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Already reported elsewhere. */ 2461dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper continue; 2462dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 246361655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper if (*versym == VER_NDX_GLOBAL) 2464dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2465dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Global symbol. Make sure it is not defined as local. */ 2466dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2467dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2468dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: local symbol with global scope\n"), 2469dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2470dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 247161655e08ba36430de47381cefdf10d0c26aa8480Ulrich Drepper else if (*versym != VER_NDX_LOCAL) 2472dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2473c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper /* Versioned symbol. Make sure it is not defined as local. */ 2474c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2475c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper ERROR (gettext ("\ 2476c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Dreppersection [%2d] '%s': symbol %d: local symbol with version\n"), 2477c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper idx, section_name (ebl, idx), cnt); 2478c5a06cd2a5f48351b273872ed3e4a2d63d29e459Ulrich Drepper 2479dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Look through the list of defined versions and locate the 2480dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper index we need for this symbol. */ 2481dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist; 2482dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 248328ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper if (runp->ndx == (*versym & 0x7fff)) 2484dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2485dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2486dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 2487dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2488dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp == NULL) 2489dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2490dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: invalid version index %d\n"), 2491dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2492dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (sym->st_shndx == SHN_UNDEF 2493dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && runp->type == ver_def) 2494dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2495dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for defined version\n"), 2496dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2497dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (sym->st_shndx != SHN_UNDEF 2498dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && runp->type == ver_need) 2499dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2500dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Unless this symbol has a copy relocation associated 2501dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper this must not happen. */ 2502637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper if (!has_copy_reloc (ebl, shdr->sh_link, cnt) 2503637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper && !in_nobits_scn (ebl, sym->st_shndx)) 2504dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2505dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': symbol %d: version index %d is for requested version\n"), 2506dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) *versym); 2507dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2508dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2509dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2510dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper} 2511dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2512dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2513dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperstatic int 2514dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperunknown_dependency_p (Elf *elf, GElf_Ehdr *ehdr, const char *fname) 2515dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper{ 2516dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr phdr_mem; 2517dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Phdr *phdr = NULL; 2518dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2519dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int i; 2520dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (i = 0; i < ehdr->e_phnum; ++i) 2521dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL 2522dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && phdr->p_type == PT_DYNAMIC) 2523dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2524dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2525dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (i == ehdr->e_phnum) 2526dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2527dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (phdr != NULL); 2528dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); 2529dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr shdr_mem; 2530dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2531dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 2532dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL) 2533dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) 2534dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2535dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Dyn dyn_mem; 2536dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); 2537dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (dyn != NULL && dyn->d_tag == DT_NEEDED) 2538dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2539dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val); 2540dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (str != NULL && strcmp (str, fname) == 0) 2541dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Found it. */ 2542dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 0; 2543dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2544dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2545dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2546dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return 1; 2547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2550acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic unsigned int nverneed; 2551acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 2553dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppercheck_verneed (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2555acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (++nverneed == 2) 2556acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("more than one version reference section present\n")); 2557acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2558acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr strshdr_mem; 2559acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2560acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &strshdr_mem); 2561acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr == NULL) 2562acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 2563acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 2564acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2565acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': sh_link does not link to string table\n"), 2566acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 2567dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2568dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2569dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2570dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2571dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2572dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2573dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2574dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2575dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int offset = 0; 2576dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = shdr->sh_info; --cnt >= 0; ) 2577dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2578dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Get the data at the next offset. */ 2579dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verneed needmem; 2580dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 2581dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need == NULL) 2582dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2583dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2584dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int auxoffset = offset + need->vn_aux; 2585dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2586dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need->vn_version != EV_CURRENT) 2587dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2588dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"), 2589dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) need->vn_version); 2590dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2591dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED, 2592dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 1, EV_CURRENT)) 2593dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2594dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 2595dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2596dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2597dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *libname = elf_strptr (ebl->elf, shdr->sh_link, 2598dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper need->vn_file); 2599dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (libname == NULL) 2600dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2601dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2602dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid file reference\n"), 2603dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2604dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto next_need; 2605dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2606dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2607dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check that there is a DT_NEEDED entry for the referenced library. */ 2608dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (unknown_dependency_p (ebl->elf, ehdr, libname)) 2609dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2610dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d references unknown dependency\n"), 2611dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2612dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2613dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2614dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2615dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Vernaux auxmem; 2616dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 2617dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 2618dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2619dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2620dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vna_flags & ~VER_FLG_WEAK) != 0) 2621dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2622dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"), 2623dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2624dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2625dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *verstr = elf_strptr (ebl->elf, shdr->sh_link, 2626dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper aux->vna_name); 2627dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (verstr == NULL) 2628dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2629dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"), 2630dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2631dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 2632dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2633dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Word hashval = elf_hash (verstr); 2634dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (hashval != aux->vna_hash) 2635dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2636dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"), 2637dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2638dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, (int) hashval, (int) aux->vna_hash); 2639dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2640dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int res = add_version (libname, verstr, aux->vna_other, 2641dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ver_need); 2642dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (unlikely (res !=0)) 2643dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2644dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (res > 0); 2645dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2646dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"), 2647dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2648dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper cnt, verstr); 2649dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2650dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2651dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2652dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vna_next != 0 || cnt2 > 0) 2653dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, 2654dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper EV_CURRENT)) 2655dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2656dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2657dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"), 2658dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2659dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2660dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2661dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2662dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += MAX (aux->vna_next, 2663dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT)); 2664dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2665dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2666dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Find the next offset. */ 2667dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper next_need: 2668dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper offset += need->vn_next; 2669dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2670dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((need->vn_next != 0 || cnt > 0) 2671dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && offset < auxoffset) 2672dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2673dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid offset to next entry\n"), 2674dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2675dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2676acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper} 2677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2678acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2679acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic unsigned int nverdef; 2680acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2681acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic void 2682acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx) 2683acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper{ 2684acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (++nverdef == 2) 2685acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("more than one version definition section present\n")); 2686acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2687acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr strshdr_mem; 2688acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2689acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper &strshdr_mem); 2690acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr == NULL) 2691acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper return; 2692acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (strshdr->sh_type != SHT_STRTAB) 2693acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 2694acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2d] '%s': sh_link does not link to string table\n"), 2695acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper idx, section_name (ebl, idx)); 2696dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2697dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2698dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (data == NULL) 2699dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2700dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper no_data: 2701dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2702dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2703dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper return; 2704dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2705dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2706dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Iterate over all version definition entries. We check that there 2707dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper is a BASE entry and that each index is unique. To do the later 2708dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper we collection the information in a list which is later 2709dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper examined. */ 2710dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist 2711dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2712dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name; 2713dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *next; 2714dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } *namelist = NULL; 2715dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *refnamelist = NULL; 2716dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2717dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper bool has_base = false; 2718dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int offset = 0; 2719dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt = shdr->sh_info; --cnt >= 0; ) 2720dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2721dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Get the data at the next offset. */ 2722dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdef defmem; 2723dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 2724dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def == NULL) 2725dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 2726dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2727dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_flags & VER_FLG_BASE) != 0) 2728dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2729dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (has_base) 2730dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2731dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': more than one BASE definition\n"), 2732dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2733dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_ndx != VER_NDX_GLOBAL) 2734dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2735dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"), 2736dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2737dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper has_base = true; 2738dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2739dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0) 2740dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2741dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has unknown flag\n"), 2742dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2743dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2744dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_version != EV_CURRENT) 2745dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2746dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong version %d\n"), 2747dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) def->vd_version); 2748dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2749dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF, 2750dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 1, EV_CURRENT)) 2751dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2752dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 2753dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2754dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2755dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper unsigned int auxoffset = offset + def->vd_aux; 2756dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdaux auxmem; 2757dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 2758dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 2759dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 2760dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2761dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 2762dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (name == NULL) 2763dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2764dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2765dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid name reference\n"), 2766dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2767dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto next_def; 2768dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2769dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper GElf_Word hashval = elf_hash (name); 2770dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (def->vd_hash != hashval) 2771dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2772dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"), 2773dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, (int) hashval, 2774dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper (int) def->vd_hash); 2775dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2776dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper int res = add_version (NULL, name, def->vd_ndx, ver_def); 2777dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (unlikely (res !=0)) 2778dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2779dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper assert (res > 0); 2780dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2781dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has duplicate version name '%s'\n"), 2782dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt, name); 2783dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2784dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2785dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct namelist *newname = alloca (sizeof (*newname)); 27866247d634c33be4c9ee4bfc650bb8f06f5add41e5Ulrich Drepper newname->name = name; 2787dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper newname->next = namelist; 2788dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper namelist = newname; 2789dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2790dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += aux->vda_next; 2791dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 2792dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2793dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper aux = gelf_getverdaux (data, auxoffset, &auxmem); 2794dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (aux == NULL) 2795dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper goto no_data; 2796dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2797c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 2798c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper if (name == NULL) 2799c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper ERROR (gettext ("\ 2800c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Dreppersection [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"), 2801c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper idx, section_name (ebl, idx), cnt); 2802c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper else 2803c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper { 2804c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname = alloca (sizeof (*newname)); 2805c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname->name = name; 2806c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper newname->next = refnamelist; 2807c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper refnamelist = newname; 2808c2e3135df6741db94a9ec98f1eb57b02277a00b8Ulrich Drepper } 2809dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2810dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt) 2811dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, 2812dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper EV_CURRENT)) 2813dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2814dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2815dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has wrong next field in auxiliary data\n"), 2816dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2817dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2818dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2819dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2820dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper auxoffset += MAX (aux->vda_next, 2821dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT)); 2822dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2823dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2824dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Find the next offset. */ 2825dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper next_def: 2826dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper offset += def->vd_next; 2827dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2828dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if ((def->vd_next != 0 || cnt > 0) 2829dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && offset < auxoffset) 2830dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2831dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': entry %d has invalid offset to next entry\n"), 2832dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), cnt); 2833dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2834dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2835dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (!has_base) 2836dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("section [%2d] '%s': no BASE definition\n"), 2837dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx)); 2838dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2839dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check whether the referenced names are available. */ 2840dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (namelist != NULL) 2841dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2842dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist; 2843dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 2844dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 2845dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp->type == ver_def 2846dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper && strcmp (runp->name, namelist->name) == 0) 2847dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 2848dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 2849dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2850dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2851dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (runp == NULL) 2852dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 2853dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Dreppersection [%2d] '%s': unknown parent version '%s'\n"), 2854dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper idx, section_name (ebl, idx), namelist->name); 2855dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 2856dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper namelist = namelist->next; 2857dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 2858acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper} 2859acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2860acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 2861637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic bool has_loadable_segment; 2862637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic bool has_interp_segment; 2863637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2864637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepperstatic const struct 2865637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper{ 2866637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper const char *name; 2867637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper size_t namelen; 2868637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word type; 2869637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper enum { unused, exact, atleast } attrflag; 2870637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word attr; 2871637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper GElf_Word attr2; 2872637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper} special_sections[] = 2873637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { 2874637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper /* See figure 4-14 in the gABI. */ 2875637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 2876637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".comment", 8, SHT_PROGBITS, exact, 0, 0 }, 2877637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 2878637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 2879637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".debug", 7, SHT_PROGBITS, exact, 0, 0 }, 2880637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE }, 2881637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 }, 2882637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 }, 2883637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 2884637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 2885637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info? 2886637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 }, 2887637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 2888637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 2889637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests? 2890637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".line", 6, SHT_PROGBITS, exact, 0, 0 }, 2891637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".note", 6, SHT_NOTE, exact, 0, 0 }, 2892637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests 2893637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 2894637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC }, // XXX more tests 2895637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests 2896637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 2897637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 2898637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 }, 2899637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 2900637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 2901637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests 2902637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 2903637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 2904637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 2905637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 2906637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2907637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper /* The following are GNU extensions. */ 2908637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 }, 2909637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 }, 2910637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 } 2911637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper }; 2912637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper#define nspecial_sections \ 2913637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper (sizeof (special_sections) / sizeof (special_sections[0])) 2914637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2915637963b564240fe6db4908b28238b75aa0758a06Ulrich Drepper 2916acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepperstatic void 2917acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppercheck_sections (Ebl *ebl, GElf_Ehdr *ehdr) 2918acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper{ 2919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_shoff == 0) 2920b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* No section header. */ 2921b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 2922b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2923b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Allocate array to count references in section groups. */ 2924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scnref = (int *) xcalloc (shnum, sizeof (int)); 2925b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the zeroth section first. It must not have any contents 2927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper and the section header must contain nonzero value at most in the 2928b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sh_size and sh_link fields. */ 2929acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr shdr_mem; 2930acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 2931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 2932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get section header of zeroth section\n")); 2933b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2934b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2935b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_name != 0) 2936b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero name\n")); 2937b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type != 0) 2938b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero type\n")); 2939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags != 0) 2940b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero flags\n")); 2941b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addr != 0) 2942b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero address\n")); 2943b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_offset != 0) 2944b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero offset\n")); 2945b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_info != 0) 2946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero info field\n")); 2947b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addralign != 0) 2948b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero align value\n")); 2949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != 0) 2950b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("zeroth section has nonzero entry size value\n")); 2951b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_size != 0 && ehdr->e_shnum != 0) 2953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero size value while ELF header has nonzero shnum value\n")); 2955b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX) 2957b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2958b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperzeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n")); 2959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2960b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2961acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper bool dot_interp_section = false; 2962b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2963dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper size_t versym_scnndx = 0; 2964acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper for (size_t cnt = 1; cnt < shnum; ++cnt) 2965acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper { 2966acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem); 2967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 2968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 2970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercannot get section header for section [%2zu] '%s': %s\n"), 2971b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), elf_errmsg (-1)); 2972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 2973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2974b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 2976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2977b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnname == NULL) 2978b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("section [%2zu]: invalid name\n"), cnt); 2979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether it is one of the special sections defined in 2982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the gABI. */ 2983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t s; 2984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (s = 0; s < nspecial_sections; ++s) 2985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strncmp (scnname, special_sections[s].name, 2986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper special_sections[s].namelen) == 0) 2987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2988b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf1[100]; 2989b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf2[100]; 2990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char stbuf3[100]; 2991b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2992653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath GElf_Word good_type = special_sections[s].type; 2993653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (special_sections[s].namelen == sizeof ".plt" && 2994653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath !memcmp (special_sections[s].name, ".plt", sizeof ".plt") 2995c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper && ebl_bss_plt_p (ebl, ehdr)) 2996653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath good_type = SHT_NOBITS; 2997653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 2998653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (shdr->sh_type != good_type 2999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !(is_debuginfo && shdr->sh_type == SHT_NOBITS)) 3000b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3001b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2d] '%s' has wrong type: expected %s, is %s\n"), 3002b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (int) cnt, scnname, 3003b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_type_name (ebl, special_sections[s].type, 3004b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3005b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_section_type_name (ebl, shdr->sh_type, 3006b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2))); 3007b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3008b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (special_sections[s].attrflag == exact) 3009b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3010b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Except for the link order and group bit all the 3011b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper other bits should match exactly. */ 3012b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP)) 3013b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != special_sections[s].attr) 3014b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3015b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s, is %s\n"), 3016b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname, 3017b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr, 3018b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3019b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (shdr->sh_flags 3020b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~SHF_LINK_ORDER, 3021b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2))); 3022b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3023b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (special_sections[s].attrflag == atleast) 3024b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3025b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & special_sections[s].attr) 3026b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != special_sections[s].attr 3027b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP 3028b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | special_sections[s].attr 3029b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | special_sections[s].attr2)) 3030b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper != 0)) 3031b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"), 3033b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname, 3034b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr, 3035b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf1, sizeof (stbuf1)), 3036b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (special_sections[s].attr2, 3037b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf2, sizeof (stbuf2)), 3038b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section_flags_string (shdr->sh_flags 3039b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~(SHF_LINK_ORDER 3040b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_GROUP), 3041b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper stbuf3, sizeof (stbuf3))); 3042b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3043b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3044b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (scnname, ".interp") == 0) 3045b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3046b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper dot_interp_section = true; 3047b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3048b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL) 3049b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3050b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' present in object file\n"), 3051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3052b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3053b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) != 0 3054b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !has_loadable_segment) 3055b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3056b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 3057b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((shdr->sh_flags & SHF_ALLOC) == 0 3059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && has_loadable_segment) 3060b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3061b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 3062b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3063b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3064b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3065b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3066b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (scnname, ".symtab_shndx") == 0 3067b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_REL) 3068b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3069b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' is extension section index table in non-object file\n"), 3070b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3071b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3072b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* These sections must have the SHF_ALLOC flag set iff 3073b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper a loadable segment is available. 3074b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3075b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .relxxx 3076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .strtab 3077b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .symtab 3078b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .symtab_shndx 3079b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3080b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Check that if there is a reference from the 3081b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loaded section these sections also have the 3082b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ALLOC flag set. */ 3083b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if 0 3084b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX TODO 3085b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_ALLOC) != 0 3086b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !has_loadable_segment) 3087b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3088b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 3089b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3090b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((shdr->sh_flags & SHF_ALLOC) == 0 3091b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && has_loadable_segment) 3092b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3093b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 3094b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, scnname); 3095b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 3096b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3097b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3098b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3099b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize) 3103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': size not multiple of entry size\n"), 3105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL) 3108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get section header\n")); 3109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type >= SHT_NUM 3111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_LIBLIST 3112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_CHECKSUM 3113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_verdef 3114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr->sh_type != SHT_GNU_verneed 311518e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath && shdr->sh_type != SHT_GNU_versym 311618e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL) 311718e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"), 311818e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath cnt, section_name (ebl, cnt), 311918e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath (int) shdr->sh_type); 3120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ 3122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ 3123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) 3124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags & ~ALL_SH_FLAGS) 312518e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" 312618e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath " %#" PRIx64 "\n"), 3127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), 312818e13427fa32a5464f1678be31512c0e0fec59c7Roland McGrath (uint64_t) shdr->sh_flags & ~(uint64_t) ALL_SH_FLAGS); 3129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (shdr->sh_flags & SHF_TLS) 3130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX Correct? 3132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_addr != 0 && !gnuld) 3133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': thread-local data sections address not zero\n"), 3135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX TODO more tests!? 3138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_link >= shnum) 3141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': invalid section reference in link value\n"), 3143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum) 3146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': invalid section reference in info value\n"), 3148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_MERGE) == 0 3151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_STRINGS) != 0 3152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && be_strict) 3153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': strings flag set without merge flag\n"), 3155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0) 3158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': merge flag set but entry size is zero\n"), 3160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_flags & SHF_GROUP) 3163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_scn_group (ebl, cnt); 3164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0) 3166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the section is contained in a loaded segment 3168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper and that the initialization part matches NOBITS sections. */ 3169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int pcnt; 3170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 3171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr; 3172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 3174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL 3175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ((phdr->p_type == PT_LOAD 3176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_TLS) == 0) 3177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (phdr->p_type == PT_TLS 3178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (shdr->sh_flags & SHF_TLS) != 0)) 3179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && phdr->p_offset <= shdr->sh_offset 3180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && phdr->p_offset + phdr->p_memsz > shdr->sh_offset) 3181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Found the segment. */ 3183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_offset + phdr->p_memsz 3184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper < shdr->sh_offset + shdr->sh_size) 3185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' not fully contained in segment of program header entry %d\n"), 3187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type == SHT_NOBITS) 3190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz 3192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && !is_debuginfo) 3193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"), 3195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3199653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const GElf_Off end = phdr->p_offset + phdr->p_filesz; 3200653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (shdr->sh_offset > end || 3201653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath (shdr->sh_offset == end && shdr->sh_size != 0)) 3202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"), 3204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt), pcnt); 3205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (pcnt == ehdr->e_phnum) 3211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': alloc flag set but section not in any loaded segment\n"), 3213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB) 3217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersection [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"), 3219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, section_name (ebl, cnt)); 3220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (shdr->sh_type) 3222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_DYNSYM: 3224acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper if (ehdr->e_type == ET_REL) 3225acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper ERROR (gettext ("\ 3226acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Dreppersection [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), 3227acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper cnt, section_name (ebl, cnt)); 3228acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper /* FALLTHROUGH */ 3229acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_SYMTAB: 3230dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_symtab (ebl, ehdr, shdr, cnt); 3231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_RELA: 3234c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper check_rela (ebl, ehdr, shdr, cnt); 3235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_REL: 3238c911c9efe553d9af2d4fb0d420d8b614983e16acUlrich Drepper check_rel (ebl, ehdr, shdr, cnt); 3239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_DYNAMIC: 3242607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper check_dynamic (ebl, ehdr, shdr, cnt); 3243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_SYMTAB_SHNDX: 3246acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper check_symtab_shndx (ebl, ehdr, shdr, cnt); 3247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_HASH: 325028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper case SHT_GNU_HASH: 325128ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); 3252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_NULL: 3255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_null (ebl, shdr, cnt); 3256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GROUP: 3259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_group (ebl, ehdr, shdr, cnt); 3260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_GNU_versym: 3263dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* We cannot process this section now since we have no guarantee 3264dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper that the verneed and verdef sections have already been read. 3265dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper Just remember the section index. */ 3266dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym_scnndx != 0) 3267dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("more than one version symbol table present\n")); 3268dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper versym_scnndx = cnt; 3269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3271acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_GNU_verneed: 3272dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_verneed (ebl, ehdr, shdr, cnt); 3273acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper break; 3274acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3275acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper case SHT_GNU_verdef: 3276acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper check_verdef (ebl, shdr, cnt); 3277acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper break; 3278acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper 3279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 3280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Nothing. */ 3281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (has_interp_segment && !dot_interp_section) 3286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("INTERP program header entry but no .interp section\n")); 3287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3288dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (version_namelist != NULL) 3289dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3290dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (versym_scnndx == 0) 3291dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3292dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepperno .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n")); 3293dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else 3294dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper check_versym (ebl, versym_scnndx); 3295dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3296dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper /* Check for duplicate index numbers. */ 3297dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper do 3298dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3299dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *runp = version_namelist->next; 3300dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (runp != NULL) 3301dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3302dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper if (version_namelist->ndx == runp->ndx) 3303dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper { 3304dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("duplicate version index %d\n"), 3305dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper (int) version_namelist->ndx); 3306dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper break; 3307dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3308dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper runp = runp->next; 3309dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3310dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3311dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper struct version_namelist *old = version_namelist; 3312dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper version_namelist = version_namelist->next; 3313dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper free (old); 3314dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3315dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper while (version_namelist != NULL); 3316dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper } 3317dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper else if (versym_scnndx != 0) 3318dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper ERROR (gettext ("\ 3319dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n")); 3320dbace2389b6f89cd4f8f2713aac50a16b16964a2Ulrich Drepper 3321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (scnref); 3322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 3326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt) 3327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 3328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL 3329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 3330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperphdr[%d]: no note entries defined for the type of file\n"), 3332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt); 3333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (is_debuginfo) 3335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The p_offset values in a separate debug file are bogus. */ 3336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 3337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *notemem = gelf_rawchunk (ebl->elf, phdr->p_offset, phdr->p_filesz); 3339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* ELF64 files often use note section entries in the 32-bit format. 3341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper The p_align field is set to 8 in case the 64-bit format is used. 3342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper In case the p_align value is 0 or 4 the 32-bit format is 3343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper used. */ 3344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Xword align = phdr->p_align == 0 || phdr->p_align == 4 ? 4 : 8; 3345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1)) 3346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Xword idx = 0; 3348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (idx < phdr->p_filesz) 3349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint64_t namesz; 3351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint64_t descsz; 3352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint64_t type; 3353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t namesz32; 3354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t descsz32; 3355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (align == 4) 3357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t *ptr = (uint32_t *) (notemem + idx); 3359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((__BYTE_ORDER == __LITTLE_ENDIAN 3361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 3362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (__BYTE_ORDER == __BIG_ENDIAN 3363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 3364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz32 = namesz = bswap_32 (*ptr); 3366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr; 3367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz32 = descsz = bswap_32 (*ptr); 3368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr; 3369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper type = bswap_32 (*ptr); 3370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz32 = namesz = *ptr++; 3374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz32 = descsz = *ptr++; 3375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper type = *ptr; 3376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint64_t *ptr = (uint64_t *) (notemem + idx); 3381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper uint32_t *ptr32 = (uint32_t *) (notemem + idx); 3382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((__BYTE_ORDER == __LITTLE_ENDIAN 3384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 3385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (__BYTE_ORDER == __BIG_ENDIAN 3386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 3387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz = bswap_64 (*ptr); 3389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr; 3390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz = bswap_64 (*ptr); 3391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr; 3392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper type = bswap_64 (*ptr); 3393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz32 = bswap_32 (*ptr32); 3395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ptr32; 3396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz32 = bswap_32 (*ptr32); 3397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz = *ptr++; 3401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz = *ptr++; 3402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper type = *ptr; 3403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper namesz32 = *ptr32++; 3405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper descsz32 = *ptr32; 3406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (idx + 3 * align > phdr->p_filesz 3410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (idx + 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz) 3411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper > phdr->p_filesz)) 3412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_ident[EI_CLASS] == ELFCLASS64 3414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && idx + 3 * 4 <= phdr->p_filesz 3415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (idx + 3 * 4 + ALIGNED_LEN (namesz32) + ALIGNED_LEN (descsz32) 3416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper <= phdr->p_filesz)) 3417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperphdr[%d]: note entries probably in form of a 32-bit ELF file\n"), cnt); 3419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("phdr[%d]: extra %zu bytes after last note\n"), 3421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, (size_t) (phdr->p_filesz - idx)); 3422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure it is one of the note types we know about. */ 3426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_CORE) 3427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (type) 3429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PRSTATUS: 3431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_FPREGSET: 3432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PRPSINFO: 3433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_TASKSTRUCT: /* NT_PRXREG on Solaris. */ 3434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PLATFORM: 3435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_AUXV: 3436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_GWINDOWS: 3437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_ASRS: 3438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PSTATUS: 3439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PSINFO: 3440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PRCRED: 3441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_UTSNAME: 3442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_LWPSTATUS: 3443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_LWPSINFO: 3444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case NT_PRFPXREG: 3445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Known type. */ 3446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 3449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperphdr[%d]: unknown core file note type %" PRIu64 " at offset %" PRIu64 "\n"), 3451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, type, idx); 3452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (type != NT_VERSION) 3457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperphdr[%d]: unknown object file note type %" PRIu64 " at offset %" PRIu64 "\n"), 3459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, type, idx); 3460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Move to the next entry. */ 3463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx += 3 * align + ALIGNED_LEN (namesz) + ALIGNED_LEN (descsz); 3464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gelf_freechunk (ebl->elf, notemem); 3468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 3472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_program_header (Ebl *ebl, GElf_Ehdr *ehdr) 3473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 3474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_phoff == 0) 3475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 3476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 3478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ehdr->e_type != ET_CORE) 3479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperonly executables, shared objects, and core files can have program headers\n")); 3481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_interp = 0; 3483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_tls = 0; 3484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int num_pt_relro = 0; 3485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int cnt = 0; cnt < ehdr->e_phnum; ++cnt) 3487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 3489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr; 3490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 3492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr == NULL) 3493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot get program header entry %d: %s\n"), 3495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt, elf_errmsg (-1)); 3496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 3497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME 3500f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO 3501f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath /* Check for a known machine-specific type. */ 3502f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL) 3503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3504f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrathprogram header entry %d: unknown program header entry type %#" PRIx64 "\n"), 3505f6895046ad74f67fc357d2c9f76dcb6313c13ab9Roland McGrath cnt, (uint64_t) phdr->p_type); 3506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_type == PT_LOAD) 3508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_loadable_segment = true; 3509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_INTERP) 3510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_interp != 1) 3512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (num_pt_interp == 2) 3514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermore than one INTERP entry in program header\n")); 3516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper has_interp_segment = true; 3518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_TLS) 3520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_tls == 2) 3522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("more than one TLS entry in program header\n")); 3523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_NOTE) 3525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_note (ebl, ehdr, phdr, cnt); 352641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else if (phdr->p_type == PT_DYNAMIC) 352741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 352841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (ehdr->e_type == ET_EXEC && ! has_interp_segment) 352941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 353041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperstatic executable cannot have dynamic sections\n")); 353141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper else 353241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 353341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Check that the .dynamic section, if it exists, has 353441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper the same address. */ 353541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper Elf_Scn *scn = NULL; 353641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 353741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 353841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr shdr_mem; 353941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 354041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 354141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper { 354241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_offset != shdr->sh_offset) 354341de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 354441de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperdynamic section reference in program header has wrong offset\n")); 354541de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (phdr->p_memsz != shdr->sh_size) 354641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("\ 354741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepperdynamic section size mismatch in program and section header\n")); 354841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper break; 354941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 355041de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 355141de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 355241de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper } 3553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (phdr->p_type == PT_GNU_RELRO) 3554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (++num_pt_relro == 2) 3556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermore than one GNU_RELRO entry in program header\n")); 3558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check that the region is in a writable segment. */ 3561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int inner; 3562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (inner = 0; inner < ehdr->e_phnum; ++inner) 3563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr2_mem; 3565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr2; 3566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 3568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr2 == NULL) 3569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 3570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr2->p_type == PT_LOAD 3572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && phdr->p_vaddr >= phdr2->p_vaddr 3573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (phdr->p_vaddr + phdr->p_memsz 3574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper <= phdr2->p_vaddr + phdr2->p_memsz)) 3575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((phdr2->p_flags & PF_W) == 0) 3577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloadable segment GNU_RELRO applies to is not writable\n")); 3579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((phdr2->p_flags & PF_X) != 0) 3580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperloadable segment GNU_RELRO applies to is executable\n")); 3582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 3583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (inner >= ehdr->e_phnum) 3587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3588607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper%s segment not contained in a loaded segment\n"), "GNU_RELRO"); 3589607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 3590607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper } 3591607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper else if (phdr->p_type == PT_PHDR) 3592607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 3593607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that the region is in a writable segment. */ 3594607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper int inner; 3595607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper for (inner = 0; inner < ehdr->e_phnum; ++inner) 3596607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper { 3597607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr phdr2_mem; 3598607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper GElf_Phdr *phdr2; 3599607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 3600607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 3601607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr2 != NULL 3602607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr2->p_type == PT_LOAD 3603607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && phdr->p_vaddr >= phdr2->p_vaddr 3604607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper && (phdr->p_vaddr + phdr->p_memsz 3605607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper <= phdr2->p_vaddr + phdr2->p_memsz)) 3606607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper break; 3607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3608607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 3609607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (inner >= ehdr->e_phnum) 3610607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 3611607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper%s segment not contained in a loaded segment\n"), "PHDR"); 3612607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper 3613607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper /* Check that offset in segment corresponds to offset in ELF 3614607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper header. */ 3615607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper if (phdr->p_offset != ehdr->e_phoff) 3616607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepper ERROR (gettext ("\ 3617607e05466d3fef5e3ad90aa200d3bba1950cf982Ulrich Drepperprogram header offset in ELF header and PHDR entry do not match")); 3618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_filesz > phdr->p_memsz) 3621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: file size greater than memory size\n"), 3623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt); 3624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr->p_align > 1) 3626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!powerof2 (phdr->p_align)) 3628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: alignment not a power of 2\n"), cnt); 3630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0) 3631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("\ 3632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprogram header entry %d: file offset and virtual address not module of alignment\n"), cnt); 3633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Process one file. */ 3639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 3640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_elf_file (Elf *elf, const char *prefix, const char *suffix, 3641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *fname, size_t size, bool only_one) 3642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 3643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Reset variables. */ 3644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ndynamic = 0; 3645acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper nverneed = 0; 3646acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper nverdef = 0; 364741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper textrel = false; 364841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper needed_textrel = false; 3649acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper has_loadable_segment = false; 3650acb8983909a3f031041ee5d7cbe09fbeb3c31b9aUlrich Drepper has_interp_segment = false; 3651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr ehdr_mem; 3653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 3654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl; 3655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Print the file name. */ 3657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!only_one) 3658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 3660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("\n%s(%s)%s:\n", prefix, fname, suffix); 3661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 3662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper printf ("\n%s:\n", fname); 3663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr == NULL) 3666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1)); 3668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return; 3669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl = ebl_openbackend (elf); 3672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If there is no appropriate backend library we cannot test 3673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper architecture and OS specific features. Any encountered extension 3674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is an error. */ 3675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Go straight by the gABI, check all the parts in turn. */ 3677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_elf_header (ebl, ehdr, size); 3678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check the program header. */ 3680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_program_header (ebl, ehdr); 3681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Next the section headers. It is OK if there are no section 3683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper headers at all. */ 3684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper check_sections (ebl, ehdr); 3685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 368641de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper /* Report if no relocation section needed the text relocation flag. */ 368741de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper if (textrel && !needed_textrel) 368841de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper ERROR (gettext ("text relocation flag set but not needed\n")); 368941de488a0ad6679e816dbab960351e5f62ab8eadUlrich Drepper 3690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Free the resources. */ 3691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_closebackend (ebl); 3692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 3693