elflint.c revision 13b69609bcd5638e6194d940855fea3dd0519605
1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov/* Pedantic checking of ELF files compliance with gABI/psABI spec. 2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc. 3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov This file is part of Red Hat elfutils. 4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Written by Ulrich Drepper <drepper@redhat.com>, 2001. 5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Red Hat elfutils is free software; you can redistribute it and/or modify 7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov it under the terms of the GNU General Public License as published by the 8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Free Software Foundation; version 2 of the License. 9f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Red Hat elfutils is distributed in the hope that it will be useful, but 11f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov WITHOUT ANY WARRANTY; without even the implied warranty of 12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov General Public License for more details. 14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov You should have received a copy of the GNU General Public License along 16f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov with Red Hat elfutils; if not, write to the Free Software Foundation, 17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 1806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Red Hat elfutils is an included package of the Open Invention Network. 20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov An included package of the Open Invention Network is a package for which 21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Open Invention Network licensees cross-license their patents. No patent 22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov license is granted, either expressly or impliedly, by designation as an 23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov included package. Should you wish to participate in the Open Invention 24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Network licensing program, please visit www.openinventionnetwork.com 25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov <http://www.openinventionnetwork.com>. */ 26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 27f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#ifdef HAVE_CONFIG_H 28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov# include <config.h> 29f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#endif 30f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 31f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <argp.h> 32c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#include <assert.h> 33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <byteswap.h> 34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <endian.h> 35f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner#include <error.h> 36b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include <fcntl.h> 37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <gelf.h> 38804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include <inttypes.h> 394437ae213d5435390f0750213b53ec807c047f22Chris Lattner#include <libintl.h> 40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <locale.h> 41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <stdbool.h> 42f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include <stdlib.h> 43b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include <string.h> 44b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include <unistd.h> 45b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include <sys/param.h> 46b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 47b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include <elf-knowledge.h> 48b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include <system.h> 49b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "../libelf/libelfP.h" 50b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "../libelf/common.h" 51b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "../libebl/libeblP.h" 52b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "../libdw/libdwP.h" 53b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "../libdwfl/libdwflP.h" 54b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "../libdw/memory-access.h" 55b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 56b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 57b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov/* Name and version of program. */ 58b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovstatic void print_version (FILE *stream, struct argp_state *state); 59b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovvoid (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; 60b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 61b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov/* Bug report address. */ 62f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovconst char *argp_program_bug_address = PACKAGE_BUGREPORT; 63f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner 64f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner#define ARGP_strict 300 65f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define ARGP_gnuld 301 6606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 6706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov/* Definitions of arguments for argp functions. */ 68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovstatic const struct argp_option options[] = 69825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson{ 70825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 71f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov { "strict", ARGP_strict, NULL, 0, 72f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov N_("Be extremely strict, flag level 2 features."), 0 }, 73f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 }, 74fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 }, 751476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov { "gnu-ld", ARGP_gnuld, NULL, 0, 761476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov N_("Binary has been created with GNU ld and is therefore known to be \ 771476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikovbroken in certain ways"), 0 }, 781476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov { NULL, 0, NULL, 0, NULL, 0 } 791476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov}; 80d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 81d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov/* Short description of program. */ 82825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic const char doc[] = N_("\ 83d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovPedantic checking of ELF files compliance with gABI/psABI spec."); 84c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 85c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov/* Strings for arguments in help texts. */ 86c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikovstatic const char args_doc[] = N_("FILE..."); 87c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 8806ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov/* Prototype for option handler. */ 896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/* Data structure to communicate with argp functions. */ 926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovstatic struct argp argp = 936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov{ 946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov options, parse_opt, args_doc, doc, NULL, NULL, NULL 956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}; 96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 9736b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov 9854f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov/* Declarations of local functions. */ 99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic void process_file (int fd, Elf *elf, const char *prefix, 100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson const char *suffix, const char *fname, size_t size, 101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson bool only_one); 102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic void process_elf_file (Elf *elf, const char *prefix, const char *suffix, 103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson const char *fname, size_t size, bool only_one); 104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic void check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, 105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson GElf_Shdr *shdr, int idx); 106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson/* Report an error. */ 109825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson#define ERROR(str, args...) \ 110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson do { \ 111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson printf (str, ##args); \ 112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ++error_count; \ 113825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } while (0) 114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic unsigned int error_count; 115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson/* True if we should perform very strict testing. */ 117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic bool be_strict; 118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson/* True if no message is to be printed if the run is succesful. */ 120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic bool be_quiet; 121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson/* True if binary is from strip -f, not a normal ELF file. */ 123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic bool is_debuginfo; 124825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 125379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov/* True if binary is assumed to be generated with GNU ld. */ 126379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikovstatic bool gnuld; 127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson/* Index of section header string table. */ 129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic uint32_t shstrndx; 130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson/* Array to count references in section groups. */ 132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic int *scnref; 133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonint 136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonmain (int argc, char *argv[]) 137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson{ 138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson /* Set locale. */ 139825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setlocale (LC_ALL, ""); 140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 141825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson /* Initialize the message catalog. */ 142825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson textdomain (PACKAGE_TARNAME); 143e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman 1448725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov /* Parse and process arguments. */ 1458983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov int remaining; 1468983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov argp_parse (&argp, argc, argv, 0, &remaining, NULL); 1478983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov 1488983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov /* Before we start tell the ELF library which version we are using. */ 1498983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov elf_version (EV_CURRENT); 150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 151825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson /* Now process all the files given at the command line. */ 152825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson bool only_one = remaining + 1 == argc; 153825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson do 154825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { 155825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson /* Open the file. */ 1568983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov int fd = open (argv[remaining], O_RDONLY); 1578983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov if (fd == -1) 1588983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov { 1598983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov error (0, errno, gettext ("cannot open input file")); 1608983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov continue; 1618983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov } 162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 163825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson /* Create an `Elf' descriptor. */ 164825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 165825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (elf == NULL) 166825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ERROR (gettext ("cannot generate Elf descriptor: %s\n"), 167825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson elf_errmsg (-1)); 168b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov else 169b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov { 170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov unsigned int prev_error_count = error_count; 171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov struct stat64 st; 172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov if (fstat64 (fd, &st) != 0) 174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov { 175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov printf ("cannot stat '%s': %m\n", argv[remaining]); 176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov close (fd); 177f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov continue; 178f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 179b8639f52143c99a3902b83555db4c54766c783caAnton Korobeynikov 180f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size, 181ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov only_one); 182e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 1834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* Now we can close the descriptor. */ 1843513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov if (elf_end (elf) != 0) 1855d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov ERROR (gettext ("error while closing Elf descriptor: %s\n"), 1861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov elf_errmsg (-1)); 1871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 188b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov if (prev_error_count == error_count && !be_quiet) 18906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov puts (gettext ("No errors")); 19006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 191f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 192c23197a26f34f559ea9797de51e187087c039c42Torok Edwin close (fd); 193f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 194f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov while (++remaining < argc); 195f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 196f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov return error_count != 0; 197b4202b84d7e54efe5e144885c7da63e6cc465f80Bill Wendling} 19820c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling 1993741be39f98795a841a4d8c35bf54928769ac3cdAnton Korobeynikov 20020c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling/* Handle program arguments. */ 20120c568f366be211323eeaf0e45ef053278ec9ddcBill Wendlingstatic error_t 202c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikovparse_opt (int key, char *arg __attribute__ ((unused)), 203cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov struct argp_state *state __attribute__ ((unused))) 204cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov{ 205cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (key) 206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov { 207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case ARGP_strict: 208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov be_strict = true; 209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'q': 212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov be_quiet = true; 213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'd': 216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov is_debuginfo = true; 217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case ARGP_gnuld: 219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov gnuld = true; 220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case ARGP_KEY_NO_ARGS: 223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov fputs (gettext ("Missing file name.\n"), stderr); 224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, 225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov program_invocation_short_name); 226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov exit (1); 227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return ARGP_ERR_UNKNOWN; 230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return 0; 232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/* Print the version information. */ 236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstatic void 237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov{ 239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov fprintf (stream, "elflint (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov fprintf (stream, gettext ("\ 241c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton KorobeynikovCopyright (C) %s Red Hat, Inc.\n\ 242c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton KorobeynikovThis is free software; see the source for copying conditions. There is NO\n\ 243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikovwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 244f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov"), "2008"); 245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 24698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman} 24798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 24865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel 24998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/* Process one file. */ 25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohmanstatic void 25198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohmanprocess_file (int fd, Elf *elf, const char *prefix, const char *suffix, 25298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const char *fname, size_t size, bool only_one) 25398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman{ 25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman /* We can handle two types of files: ELF files and archives. */ 25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman Elf_Kind kind = elf_kind (elf); 25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 257c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov switch (kind) 258c23197a26f34f559ea9797de51e187087c039c42Torok Edwin { 259c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case ELF_K_ELF: 260c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov /* Yes! It's an ELF file. */ 26198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman process_elf_file (elf, prefix, suffix, fname, size, only_one); 262e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov break; 263e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 264e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case ELF_K_AR: 265e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov { 266e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov Elf *subelf; 267e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov Elf_Cmd cmd = ELF_C_READ_MMAP; 268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 269c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov size_t fname_len = strlen (fname) + 1; 270c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov char new_prefix[prefix_len + 1 + fname_len]; 271c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2]; 27298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman char *cp = new_prefix; 27398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 27465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel /* Create the full name of the file. */ 27598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (prefix != NULL) 27698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman { 27798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman cp = mempcpy (cp, prefix, prefix_len); 27898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman *cp++ = '('; 27998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman strcpy (stpcpy (new_suffix, suffix), ")"); 28098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman } 28198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman else 2824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov new_suffix[0] = '\0'; 283c23197a26f34f559ea9797de51e187087c039c42Torok Edwin memcpy (cp, fname, fname_len); 2844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 2854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* It's an archive. We process each file in it. */ 28698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 28798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman { 288e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov kind = elf_kind (subelf); 289e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 290e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov /* Call this function recursively. */ 2914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (kind == ELF_K_ELF || kind == ELF_K_AR) 2924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov { 2934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Elf_Arhdr *arhdr = elf_getarhdr (subelf); 294c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert (arhdr != NULL); 295c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 296c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov process_file (fd, subelf, new_prefix, new_suffix, 297c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov arhdr->ar_name, arhdr->ar_size, false); 29898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman } 29998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 30065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel /* Get next archive element. */ 30198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman cmd = elf_next (subelf); 30298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (elf_end (subelf) != 0) 30398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"), 30498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman elf_errmsg (-1)); 30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman } 30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman } 307c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov break; 308c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 309c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 310c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov /* We cannot do anything. */ 311c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ERROR (gettext ("\ 312c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton KorobeynikovNot an ELF file - it has the wrong magic bytes at the start\n")); 31398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman break; 31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman } 31598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman} 316c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikovstatic const char * 319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikovsection_name (Ebl *ebl, int idx) 320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov{ 321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov GElf_Shdr shdr_mem; 322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov GElf_Shdr *shdr; 323e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson 324825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem); 325804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin 326804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin return elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 327dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin} 3284437ae213d5435390f0750213b53ec807c047f22Chris Lattner 329825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 330dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwinstatic const int valid_e_machine[] = 331c23197a26f34f559ea9797de51e187087c039c42Torok Edwin { 332804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370, 333825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC, 334c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM, 3351df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300, 336c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE, 33798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16, 338c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7, 339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX, 340c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM, 341c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300, 342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA 343c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov }; 344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#define nvalid_e_machine \ 345c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) 346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/* Number of sections. */ 349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikovstatic unsigned int shnum; 350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 35298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohmanstatic void 353c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikovcheck_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size) 354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov{ 355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov char buf[512]; 356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov size_t cnt; 357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov /* Check e_ident field. */ 359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ehdr->e_ident[EI_MAG0] != ELFMAG0) 3604437ae213d5435390f0750213b53ec807c047f22Chris Lattner ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0); 361825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (ehdr->e_ident[EI_MAG1] != ELFMAG1) 362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1); 363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ehdr->e_ident[EI_MAG2] != ELFMAG2) 364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2); 3653f2bf85d14759cc4b28a86805f566ac805a54d00David Greene if (ehdr->e_ident[EI_MAG3] != ELFMAG3) 366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3); 367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 368c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ehdr->e_ident[EI_CLASS] != ELFCLASS32 369825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && ehdr->e_ident[EI_CLASS] != ELFCLASS64) 37098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ERROR (gettext ("e_ident[%d] == %d is no known class\n"), 3716553155172a2e74feff1253837daa608123de54aEvan Cheng EI_CLASS, ehdr->e_ident[EI_CLASS]); 372c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 373c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB 374c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov && ehdr->e_ident[EI_DATA] != ELFDATA2MSB) 37598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"), 376c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov EI_DATA, ehdr->e_ident[EI_DATA]); 377fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 37898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) 37998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"), 38065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel EI_VERSION, ehdr->e_ident[EI_VERSION]); 38198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 38298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman /* We currently don't handle any OS ABIs. */ 38398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE) 384fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"), 385fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov EI_OSABI, 386fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 387e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 388e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov /* No ABI versions other than zero supported either. */ 389e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov if (ehdr->e_ident[EI_ABIVERSION] != 0) 390e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov ERROR (gettext ("unsupport ABI version e_ident[%d] == %d\n"), 391e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]); 392e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 393fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt) 39498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (ehdr->e_ident[cnt] != 0) 39598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt); 396fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 39798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman /* Check the e_type field. */ 39898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC 399fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE) 400fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type); 401fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 402fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov /* Check the e_machine field. */ 403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (cnt = 0; cnt < nvalid_e_machine; ++cnt) 404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (valid_e_machine[cnt] == ehdr->e_machine) 405fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov break; 406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (cnt == nvalid_e_machine) 407fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine); 408fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov /* Check the e_version field. */ 410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (ehdr->e_version != EV_CURRENT) 411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov ERROR (gettext ("unknown object file version\n")); 412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov /* Check the e_phoff and e_phnum fields. */ 414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (ehdr->e_phoff == 0) 415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov { 41698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (ehdr->e_phnum != 0) 417fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov ERROR (gettext ("invalid program header offset\n")); 418dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) 419dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov ERROR (gettext ("\ 420fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovexecutables and DSOs cannot have zero program header offset\n")); 421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov else if (ehdr->e_phnum == 0) 423e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov ERROR (gettext ("invalid number of program header entries\n")); 424e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 425e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov /* Check the e_shoff field. */ 426fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov shnum = ehdr->e_shnum; 427e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov shstrndx = ehdr->e_shstrndx; 428fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (ehdr->e_shoff == 0) 429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov { 430e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov if (ehdr->e_shnum != 0) 431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov ERROR (gettext ("invalid section header table offset\n")); 432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 4334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov && ehdr->e_type != ET_CORE) 4344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("section header table must be present\n")); 4354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 43698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman else 43798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman { 43865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel if (ehdr->e_shnum == 0) 43998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman { 44098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman /* Get the header of the zeroth section. The sh_size field 44198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman might contain the section number. */ 44298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman GElf_Shdr shdr_mem; 44398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 44498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (shdr != NULL) 4454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov { 4464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* The error will be reported later. */ 44798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (shdr->sh_size == 0) 44898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ERROR (gettext ("\ 4494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikovinvalid number of section header table entries\n")); 45098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman else 4514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov shnum = shdr->sh_size; 4524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (ehdr->e_shstrndx == SHN_XINDEX) 4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov { 4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* Get the header of the zeroth section. The sh_size field 4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov might contain the section number. */ 4594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov GElf_Shdr shdr_mem; 4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 4614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (shdr != NULL && shdr->sh_link < shnum) 4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov shstrndx = shdr->sh_link; 4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (shstrndx >= shnum) 4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid section header index\n")); 46698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman } 4674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* Check the e_flags field. */ 4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!ebl_machine_flag_check (ebl, ehdr->e_flags)) 470c23197a26f34f559ea9797de51e187087c039c42Torok Edwin ERROR (gettext ("invalid machine flags: %s\n"), 4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* Check e_ehsize, e_phentsize, and e_shentsize fields. */ 4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (gelf_getclass (ebl->elf) == ELFCLASS32) 4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov { 4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr)) 4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr)) 4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid program header size: %hd\n"), 4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ehdr->e_phentsize); 4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size) 4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid program header position or size\n")); 4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr)) 4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid section header size: %hd\n"), 4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ehdr->e_shentsize); 4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid section header position or size\n")); 4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (gelf_getclass (ebl->elf) == ELFCLASS64) 4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov { 4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr)) 4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize); 4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr)) 4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid program header size: %hd\n"), 4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ehdr->e_phentsize); 4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > size) 5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid program header position or size\n")); 5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr)) 5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid section header size: %hd\n"), 5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ehdr->e_shentsize); 5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size) 5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("invalid section header position or size\n")); 507825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } 5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/* Check that there is a section group section with index < IDX which 5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov contains section IDX and that there is exactly one. */ 5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikovstatic void 5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikovcheck_scn_group (Ebl *ebl, int idx) 5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov{ 5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (scnref[idx] == 0) 5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov { 5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* No reference so far. Search following sections, maybe the 5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov order is wrong. */ 5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov size_t cnt; 5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (cnt = idx + 1; cnt < shnum; ++cnt) 5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov { 524825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Elf_Scn *scn = elf_getscn (ebl->elf, cnt); 5254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov GElf_Shdr shdr_mem; 526825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 5274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (shdr == NULL) 5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* We cannot get the section header so we cannot check it. 529825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson The error to get the section header will be shown 5304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov somewhere else. */ 5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov continue; 5324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (shdr->sh_type != SHT_GROUP) 5344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov continue; 5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Elf_Data *data = elf_getdata (scn, NULL); 5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (data == NULL || data->d_size < sizeof (Elf32_Word)) 5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* Cannot check the section. */ 5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov continue; 5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Elf32_Word *grpdata = (Elf32_Word *) data->d_buf; 5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word); 5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ++inner) 5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (grpdata[inner] == (Elf32_Word) idx) 5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov goto out; 5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov out: 5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (cnt == shnum) 5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("\ 5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikovsection [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"), 5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov idx, section_name (ebl, idx)); 5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else 5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("\ 55598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohmansection [%2d] '%s': section group [%2zu] '%s' does not preceed group member\n"), 55698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman idx, section_name (ebl, idx), 5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov cnt, section_name (ebl, cnt)); 5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 55998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman} 56098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 56198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 56298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohmanstatic void 5634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikovcheck_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 56465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel{ 56598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool no_xndx_warned = false; 56698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman int no_pt_tls = 0; 56798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 5684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (data == NULL) 5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov { 5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 57198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman idx, section_name (ebl, idx)); 572e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson return; 5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 57498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 5754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov GElf_Shdr strshdr_mem; 5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &strshdr_mem); 5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (strshdr == NULL) 5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov return; 5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 58198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (strshdr->sh_type != SHT_STRTAB) 5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov shdr->sh_link, section_name (ebl, shdr->sh_link), 58498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman idx, section_name (ebl, idx)); 5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /* Search for an extended section index table section. */ 587d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov Elf_Data *xndxdata = NULL; 588d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov Elf32_Word xndxscnidx = 0; 589ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov bool found_xndx = false; 590d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov for (size_t cnt = 1; cnt < shnum; ++cnt) 591e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson if (cnt != (size_t) idx) 592d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov { 593d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt); 594ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov GElf_Shdr xndxshdr_mem; 595d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem); 596d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (xndxshdr == NULL) 597d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov continue; 598d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 599d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX 600d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov && xndxshdr->sh_link == (GElf_Word) idx) 601d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov { 602d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (found_xndx) 603d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov ERROR (gettext ("\ 604e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikovsection [%2d] '%s': symbol table cannot have more than one extended index section\n"), 605e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov idx, section_name (ebl, idx)); 606e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 607e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov xndxdata = elf_getdata (xndxscn, NULL); 608bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov xndxscnidx = elf_ndxscn (xndxscn); 609e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov found_xndx = true; 610e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 611e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 612d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 613aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)) 614ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov ERROR (gettext ("\ 615d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikovsection [%2u] '%s': entry size is does not match ElfXX_Sym\n"), 616d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov idx, section_name (ebl, idx)); 617d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 618d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov /* Test the zeroth entry. */ 6193513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov GElf_Sym sym_mem; 6203513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov Elf32_Word xndx; 6213513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx); 6223513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov if (sym == NULL) 6233513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"), 6243513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov idx, section_name (ebl, idx), 0, elf_errmsg (-1)); 6253513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov else 6263513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov { 6273513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov if (sym->st_name != 0) 6283513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 6295d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov idx, section_name (ebl, idx), "st_name"); 6305d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov if (sym->st_value != 0) 6315d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 6325d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov idx, section_name (ebl, idx), "st_value"); 6335d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov if (sym->st_size != 0) 6345d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 6355d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov idx, section_name (ebl, idx), "st_size"); 6365d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov if (sym->st_info != 0) 6375d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 6383926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov idx, section_name (ebl, idx), "st_info"); 6391bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov if (sym->st_other != 0) 6401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 641ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov idx, section_name (ebl, idx), "st_other"); 642ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov if (sym->st_shndx != 0) 643ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"), 644ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov idx, section_name (ebl, idx), "st_shndx"); 6453926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov if (xndxdata != NULL && xndx != 0) 646ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov ERROR (gettext ("\ 647c23197a26f34f559ea9797de51e187087c039c42Torok Edwinsection [%2d] '%s': XINDEX for zeroth entry not zero\n"), 648ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov xndxscnidx, section_name (ebl, xndxscnidx)); 6493926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov } 6501722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov 6511722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov for (size_t cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 6521722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov { 6531722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx); 654ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov if (sym == NULL) 655ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov { 6563926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"), 6571722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 6581722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov continue; 6591722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov } 6601722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov 661ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov const char *name = NULL; 662ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov if (sym->st_name >= strshdr->sh_size) 663ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov ERROR (gettext ("\ 664ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikovsection [%2d] '%s': symbol %zu: invalid name value\n"), 6653926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov idx, section_name (ebl, idx), cnt); 666ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov else 667ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov { 668ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name); 669ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert (name != NULL); 6703926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov } 671ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 672ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov if (sym->st_shndx == SHN_XINDEX) 673ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov { 674ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov if (xndxdata == NULL) 6753926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov { 676ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov ERROR (gettext ("\ 677ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikovsection [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"), 678ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov idx, section_name (ebl, idx), cnt); 679ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov no_xndx_warned = true; 6803926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov } 681ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov else if (xndx < SHN_LORESERVE) 682ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov ERROR (gettext ("\ 683ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikovsection [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"), 6843926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov xndxscnidx, section_name (ebl, xndxscnidx), cnt, 685825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson xndx); 686ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 687ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov else if ((sym->st_shndx >= SHN_LORESERVE 6881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov // && sym->st_shndx <= SHN_HIRESERVE always true 6891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov && sym->st_shndx != SHN_ABS 690ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov && sym->st_shndx != SHN_COMMON) 6911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov || (sym->st_shndx >= shnum 6921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov && (sym->st_shndx < SHN_LORESERVE 6931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov /* || sym->st_shndx > SHN_HIRESERVE always false */))) 6941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ERROR (gettext ("\ 6951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikovsection [%2d] '%s': symbol %zu: invalid section index\n"), 6961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov idx, section_name (ebl, idx), cnt); 6973926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov else 6981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov xndx = sym->st_shndx; 6991bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7001bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov if (GELF_ST_TYPE (sym->st_info) >= STT_NUM 7013926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0)) 702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"), 703ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov idx, section_name (ebl, idx), cnt); 7041bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7051bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov if (GELF_ST_BIND (sym->st_info) >= STB_NUM) 7061bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ERROR (gettext ("\ 7071bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikovsection [%2d] '%s': symbol %zu: unknown symbol binding\n"), 7081bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov idx, section_name (ebl, idx), cnt); 7091bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (xndx == SHN_COMMON) 7111bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov { 7123926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov /* Common symbols can only appear in relocatable files. */ 7131bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov if (ehdr->e_type != ET_REL) 7148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ERROR (gettext ("\ 715825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonsection [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"), 7168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov idx, section_name (ebl, idx), cnt); 7178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (cnt < shdr->sh_info) 7188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ERROR (gettext ("\ 7193926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovsection [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"), 7201bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov idx, section_name (ebl, idx), cnt); 7218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (GELF_R_TYPE (sym->st_info) == STT_FUNC) 7221bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ERROR (gettext ("\ 7238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikovsection [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"), 7248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov idx, section_name (ebl, idx), cnt); 725b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov } 726b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov else if (xndx > 0 && xndx < shnum) 727b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov { 728e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson GElf_Shdr destshdr_mem; 729b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov GElf_Shdr *destshdr; 730b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 731825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem); 732b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov if (destshdr != NULL) 733b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov { 734b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov GElf_Addr sh_addr = (ehdr->e_type == ET_REL ? 0 735b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov : destshdr->sh_addr); 736b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov if (GELF_ST_TYPE (sym->st_info) != STT_TLS) 737b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov { 73806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (! ebl_check_special_symbol (ebl, ehdr, sym, name, 73906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov destshdr)) 74006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov { 74106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (sym->st_value - sh_addr > destshdr->sh_size) 74206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov { 74306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov /* GNU ld has severe bugs. When it decides to remove 74406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov empty sections it leaves symbols referencing them 74506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov behind. These are symbols in .symtab. */ 74606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (!gnuld 74706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov || strcmp (section_name (ebl, idx), ".symtab") 74806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov || (strcmp (name, "__preinit_array_start") != 0 74906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov && strcmp (name, "__preinit_array_end") != 0 75006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov && strcmp (name, "__init_array_start") != 0 75106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov && strcmp (name, "__init_array_end") != 0 75206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov && strcmp (name, "__fini_array_start") != 0 75306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov && strcmp (name, "__fini_array_end") != 0)) 75406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ERROR (gettext ("\ 75506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikovsection [%2d] '%s': symbol %zu: st_value out of bounds\n"), 75606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov idx, section_name (ebl, idx), cnt); 75706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 75806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov else if ((sym->st_value - sh_addr 75906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov + sym->st_size) > destshdr->sh_size) 76006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ERROR (gettext ("\ 76106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikovsection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 76206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov idx, section_name (ebl, idx), cnt, 76306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov (int) xndx, section_name (ebl, xndx)); 76406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 76506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 76606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov else 76706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov { 76806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if ((destshdr->sh_flags & SHF_TLS) == 0) 76906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ERROR (gettext ("\ 77006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikovsection [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"), 77106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov idx, section_name (ebl, idx), cnt, 77206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov (int) xndx, section_name (ebl, xndx)); 77306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 77406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (ehdr->e_type == ET_REL) 77506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov { 77606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov /* For object files the symbol value must fall 77706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov into the section. */ 77806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (sym->st_value > destshdr->sh_size) 77906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ERROR (gettext ("\ 78006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikovsection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 78106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov idx, section_name (ebl, idx), cnt, 78206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov (int) xndx, section_name (ebl, xndx)); 78306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov else if (sym->st_value + sym->st_size 78406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov > destshdr->sh_size) 78506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ERROR (gettext ("\ 78606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikovsection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 7876534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov idx, section_name (ebl, idx), cnt, 7886534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (int) xndx, section_name (ebl, xndx)); 7896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 7906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov else 7916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov { 7926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov GElf_Phdr phdr_mem; 7936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov GElf_Phdr *phdr = NULL; 7946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov int pcnt; 7956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 7966534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 7976534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov { 7986534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 7996534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (phdr != NULL && phdr->p_type == PT_TLS) 8006534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov break; 8016534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 8026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 8036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (pcnt == ehdr->e_phnum) 8046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov { 8056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (no_pt_tls++ == 0) 8066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ERROR (gettext ("\ 8076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovsection [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"), 8086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov idx, section_name (ebl, idx), cnt); 8096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 8106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov else 8116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov { 8126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (sym->st_value 8136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov < destshdr->sh_offset - phdr->p_offset) 8146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ERROR (gettext ("\ 8156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovsection [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"), 8166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov idx, section_name (ebl, idx), cnt, 8176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (int) xndx, section_name (ebl, xndx)); 8186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov else if (sym->st_value 8196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov > (destshdr->sh_offset - phdr->p_offset 8206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov + destshdr->sh_size)) 8216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ERROR (gettext ("\ 8226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovsection [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"), 823fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov idx, section_name (ebl, idx), cnt, 824fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov (int) xndx, section_name (ebl, xndx)); 825fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov else if (sym->st_value + sym->st_size 826fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov > (destshdr->sh_offset - phdr->p_offset 827d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov + destshdr->sh_size)) 828e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ERROR (gettext ("\ 829e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikovsection [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), 830b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov idx, section_name (ebl, idx), cnt, 8313513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov (int) xndx, section_name (ebl, xndx)); 8321bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov } 833ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 8341bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov } 835fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 836fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 8378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 8398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov { 8408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (cnt >= shdr->sh_info) 8418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ERROR (gettext ("\ 8428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikovsection [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"), 8438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov idx, section_name (ebl, idx), cnt); 844fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng } 845fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng else 8468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov { 8478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (cnt < shdr->sh_info) 848da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov ERROR (gettext ("\ 849da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikovsection [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"), 8508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov idx, section_name (ebl, idx), cnt); 8518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov } 8528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (GELF_ST_TYPE (sym->st_info) == STT_SECTION 8548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 8558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ERROR (gettext ("\ 8568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikovsection [%2d] '%s': symbol %zu: non-local section symbol\n"), 8578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov idx, section_name (ebl, idx), cnt); 8588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (name != NULL) 8608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov { 8618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 8628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov { 8638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov /* Check that address and size match the global offset table. */ 8648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov GElf_Shdr destshdr_mem; 8668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), 8678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov &destshdr_mem); 8688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (destshdr == NULL && xndx == SHN_ABS) 8708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov { 8718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov /* In a DSO, we have to find the GOT section by name. */ 8728b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Elf_Scn *gotscn = NULL; 8738b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Elf_Scn *gscn = NULL; 8748b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL) 875ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng { 876ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng destshdr = gelf_getshdr (gscn, &destshdr_mem); 877ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng assert (destshdr != NULL); 878ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng const char *sname = elf_strptr (ebl->elf, 8798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ehdr->e_shstrndx, 8808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov destshdr->sh_name); 8818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (sname != NULL) 8828b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov { 8838b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (strcmp (sname, ".got.plt") == 0) 8848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov break; 8858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (strcmp (sname, ".got") == 0) 8868b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov /* Do not stop looking. 8878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov There might be a .got.plt section. */ 8888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov gotscn = gscn; 8898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov } 8908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov destshdr = NULL; 8928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov } 8938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (destshdr == NULL && gotscn != NULL) 8958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov destshdr = gelf_getshdr (gotscn, &destshdr_mem); 8968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov } 8978b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const char *sname = ((destshdr == NULL || xndx == SHN_UNDEF) 8998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ? NULL 9008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov : elf_strptr (ebl->elf, ehdr->e_shstrndx, 9018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov destshdr->sh_name)); 9028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (sname == NULL) 9038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov { 9048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov if (xndx != SHN_UNDEF || ehdr->e_type != ET_REL) 9058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ERROR (gettext ("\ 906section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \ 907bad section [%2d]\n"), 908 idx, section_name (ebl, idx), xndx); 909 } 910 else if (strcmp (sname, ".got.plt") != 0 911 && strcmp (sname, ".got") != 0) 912 ERROR (gettext ("\ 913section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \ 914section [%2d] '%s'\n"), 915 idx, section_name (ebl, idx), xndx, sname); 916 917 if (destshdr != NULL) 918 { 919 /* Found it. */ 920 if (!ebl_check_special_symbol (ebl, ehdr, sym, name, 921 destshdr)) 922 { 923 if (ehdr->e_type != ET_REL 924 && sym->st_value != destshdr->sh_addr) 925 /* This test is more strict than the psABIs which 926 usually allow the symbol to be in the middle of 927 the .got section, allowing negative offsets. */ 928 ERROR (gettext ("\ 929section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"), 930 idx, section_name (ebl, idx), 931 (uint64_t) sym->st_value, 932 sname, (uint64_t) destshdr->sh_addr); 933 934 if (!gnuld && sym->st_size != destshdr->sh_size) 935 ERROR (gettext ("\ 936section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"), 937 idx, section_name (ebl, idx), 938 (uint64_t) sym->st_size, 939 sname, (uint64_t) destshdr->sh_size); 940 } 941 } 942 else 943 ERROR (gettext ("\ 944section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"), 945 idx, section_name (ebl, idx)); 946 } 947 else if (strcmp (name, "_DYNAMIC") == 0) 948 /* Check that address and size match the dynamic section. 949 We locate the dynamic section via the program header 950 entry. */ 951 for (int pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 952 { 953 GElf_Phdr phdr_mem; 954 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 955 956 if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 957 { 958 if (sym->st_value != phdr->p_vaddr) 959 ERROR (gettext ("\ 960section [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"), 961 idx, section_name (ebl, idx), 962 (uint64_t) sym->st_value, 963 (uint64_t) phdr->p_vaddr); 964 965 if (!gnuld && sym->st_size != phdr->p_memsz) 966 ERROR (gettext ("\ 967section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"), 968 idx, section_name (ebl, idx), 969 (uint64_t) sym->st_size, 970 (uint64_t) phdr->p_memsz); 971 972 break; 973 } 974 } 975 } 976 } 977} 978 979 980static bool 981is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr, 982 bool is_rela) 983{ 984 /* If this is no executable or DSO it cannot be a .rel.dyn section. */ 985 if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 986 return false; 987 988 /* Check the section name. Unfortunately necessary. */ 989 if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn")) 990 return false; 991 992 /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section 993 entry can be present as well. */ 994 Elf_Scn *scn = NULL; 995 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 996 { 997 GElf_Shdr rcshdr_mem; 998 const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem); 999 assert (rcshdr != NULL); 1000 1001 if (rcshdr->sh_type == SHT_DYNAMIC) 1002 { 1003 /* Found the dynamic section. Look through it. */ 1004 Elf_Data *d = elf_getdata (scn, NULL); 1005 size_t cnt; 1006 1007 for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt) 1008 { 1009 GElf_Dyn dyn_mem; 1010 GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem); 1011 assert (dyn != NULL); 1012 1013 if (dyn->d_tag == DT_RELCOUNT) 1014 { 1015 /* Found it. Does the type match. */ 1016 if (is_rela) 1017 ERROR (gettext ("\ 1018section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"), 1019 idx, section_name (ebl, idx)); 1020 else 1021 { 1022 /* Does the number specified number of relative 1023 relocations exceed the total number of 1024 relocations? */ 1025 if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 1026 ERROR (gettext ("\ 1027section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 1028 idx, section_name (ebl, idx), 1029 (int) dyn->d_un.d_val); 1030 1031 /* Make sure the specified number of relocations are 1032 relative. */ 1033 Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, 1034 idx), NULL); 1035 if (reldata != NULL) 1036 for (size_t inner = 0; 1037 inner < shdr->sh_size / shdr->sh_entsize; 1038 ++inner) 1039 { 1040 GElf_Rel rel_mem; 1041 GElf_Rel *rel = gelf_getrel (reldata, inner, 1042 &rel_mem); 1043 if (rel == NULL) 1044 /* The problem will be reported elsewhere. */ 1045 break; 1046 1047 if (ebl_relative_reloc_p (ebl, 1048 GELF_R_TYPE (rel->r_info))) 1049 { 1050 if (inner >= dyn->d_un.d_val) 1051 ERROR (gettext ("\ 1052section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), 1053 idx, section_name (ebl, idx), 1054 (int) dyn->d_un.d_val); 1055 } 1056 else if (inner < dyn->d_un.d_val) 1057 ERROR (gettext ("\ 1058section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), 1059 idx, section_name (ebl, idx), 1060 inner, (int) dyn->d_un.d_val); 1061 } 1062 } 1063 } 1064 1065 if (dyn->d_tag == DT_RELACOUNT) 1066 { 1067 /* Found it. Does the type match. */ 1068 if (!is_rela) 1069 ERROR (gettext ("\ 1070section [%2d] '%s': DT_RELACOUNT used for this REL section\n"), 1071 idx, section_name (ebl, idx)); 1072 else 1073 { 1074 /* Does the number specified number of relative 1075 relocations exceed the total number of 1076 relocations? */ 1077 if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) 1078 ERROR (gettext ("\ 1079section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), 1080 idx, section_name (ebl, idx), 1081 (int) dyn->d_un.d_val); 1082 1083 /* Make sure the specified number of relocations are 1084 relative. */ 1085 Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf, 1086 idx), NULL); 1087 if (reldata != NULL) 1088 for (size_t inner = 0; 1089 inner < shdr->sh_size / shdr->sh_entsize; 1090 ++inner) 1091 { 1092 GElf_Rela rela_mem; 1093 GElf_Rela *rela = gelf_getrela (reldata, inner, 1094 &rela_mem); 1095 if (rela == NULL) 1096 /* The problem will be reported elsewhere. */ 1097 break; 1098 1099 if (ebl_relative_reloc_p (ebl, 1100 GELF_R_TYPE (rela->r_info))) 1101 { 1102 if (inner >= dyn->d_un.d_val) 1103 ERROR (gettext ("\ 1104section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"), 1105 idx, section_name (ebl, idx), 1106 (int) dyn->d_un.d_val); 1107 } 1108 else if (inner < dyn->d_un.d_val) 1109 ERROR (gettext ("\ 1110section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"), 1111 idx, section_name (ebl, idx), 1112 inner, (int) dyn->d_un.d_val); 1113 } 1114 } 1115 } 1116 } 1117 1118 break; 1119 } 1120 } 1121 1122 return true; 1123} 1124 1125 1126struct loaded_segment 1127{ 1128 GElf_Addr from; 1129 GElf_Addr to; 1130 bool read_only; 1131 struct loaded_segment *next; 1132}; 1133 1134 1135/* Check whether binary has text relocation flag set. */ 1136static bool textrel; 1137 1138/* Keep track of whether text relocation flag is needed. */ 1139static bool needed_textrel; 1140 1141 1142static bool 1143check_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr, 1144 int idx, int reltype, GElf_Shdr **destshdrp, 1145 GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp) 1146{ 1147 bool reldyn = false; 1148 1149 /* Check whether the link to the section we relocate is reasonable. */ 1150 if (shdr->sh_info >= shnum) 1151 ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"), 1152 idx, section_name (ebl, idx)); 1153 else if (shdr->sh_info != 0) 1154 { 1155 *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1156 destshdr_memp); 1157 if (*destshdrp != NULL) 1158 { 1159 if((*destshdrp)->sh_type != SHT_PROGBITS 1160 && (*destshdrp)->sh_type != SHT_NOBITS) 1161 { 1162 reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true); 1163 if (!reldyn) 1164 ERROR (gettext ("\ 1165section [%2d] '%s': invalid destination section type\n"), 1166 idx, section_name (ebl, idx)); 1167 else 1168 { 1169 /* There is no standard, but we require that .rel{,a}.dyn 1170 sections have a sh_info value of zero. */ 1171 if (shdr->sh_info != 0) 1172 ERROR (gettext ("\ 1173section [%2d] '%s': sh_info should be zero\n"), 1174 idx, section_name (ebl, idx)); 1175 } 1176 } 1177 1178 if (((*destshdrp)->sh_flags & (SHF_MERGE | SHF_STRINGS)) != 0) 1179 ERROR (gettext ("\ 1180section [%2d] '%s': no relocations for merge-able sections possible\n"), 1181 idx, section_name (ebl, idx)); 1182 } 1183 } 1184 1185 if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT)) 1186 ERROR (gettext (reltype == ELF_T_RELA ? "\ 1187section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\ 1188section [%2d] '%s': section entry size does not match ElfXX_Rel\n"), 1189 idx, section_name (ebl, idx)); 1190 1191 /* In preparation of checking whether relocations are text 1192 relocations or not we need to determine whether the file is 1193 flagged to have text relocation and we need to determine a) what 1194 the loaded segments are and b) which are read-only. This will 1195 also allow us to determine whether the same reloc section is 1196 modifying loaded and not loaded segments. */ 1197 for (int i = 0; i < ehdr->e_phnum; ++i) 1198 { 1199 GElf_Phdr phdr_mem; 1200 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 1201 if (phdr == NULL) 1202 continue; 1203 1204 if (phdr->p_type == PT_LOAD) 1205 { 1206 struct loaded_segment *newp = xmalloc (sizeof (*newp)); 1207 newp->from = phdr->p_vaddr; 1208 newp->to = phdr->p_vaddr + phdr->p_memsz; 1209 newp->read_only = (phdr->p_flags & PF_W) == 0; 1210 newp->next = *loadedp; 1211 *loadedp = newp; 1212 } 1213 else if (phdr->p_type == PT_DYNAMIC) 1214 { 1215 Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset); 1216 GElf_Shdr dynshdr_mem; 1217 GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem); 1218 Elf_Data *dyndata = elf_getdata (dynscn, NULL); 1219 if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC 1220 && dyndata != NULL) 1221 for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j) 1222 { 1223 GElf_Dyn dyn_mem; 1224 GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem); 1225 if (dyn != NULL 1226 && (dyn->d_tag == DT_TEXTREL 1227 || (dyn->d_tag == DT_FLAGS 1228 && (dyn->d_un.d_val & DF_TEXTREL) != 0))) 1229 { 1230 textrel = true; 1231 break; 1232 } 1233 } 1234 } 1235 } 1236 1237 /* A quick test which can be easily done here (although it is a bit 1238 out of place): the text relocation flag makes only sense if there 1239 is a segment which is not writable. */ 1240 if (textrel) 1241 { 1242 struct loaded_segment *seg = *loadedp; 1243 while (seg != NULL && !seg->read_only) 1244 seg = seg->next; 1245 if (seg == NULL) 1246 ERROR (gettext ("\ 1247text relocation flag set but there is no read-only segment\n")); 1248 } 1249 1250 return reldyn; 1251} 1252 1253 1254enum load_state 1255 { 1256 state_undecided, 1257 state_loaded, 1258 state_unloaded, 1259 state_error 1260 }; 1261 1262 1263static void 1264check_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx, 1265 size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata, 1266 GElf_Addr r_offset, GElf_Xword r_info, 1267 const GElf_Shdr *destshdr, bool reldyn, 1268 struct loaded_segment *loaded, enum load_state *statep) 1269{ 1270 bool known_broken = gnuld; 1271 1272 if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info))) 1273 ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"), 1274 idx, section_name (ebl, idx), cnt); 1275 else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1276 /* The executable/DSO can contain relocation sections with 1277 all the relocations the linker has applied. Those sections 1278 are marked non-loaded, though. */ 1279 || (relshdr->sh_flags & SHF_ALLOC) != 0) 1280 && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info))) 1281 ERROR (gettext ("\ 1282section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"), 1283 idx, section_name (ebl, idx), cnt); 1284 1285 if (symshdr != NULL 1286 && ((GELF_R_SYM (r_info) + 1) 1287 * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT) 1288 > symshdr->sh_size)) 1289 ERROR (gettext ("\ 1290section [%2d] '%s': relocation %zu: invalid symbol index\n"), 1291 idx, section_name (ebl, idx), cnt); 1292 1293 /* No more tests if this is a no-op relocation. */ 1294 if (ebl_none_reloc_p (ebl, GELF_R_TYPE (r_info))) 1295 return; 1296 1297 if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info))) 1298 { 1299 const char *name; 1300 char buf[64]; 1301 GElf_Sym sym_mem; 1302 GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 1303 if (sym != NULL 1304 /* Get the name for the symbol. */ 1305 && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) 1306 && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 ) 1307 ERROR (gettext ("\ 1308section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"), 1309 idx, section_name (ebl, idx), cnt, 1310 ebl_reloc_type_name (ebl, GELF_R_SYM (r_info), 1311 buf, sizeof (buf))); 1312 } 1313 1314 if (reldyn) 1315 { 1316 // XXX TODO Check .rel.dyn section addresses. 1317 } 1318 else if (!known_broken) 1319 { 1320 if (destshdr != NULL 1321 && GELF_R_TYPE (r_info) != 0 1322 && (r_offset - (ehdr->e_type == ET_REL ? 0 1323 : destshdr->sh_addr)) >= destshdr->sh_size) 1324 ERROR (gettext ("\ 1325section [%2d] '%s': relocation %zu: offset out of bounds\n"), 1326 idx, section_name (ebl, idx), cnt); 1327 } 1328 1329 GElf_Sym sym_mem; 1330 GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem); 1331 1332 if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info)) 1333 /* Make sure the referenced symbol is an object or unspecified. */ 1334 && sym != NULL 1335 && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE 1336 && GELF_ST_TYPE (sym->st_info) != STT_OBJECT) 1337 { 1338 char buf[64]; 1339 ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"), 1340 idx, section_name (ebl, idx), cnt, 1341 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 1342 buf, sizeof (buf))); 1343 } 1344 1345 if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 1346 || (relshdr->sh_flags & SHF_ALLOC) != 0) 1347 { 1348 bool in_loaded_seg = false; 1349 while (loaded != NULL) 1350 { 1351 if (r_offset < loaded->to 1352 && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from) 1353 { 1354 /* The symbol is in this segment. */ 1355 if (loaded->read_only) 1356 { 1357 if (textrel) 1358 needed_textrel = true; 1359 else 1360 ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"), 1361 idx, section_name (ebl, idx), cnt); 1362 } 1363 1364 in_loaded_seg = true; 1365 } 1366 1367 loaded = loaded->next; 1368 } 1369 1370 if (*statep == state_undecided) 1371 *statep = in_loaded_seg ? state_loaded : state_unloaded; 1372 else if ((*statep == state_unloaded && in_loaded_seg) 1373 || (*statep == state_loaded && !in_loaded_seg)) 1374 { 1375 ERROR (gettext ("\ 1376section [%2d] '%s': relocations are against loaded and unloaded data\n"), 1377 idx, section_name (ebl, idx)); 1378 *statep = state_error; 1379 } 1380 } 1381} 1382 1383 1384static void 1385check_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1386{ 1387 Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1388 if (data == NULL) 1389 { 1390 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1391 idx, section_name (ebl, idx)); 1392 return; 1393 } 1394 1395 /* Check the fields of the section header. */ 1396 GElf_Shdr destshdr_mem; 1397 GElf_Shdr *destshdr = NULL; 1398 struct loaded_segment *loaded = NULL; 1399 bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr, 1400 &destshdr_mem, &loaded); 1401 1402 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1403 GElf_Shdr symshdr_mem; 1404 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1405 Elf_Data *symdata = elf_getdata (symscn, NULL); 1406 enum load_state state = state_undecided; 1407 1408 for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1409 { 1410 GElf_Rela rela_mem; 1411 GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem); 1412 if (rela == NULL) 1413 { 1414 ERROR (gettext ("\ 1415section [%2d] '%s': cannot get relocation %zu: %s\n"), 1416 idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1417 continue; 1418 } 1419 1420 check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1421 rela->r_offset, rela->r_info, destshdr, reldyn, loaded, 1422 &state); 1423 } 1424 1425 while (loaded != NULL) 1426 { 1427 struct loaded_segment *old = loaded; 1428 loaded = loaded->next; 1429 free (old); 1430 } 1431} 1432 1433 1434static void 1435check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1436{ 1437 Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1438 if (data == NULL) 1439 { 1440 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1441 idx, section_name (ebl, idx)); 1442 return; 1443 } 1444 1445 /* Check the fields of the section header. */ 1446 GElf_Shdr destshdr_mem; 1447 GElf_Shdr *destshdr = NULL; 1448 struct loaded_segment *loaded = NULL; 1449 bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr, 1450 &destshdr_mem, &loaded); 1451 1452 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1453 GElf_Shdr symshdr_mem; 1454 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1455 Elf_Data *symdata = elf_getdata (symscn, NULL); 1456 enum load_state state = state_undecided; 1457 1458 for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1459 { 1460 GElf_Rel rel_mem; 1461 GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem); 1462 if (rel == NULL) 1463 { 1464 ERROR (gettext ("\ 1465section [%2d] '%s': cannot get relocation %zu: %s\n"), 1466 idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1467 continue; 1468 } 1469 1470 check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata, 1471 rel->r_offset, rel->r_info, destshdr, reldyn, loaded, 1472 &state); 1473 } 1474 1475 while (loaded != NULL) 1476 { 1477 struct loaded_segment *old = loaded; 1478 loaded = loaded->next; 1479 free (old); 1480 } 1481} 1482 1483 1484/* Number of dynamic sections. */ 1485static int ndynamic; 1486 1487 1488static void 1489check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1490{ 1491 Elf_Data *data; 1492 GElf_Shdr strshdr_mem; 1493 GElf_Shdr *strshdr; 1494 size_t cnt; 1495 static const bool dependencies[DT_NUM][DT_NUM] = 1496 { 1497 [DT_NEEDED] = { [DT_STRTAB] = true }, 1498 [DT_PLTRELSZ] = { [DT_JMPREL] = true }, 1499 [DT_HASH] = { [DT_SYMTAB] = true }, 1500 [DT_STRTAB] = { [DT_STRSZ] = true }, 1501 [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_SYMENT] = true }, 1502 [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true }, 1503 [DT_RELASZ] = { [DT_RELA] = true }, 1504 [DT_RELAENT] = { [DT_RELA] = true }, 1505 [DT_STRSZ] = { [DT_STRTAB] = true }, 1506 [DT_SYMENT] = { [DT_SYMTAB] = true }, 1507 [DT_SONAME] = { [DT_STRTAB] = true }, 1508 [DT_RPATH] = { [DT_STRTAB] = true }, 1509 [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true }, 1510 [DT_RELSZ] = { [DT_REL] = true }, 1511 [DT_RELENT] = { [DT_REL] = true }, 1512 [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true }, 1513 [DT_RUNPATH] = { [DT_STRTAB] = true }, 1514 [DT_PLTREL] = { [DT_JMPREL] = true }, 1515 }; 1516 bool has_dt[DT_NUM]; 1517 bool has_val_dt[DT_VALNUM]; 1518 bool has_addr_dt[DT_ADDRNUM]; 1519 static const bool level2[DT_NUM] = 1520 { 1521 [DT_RPATH] = true, 1522 [DT_SYMBOLIC] = true, 1523 [DT_TEXTREL] = true, 1524 [DT_BIND_NOW] = true 1525 }; 1526 static const bool mandatory[DT_NUM] = 1527 { 1528 [DT_NULL] = true, 1529 [DT_STRTAB] = true, 1530 [DT_SYMTAB] = true, 1531 [DT_STRSZ] = true, 1532 [DT_SYMENT] = true 1533 }; 1534 GElf_Addr reladdr = 0; 1535 GElf_Word relsz = 0; 1536 GElf_Addr pltreladdr = 0; 1537 GElf_Word pltrelsz = 0; 1538 1539 memset (has_dt, '\0', sizeof (has_dt)); 1540 memset (has_val_dt, '\0', sizeof (has_val_dt)); 1541 memset (has_addr_dt, '\0', sizeof (has_addr_dt)); 1542 1543 if (++ndynamic == 2) 1544 ERROR (gettext ("more than one dynamic section present\n")); 1545 1546 data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1547 if (data == NULL) 1548 { 1549 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 1550 idx, section_name (ebl, idx)); 1551 return; 1552 } 1553 1554 strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem); 1555 if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB) 1556 ERROR (gettext ("\ 1557section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"), 1558 shdr->sh_link, section_name (ebl, shdr->sh_link), 1559 idx, section_name (ebl, idx)); 1560 1561 if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT)) 1562 ERROR (gettext ("\ 1563section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"), 1564 idx, section_name (ebl, idx)); 1565 1566 if (shdr->sh_info != 0) 1567 ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1568 idx, section_name (ebl, idx)); 1569 1570 bool non_null_warned = false; 1571 for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1572 { 1573 GElf_Dyn dyn_mem; 1574 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem); 1575 if (dyn == NULL) 1576 { 1577 ERROR (gettext ("\ 1578section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"), 1579 idx, section_name (ebl, idx), cnt, elf_errmsg (-1)); 1580 continue; 1581 } 1582 1583 if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned) 1584 { 1585 ERROR (gettext ("\ 1586section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"), 1587 idx, section_name (ebl, idx)); 1588 non_null_warned = true; 1589 } 1590 1591 if (!ebl_dynamic_tag_check (ebl, dyn->d_tag)) 1592 ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"), 1593 idx, section_name (ebl, idx), cnt); 1594 1595 if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM) 1596 { 1597 if (has_dt[dyn->d_tag] 1598 && dyn->d_tag != DT_NEEDED 1599 && dyn->d_tag != DT_NULL 1600 && dyn->d_tag != DT_POSFLAG_1) 1601 { 1602 char buf[50]; 1603 ERROR (gettext ("\ 1604section [%2d] '%s': entry %zu: more than one entry with tag %s\n"), 1605 idx, section_name (ebl, idx), cnt, 1606 ebl_dynamic_tag_name (ebl, dyn->d_tag, 1607 buf, sizeof (buf))); 1608 } 1609 1610 if (be_strict && level2[dyn->d_tag]) 1611 { 1612 char buf[50]; 1613 ERROR (gettext ("\ 1614section [%2d] '%s': entry %zu: level 2 tag %s used\n"), 1615 idx, section_name (ebl, idx), cnt, 1616 ebl_dynamic_tag_name (ebl, dyn->d_tag, 1617 buf, sizeof (buf))); 1618 } 1619 1620 has_dt[dyn->d_tag] = true; 1621 } 1622 else if (dyn->d_tag <= DT_VALRNGHI 1623 && DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) 1624 has_val_dt[DT_VALTAGIDX (dyn->d_tag)] = true; 1625 else if (dyn->d_tag <= DT_ADDRRNGHI 1626 && DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) 1627 has_addr_dt[DT_ADDRTAGIDX (dyn->d_tag)] = true; 1628 1629 if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL 1630 && dyn->d_un.d_val != DT_RELA) 1631 ERROR (gettext ("\ 1632section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"), 1633 idx, section_name (ebl, idx), cnt); 1634 1635 if (dyn->d_tag == DT_REL) 1636 reladdr = dyn->d_un.d_ptr; 1637 if (dyn->d_tag == DT_RELSZ) 1638 relsz = dyn->d_un.d_val; 1639 if (dyn->d_tag == DT_JMPREL) 1640 pltreladdr = dyn->d_un.d_ptr; 1641 if (dyn->d_tag == DT_PLTRELSZ) 1642 pltrelsz = dyn->d_un.d_val; 1643 1644 /* Check that addresses for entries are in loaded segments. */ 1645 switch (dyn->d_tag) 1646 { 1647 size_t n; 1648 case DT_STRTAB: 1649 /* We require the referenced section is the same as the one 1650 specified in sh_link. */ 1651 if (strshdr->sh_addr != dyn->d_un.d_val) 1652 { 1653 ERROR (gettext ("\ 1654section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '%s' referenced by sh_link\n"), 1655 idx, section_name (ebl, idx), cnt, 1656 shdr->sh_link, section_name (ebl, shdr->sh_link)); 1657 break; 1658 } 1659 goto check_addr; 1660 1661 default: 1662 if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI) 1663 /* Value is no pointer. */ 1664 break; 1665 /* FALLTHROUGH */ 1666 1667 case DT_AUXILIARY: 1668 case DT_FILTER: 1669 case DT_FINI: 1670 case DT_FINI_ARRAY: 1671 case DT_HASH: 1672 case DT_INIT: 1673 case DT_INIT_ARRAY: 1674 case DT_JMPREL: 1675 case DT_PLTGOT: 1676 case DT_REL: 1677 case DT_RELA: 1678 case DT_SYMBOLIC: 1679 case DT_SYMTAB: 1680 case DT_VERDEF: 1681 case DT_VERNEED: 1682 case DT_VERSYM: 1683 check_addr: 1684 for (n = 0; n < ehdr->e_phnum; ++n) 1685 { 1686 GElf_Phdr phdr_mem; 1687 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem); 1688 if (phdr != NULL && phdr->p_type == PT_LOAD 1689 && phdr->p_vaddr <= dyn->d_un.d_ptr 1690 && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr) 1691 break; 1692 } 1693 if (unlikely (n >= ehdr->e_phnum)) 1694 { 1695 char buf[50]; 1696 ERROR (gettext ("\ 1697section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"), 1698 idx, section_name (ebl, idx), cnt, 1699 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1700 sizeof (buf))); 1701 } 1702 break; 1703 1704 case DT_NEEDED: 1705 case DT_RPATH: 1706 case DT_RUNPATH: 1707 case DT_SONAME: 1708 if (dyn->d_un.d_ptr >= strshdr->sh_size) 1709 { 1710 char buf[50]; 1711 ERROR (gettext ("\ 1712section [%2d] '%s': entry %zu: %s value must be valid offset in section [%2d] '%s'\n"), 1713 idx, section_name (ebl, idx), cnt, 1714 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, 1715 sizeof (buf)), 1716 shdr->sh_link, section_name (ebl, shdr->sh_link)); 1717 } 1718 break; 1719 } 1720 } 1721 1722 for (cnt = 1; cnt < DT_NUM; ++cnt) 1723 if (has_dt[cnt]) 1724 { 1725 for (int inner = 0; inner < DT_NUM; ++inner) 1726 if (dependencies[cnt][inner] && ! has_dt[inner]) 1727 { 1728 char buf1[50]; 1729 char buf2[50]; 1730 1731 ERROR (gettext ("\ 1732section [%2d] '%s': contains %s entry but not %s\n"), 1733 idx, section_name (ebl, idx), 1734 ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)), 1735 ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2))); 1736 } 1737 } 1738 else 1739 { 1740 if (mandatory[cnt]) 1741 { 1742 char buf[50]; 1743 ERROR (gettext ("\ 1744section [%2d] '%s': mandatory tag %s not present\n"), 1745 idx, section_name (ebl, idx), 1746 ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf))); 1747 } 1748 } 1749 1750 /* Make sure we have an hash table. */ 1751 if (!has_dt[DT_HASH] && !has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)]) 1752 ERROR (gettext ("\ 1753section [%2d] '%s': no hash section present\n"), 1754 idx, section_name (ebl, idx)); 1755 1756 /* The GNU-style hash table also needs a symbol table. */ 1757 if (!has_dt[DT_HASH] && has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)] 1758 && !has_dt[DT_SYMTAB]) 1759 ERROR (gettext ("\ 1760section [%2d] '%s': contains %s entry but not %s\n"), 1761 idx, section_name (ebl, idx), 1762 "DT_GNU_HASH", "DT_SYMTAB"); 1763 1764 /* Check the rel/rela tags. At least one group must be available. */ 1765 if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT]) 1766 && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT])) 1767 ERROR (gettext ("\ 1768section [%2d] '%s': not all of %s, %s, and %s are present\n"), 1769 idx, section_name (ebl, idx), 1770 "DT_RELA", "DT_RELASZ", "DT_RELAENT"); 1771 1772 if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT]) 1773 && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT])) 1774 ERROR (gettext ("\ 1775section [%2d] '%s': not all of %s, %s, and %s are present\n"), 1776 idx, section_name (ebl, idx), 1777 "DT_REL", "DT_RELSZ", "DT_RELENT"); 1778 1779 /* Check that all prelink sections are present if any of them is. */ 1780 if (has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)] 1781 || has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)]) 1782 { 1783 if (!has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)]) 1784 ERROR (gettext ("\ 1785section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"), 1786 idx, section_name (ebl, idx), "DT_GNU_PRELINKED"); 1787 if (!has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)]) 1788 ERROR (gettext ("\ 1789section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"), 1790 idx, section_name (ebl, idx), "DT_CHECKSUM"); 1791 1792 /* Only DSOs can be marked like this. */ 1793 if (ehdr->e_type != ET_DYN) 1794 ERROR (gettext ("\ 1795section [%2d] '%s': non-DSO file marked as dependency during prelink\n"), 1796 idx, section_name (ebl, idx)); 1797 } 1798 1799 if (has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)] 1800 || has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)] 1801 || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)] 1802 || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)]) 1803 { 1804 if (!has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)]) 1805 ERROR (gettext ("\ 1806section [%2d] '%s': %s tag missing in prelinked executable\n"), 1807 idx, section_name (ebl, idx), "DT_GNU_CONFLICTSZ"); 1808 if (!has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)]) 1809 ERROR (gettext ("\ 1810section [%2d] '%s': %s tag missing in prelinked executable\n"), 1811 idx, section_name (ebl, idx), "DT_GNU_LIBLISTSZ"); 1812 if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)]) 1813 ERROR (gettext ("\ 1814section [%2d] '%s': %s tag missing in prelinked executable\n"), 1815 idx, section_name (ebl, idx), "DT_GNU_CONFLICT"); 1816 if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)]) 1817 ERROR (gettext ("\ 1818section [%2d] '%s': %s tag missing in prelinked executable\n"), 1819 idx, section_name (ebl, idx), "DT_GNU_LIBLIST"); 1820 } 1821} 1822 1823 1824static void 1825check_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 1826{ 1827 if (ehdr->e_type != ET_REL) 1828 { 1829 ERROR (gettext ("\ 1830section [%2d] '%s': only relocatable files can have extended section index\n"), 1831 idx, section_name (ebl, idx)); 1832 return; 1833 } 1834 1835 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1836 GElf_Shdr symshdr_mem; 1837 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1838 if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB) 1839 ERROR (gettext ("\ 1840section [%2d] '%s': extended section index section not for symbol table\n"), 1841 idx, section_name (ebl, idx)); 1842 Elf_Data *symdata = elf_getdata (symscn, NULL); 1843 if (symdata == NULL) 1844 ERROR (gettext ("cannot get data for symbol section\n")); 1845 1846 if (shdr->sh_entsize != sizeof (Elf32_Word)) 1847 ERROR (gettext ("\ 1848section [%2d] '%s': entry size does not match Elf32_Word\n"), 1849 idx, section_name (ebl, idx)); 1850 1851 if (symshdr != NULL 1852 && (shdr->sh_size / shdr->sh_entsize 1853 < symshdr->sh_size / symshdr->sh_entsize)) 1854 ERROR (gettext ("\ 1855section [%2d] '%s': extended index table too small for symbol table\n"), 1856 idx, section_name (ebl, idx)); 1857 1858 if (shdr->sh_info != 0) 1859 ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"), 1860 idx, section_name (ebl, idx)); 1861 1862 for (size_t cnt = idx + 1; cnt < shnum; ++cnt) 1863 { 1864 GElf_Shdr rshdr_mem; 1865 GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem); 1866 if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX 1867 && rshdr->sh_link == shdr->sh_link) 1868 { 1869 ERROR (gettext ("\ 1870section [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"), 1871 idx, section_name (ebl, idx), 1872 cnt, section_name (ebl, cnt)); 1873 break; 1874 } 1875 } 1876 1877 Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 1878 1879 if (*((Elf32_Word *) data->d_buf) != 0) 1880 ERROR (gettext ("symbol 0 should have zero extended section index\n")); 1881 1882 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1883 { 1884 Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt]; 1885 1886 if (xndx != 0) 1887 { 1888 GElf_Sym sym_data; 1889 GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data); 1890 if (sym == NULL) 1891 { 1892 ERROR (gettext ("cannot get data for symbol %zu\n"), cnt); 1893 continue; 1894 } 1895 1896 if (sym->st_shndx != SHN_XINDEX) 1897 ERROR (gettext ("\ 1898extended section index is %" PRIu32 " but symbol index is not XINDEX\n"), 1899 (uint32_t) xndx); 1900 } 1901 } 1902} 1903 1904 1905static void 1906check_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 1907 GElf_Shdr *symshdr) 1908{ 1909 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 1910 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 1911 1912 if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 1913 ERROR (gettext ("\ 1914section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 1915 idx, section_name (ebl, idx), (long int) shdr->sh_size, 1916 (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 1917 1918 size_t maxidx = nchain; 1919 1920 if (symshdr != NULL) 1921 { 1922 size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 1923 1924 if (nchain > symshdr->sh_size / symshdr->sh_entsize) 1925 ERROR (gettext ("section [%2d] '%s': chain array too large\n"), 1926 idx, section_name (ebl, idx)); 1927 1928 maxidx = symsize; 1929 } 1930 1931 size_t cnt; 1932 for (cnt = 2; cnt < 2 + nbucket; ++cnt) 1933 if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx) 1934 ERROR (gettext ("\ 1935section [%2d] '%s': hash bucket reference %zu out of bounds\n"), 1936 idx, section_name (ebl, idx), cnt - 2); 1937 1938 for (; cnt < 2 + nbucket + nchain; ++cnt) 1939 if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx) 1940 ERROR (gettext ("\ 1941section [%2d] '%s': hash chain reference %zu out of bounds\n"), 1942 idx, section_name (ebl, idx), cnt - 2 - nbucket); 1943} 1944 1945 1946static void 1947check_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 1948 GElf_Shdr *symshdr) 1949{ 1950 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; 1951 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; 1952 1953 if (shdr->sh_size < (2 + nbucket + nchain) * shdr->sh_entsize) 1954 ERROR (gettext ("\ 1955section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"), 1956 idx, section_name (ebl, idx), (long int) shdr->sh_size, 1957 (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); 1958 1959 size_t maxidx = nchain; 1960 1961 if (symshdr != NULL) 1962 { 1963 size_t symsize = symshdr->sh_size / symshdr->sh_entsize; 1964 1965 if (nchain > symshdr->sh_size / symshdr->sh_entsize) 1966 ERROR (gettext ("section [%2d] '%s': chain array too large\n"), 1967 idx, section_name (ebl, idx)); 1968 1969 maxidx = symsize; 1970 } 1971 1972 size_t cnt; 1973 for (cnt = 2; cnt < 2 + nbucket; ++cnt) 1974 if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx) 1975 ERROR (gettext ("\ 1976section [%2d] '%s': hash bucket reference %zu out of bounds\n"), 1977 idx, section_name (ebl, idx), cnt - 2); 1978 1979 for (; cnt < 2 + nbucket + nchain; ++cnt) 1980 if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx) 1981 ERROR (gettext ("\ 1982section [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"), 1983 idx, section_name (ebl, idx), (uint64_t) (cnt - 2 - nbucket)); 1984} 1985 1986 1987static void 1988check_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx, 1989 GElf_Shdr *symshdr) 1990{ 1991 Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0]; 1992 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; 1993 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; 1994 1995 if (!powerof2 (bitmask_words)) 1996 ERROR (gettext ("\ 1997section [%2d] '%s': bitmask size not power of 2: %u\n"), 1998 idx, section_name (ebl, idx), bitmask_words); 1999 2000 size_t bitmask_idxmask = bitmask_words - 1; 2001 if (gelf_getclass (ebl->elf) == ELFCLASS64) 2002 bitmask_words *= 2; 2003 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; 2004 2005 if (shdr->sh_size < (4 + bitmask_words + nbuckets) * sizeof (Elf32_Word)) 2006 { 2007 ERROR (gettext ("\ 2008section [%2d] '%s': hash table section is too small (is %ld, expected at least%ld)\n"), 2009 idx, section_name (ebl, idx), (long int) shdr->sh_size, 2010 (long int) ((4 + bitmask_words + nbuckets) * sizeof (Elf32_Word))); 2011 return; 2012 } 2013 2014 if (shift > 31) 2015 ERROR (gettext ("\ 2016section [%2d] '%s': 2nd hash function shift too big: %u\n"), 2017 idx, section_name (ebl, idx), shift); 2018 2019 size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words 2020 + nbuckets); 2021 2022 if (symshdr != NULL) 2023 maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize); 2024 2025 /* We need the symbol section data. */ 2026 Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL); 2027 2028 union 2029 { 2030 Elf32_Word *p32; 2031 Elf64_Xword *p64; 2032 } bitmask = { .p32 = &((Elf32_Word *) data->d_buf)[4] }, 2033 collected = { .p32 = xcalloc (bitmask_words, sizeof (Elf32_Word)) }; 2034 2035 size_t classbits = gelf_getclass (ebl->elf) == ELFCLASS32 ? 32 : 64; 2036 2037 size_t cnt; 2038 for (cnt = 4 + bitmask_words; cnt < 4 + bitmask_words + nbuckets; ++cnt) 2039 { 2040 Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt]; 2041 2042 if (symidx == 0) 2043 continue; 2044 2045 if (symidx < symbias) 2046 { 2047 ERROR (gettext ("\ 2048section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"), 2049 idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); 2050 continue; 2051 } 2052 2053 while (symidx - symbias < maxidx) 2054 { 2055 Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[4 2056 + bitmask_words 2057 + nbuckets 2058 + symidx 2059 - symbias]; 2060 2061 if (symdata != NULL) 2062 { 2063 /* Check that the referenced symbol is not undefined. */ 2064 GElf_Sym sym_mem; 2065 GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem); 2066 if (sym != NULL && sym->st_shndx == SHN_UNDEF 2067 && GELF_ST_TYPE (sym->st_info) != STT_FUNC) 2068 ERROR (gettext ("\ 2069section [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"), 2070 idx, section_name (ebl, idx), symidx, 2071 cnt - (4 + bitmask_words)); 2072 2073 const char *symname = elf_strptr (ebl->elf, symshdr->sh_link, 2074 sym->st_name); 2075 if (symname != NULL) 2076 { 2077 Elf32_Word hval = elf_gnu_hash (symname); 2078 if ((hval & ~1u) != (chainhash & ~1u)) 2079 ERROR (gettext ("\ 2080section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"), 2081 idx, section_name (ebl, idx), symidx, 2082 cnt - (4 + bitmask_words)); 2083 2084 /* Set the bits in the bitmask. */ 2085 size_t maskidx = (hval / classbits) & bitmask_idxmask; 2086 if (classbits == 32) 2087 { 2088 collected.p32[maskidx] 2089 |= UINT32_C (1) << (hval & (classbits - 1)); 2090 collected.p32[maskidx] 2091 |= UINT32_C (1) << ((hval >> shift) & (classbits - 1)); 2092 } 2093 else 2094 { 2095 collected.p64[maskidx] 2096 |= UINT64_C (1) << (hval & (classbits - 1)); 2097 collected.p64[maskidx] 2098 |= UINT64_C (1) << ((hval >> shift) & (classbits - 1)); 2099 } 2100 } 2101 } 2102 2103 if ((chainhash & 1) != 0) 2104 break; 2105 2106 ++symidx; 2107 } 2108 2109 if (symidx - symbias >= maxidx) 2110 ERROR (gettext ("\ 2111section [%2d] '%s': hash chain for bucket %zu out of bounds\n"), 2112 idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); 2113 else if (symshdr != NULL 2114 && symidx > symshdr->sh_size / symshdr->sh_entsize) 2115 ERROR (gettext ("\ 2116section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"), 2117 idx, section_name (ebl, idx), cnt - (4 + bitmask_words)); 2118 } 2119 2120 if (memcmp (collected.p32, bitmask.p32, bitmask_words * sizeof (Elf32_Word))) 2121 ERROR (gettext ("\ 2122section [%2d] '%s': bitmask does not match names in the hash table\n"), 2123 idx, section_name (ebl, idx)); 2124 2125 free (collected.p32); 2126} 2127 2128 2129static void 2130check_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2131{ 2132 if (ehdr->e_type == ET_REL) 2133 { 2134 ERROR (gettext ("\ 2135section [%2d] '%s': relocatable files cannot have hash tables\n"), 2136 idx, section_name (ebl, idx)); 2137 return; 2138 } 2139 2140 Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2141 if (data == NULL) 2142 { 2143 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2144 idx, section_name (ebl, idx)); 2145 return; 2146 } 2147 2148 GElf_Shdr symshdr_mem; 2149 GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2150 &symshdr_mem); 2151 if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM) 2152 ERROR (gettext ("\ 2153section [%2d] '%s': hash table not for dynamic symbol table\n"), 2154 idx, section_name (ebl, idx)); 2155 2156 if (shdr->sh_entsize != (tag == SHT_GNU_HASH 2157 ? (gelf_getclass (ebl->elf) == ELFCLASS32 2158 ? sizeof (Elf32_Word) : 0) 2159 : (size_t) ebl_sysvhash_entrysize (ebl))) 2160 ERROR (gettext ("\ 2161section [%2d] '%s': hash table entry size incorrect\n"), 2162 idx, section_name (ebl, idx)); 2163 2164 if ((shdr->sh_flags & SHF_ALLOC) == 0) 2165 ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"), 2166 idx, section_name (ebl, idx)); 2167 2168 if (shdr->sh_size < (tag == SHT_GNU_HASH ? 4 : 2) * (shdr->sh_entsize ?: 4)) 2169 { 2170 ERROR (gettext ("\ 2171section [%2d] '%s': hash table has not even room for initial administrative entries\n"), 2172 idx, section_name (ebl, idx)); 2173 return; 2174 } 2175 2176 switch (tag) 2177 { 2178 case SHT_HASH: 2179 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) 2180 check_sysv_hash64 (ebl, shdr, data, idx, symshdr); 2181 else 2182 check_sysv_hash (ebl, shdr, data, idx, symshdr); 2183 break; 2184 2185 case SHT_GNU_HASH: 2186 check_gnu_hash (ebl, shdr, data, idx, symshdr); 2187 break; 2188 2189 default: 2190 assert (! "should not happen"); 2191 } 2192} 2193 2194 2195/* Compare content of both hash tables, it must be identical. */ 2196static void 2197compare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx, 2198 size_t gnu_hash_idx) 2199{ 2200 Elf_Scn *hash_scn = elf_getscn (ebl->elf, hash_idx); 2201 Elf_Data *hash_data = elf_getdata (hash_scn, NULL); 2202 GElf_Shdr hash_shdr_mem; 2203 GElf_Shdr *hash_shdr = gelf_getshdr (hash_scn, &hash_shdr_mem); 2204 Elf_Scn *gnu_hash_scn = elf_getscn (ebl->elf, gnu_hash_idx); 2205 Elf_Data *gnu_hash_data = elf_getdata (gnu_hash_scn, NULL); 2206 GElf_Shdr gnu_hash_shdr_mem; 2207 GElf_Shdr *gnu_hash_shdr = gelf_getshdr (gnu_hash_scn, &gnu_hash_shdr_mem); 2208 2209 if (hash_shdr == NULL || gnu_hash_shdr == NULL 2210 || hash_data == NULL || gnu_hash_data == NULL) 2211 /* None of these pointers should be NULL since we used the 2212 sections already. We are careful nonetheless. */ 2213 return; 2214 2215 /* The link must point to the same symbol table. */ 2216 if (hash_shdr->sh_link != gnu_hash_shdr->sh_link) 2217 { 2218 ERROR (gettext ("\ 2219sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"), 2220 hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name), 2221 gnu_hash_idx, 2222 elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 2223 return; 2224 } 2225 2226 Elf_Scn *sym_scn = elf_getscn (ebl->elf, hash_shdr->sh_link); 2227 Elf_Data *sym_data = elf_getdata (sym_scn, NULL); 2228 GElf_Shdr sym_shdr_mem; 2229 GElf_Shdr *sym_shdr = gelf_getshdr (sym_scn, &sym_shdr_mem); 2230 2231 if (sym_data == NULL || sym_shdr == NULL) 2232 return; 2233 2234 int nentries = sym_shdr->sh_size / sym_shdr->sh_entsize; 2235 char *used = alloca (nentries); 2236 memset (used, '\0', nentries); 2237 2238 /* First go over the GNU_HASH table and mark the entries as used. */ 2239 const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf; 2240 Elf32_Word gnu_nbucket = gnu_hasharr[0]; 2241 const int bitmap_factor = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 1 : 2; 2242 const Elf32_Word *gnu_bucket = (gnu_hasharr 2243 + (4 + gnu_hasharr[2] * bitmap_factor)); 2244 const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0] - gnu_hasharr[1]; 2245 2246 for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt) 2247 { 2248 Elf32_Word symidx = gnu_bucket[cnt]; 2249 if (symidx != STN_UNDEF) 2250 do 2251 used[symidx] |= 1; 2252 while ((gnu_chain[symidx++] & 1u) == 0); 2253 } 2254 2255 /* Now go over the old hash table and check that we cover the same 2256 entries. */ 2257 if (hash_shdr->sh_entsize == sizeof (Elf32_Word)) 2258 { 2259 const Elf32_Word *hasharr = (Elf32_Word *) hash_data->d_buf; 2260 Elf32_Word nbucket = hasharr[0]; 2261 const Elf32_Word *bucket = &hasharr[2]; 2262 const Elf32_Word *chain = &hasharr[2 + nbucket]; 2263 2264 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 2265 { 2266 Elf32_Word symidx = bucket[cnt]; 2267 while (symidx != STN_UNDEF) 2268 { 2269 used[symidx] |= 2; 2270 symidx = chain[symidx]; 2271 } 2272 } 2273 } 2274 else 2275 { 2276 const Elf64_Xword *hasharr = (Elf64_Xword *) hash_data->d_buf; 2277 Elf64_Xword nbucket = hasharr[0]; 2278 const Elf64_Xword *bucket = &hasharr[2]; 2279 const Elf64_Xword *chain = &hasharr[2 + nbucket]; 2280 2281 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) 2282 { 2283 Elf64_Xword symidx = bucket[cnt]; 2284 while (symidx != STN_UNDEF) 2285 { 2286 used[symidx] |= 2; 2287 symidx = chain[symidx]; 2288 } 2289 } 2290 } 2291 2292 /* Now see which entries are not set in one or both hash tables 2293 (unless the symbol is undefined in which case it can be omitted 2294 in the new table format). */ 2295 if ((used[0] & 1) != 0) 2296 ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"), 2297 gnu_hash_idx, 2298 elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 2299 if ((used[0] & 2) != 0) 2300 ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"), 2301 hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name)); 2302 2303 for (int cnt = 1; cnt < nentries; ++cnt) 2304 if (used[cnt] != 0 && used[cnt] != 3) 2305 { 2306 if (used[cnt] == 1) 2307 ERROR (gettext ("\ 2308symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash table in [%2zu] '%s'\n"), 2309 cnt, gnu_hash_idx, 2310 elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name), 2311 hash_idx, 2312 elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name)); 2313 else 2314 { 2315 GElf_Sym sym_mem; 2316 GElf_Sym *sym = gelf_getsym (sym_data, cnt, &sym_mem); 2317 2318 if (sym != NULL && sym->st_shndx != STN_UNDEF) 2319 ERROR (gettext ("\ 2320symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash table in [%2zu] '%s'\n"), 2321 cnt, hash_idx, 2322 elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name), 2323 gnu_hash_idx, 2324 elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); 2325 } 2326 } 2327} 2328 2329 2330static void 2331check_null (Ebl *ebl, GElf_Shdr *shdr, int idx) 2332{ 2333#define TEST(name, extra) \ 2334 if (extra && shdr->sh_##name != 0) \ 2335 ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"), \ 2336 idx, section_name (ebl, idx), #name) 2337 2338 TEST (name, 1); 2339 TEST (flags, 1); 2340 TEST (addr, 1); 2341 TEST (offset, 1); 2342 TEST (size, idx != 0); 2343 TEST (link, idx != 0); 2344 TEST (info, 1); 2345 TEST (addralign, 1); 2346 TEST (entsize, 1); 2347} 2348 2349 2350static void 2351check_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2352{ 2353 if (ehdr->e_type != ET_REL) 2354 { 2355 ERROR (gettext ("\ 2356section [%2d] '%s': section groups only allowed in relocatable object files\n"), 2357 idx, section_name (ebl, idx)); 2358 return; 2359 } 2360 2361 /* Check that sh_link is an index of a symbol table. */ 2362 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 2363 GElf_Shdr symshdr_mem; 2364 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 2365 if (symshdr == NULL) 2366 ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"), 2367 idx, section_name (ebl, idx), elf_errmsg (-1)); 2368 else 2369 { 2370 if (symshdr->sh_type != SHT_SYMTAB) 2371 ERROR (gettext ("\ 2372section [%2d] '%s': section reference in sh_link is no symbol table\n"), 2373 idx, section_name (ebl, idx)); 2374 2375 if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM, 2376 1, EV_CURRENT)) 2377 ERROR (gettext ("\ 2378section [%2d] '%s': invalid symbol index in sh_info\n"), 2379 idx, section_name (ebl, idx)); 2380 2381 if (shdr->sh_flags != 0) 2382 ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"), 2383 idx, section_name (ebl, idx)); 2384 2385 GElf_Sym sym_data; 2386 GElf_Sym *sym = gelf_getsym (elf_getdata (symscn, NULL), shdr->sh_info, 2387 &sym_data); 2388 if (sym == NULL) 2389 ERROR (gettext ("\ 2390section [%2d] '%s': cannot get symbol for signature\n"), 2391 idx, section_name (ebl, idx)); 2392 else if (strcmp (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name), 2393 "") == 0) 2394 ERROR (gettext ("\ 2395section [%2d] '%s': signature symbol canot be empty string\n"), 2396 idx, section_name (ebl, idx)); 2397 2398 if (be_strict 2399 && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT)) 2400 ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"), 2401 idx, section_name (ebl, idx)); 2402 } 2403 2404 Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2405 if (data == NULL) 2406 ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"), 2407 idx, section_name (ebl, idx), elf_errmsg (-1)); 2408 else 2409 { 2410 size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT); 2411 size_t cnt; 2412 Elf32_Word val; 2413 2414 if (data->d_size % elsize != 0) 2415 ERROR (gettext ("\ 2416section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"), 2417 idx, section_name (ebl, idx)); 2418 2419 if (data->d_size < elsize) 2420 ERROR (gettext ("\ 2421section [%2d] '%s': section group without flags word\n"), 2422 idx, section_name (ebl, idx)); 2423 else if (be_strict) 2424 { 2425 if (data->d_size < 2 * elsize) 2426 ERROR (gettext ("\ 2427section [%2d] '%s': section group without member\n"), 2428 idx, section_name (ebl, idx)); 2429 else if (data->d_size < 3 * elsize) 2430 ERROR (gettext ("\ 2431section [%2d] '%s': section group with only one member\n"), 2432 idx, section_name (ebl, idx)); 2433 } 2434 2435#if ALLOW_UNALIGNED 2436 val = *((Elf32_Word *) data->d_buf); 2437#else 2438 memcpy (&val, data->d_buf, elsize); 2439#endif 2440 if ((val & ~GRP_COMDAT) != 0) 2441 ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"), 2442 idx, section_name (ebl, idx)); 2443 2444 for (cnt = elsize; cnt < data->d_size; cnt += elsize) 2445 { 2446#if ALLOW_UNALIGNED 2447 val = *((Elf32_Word *) ((char *) data->d_buf + cnt)); 2448#else 2449 memcpy (&val, (char *) data->d_buf + cnt, elsize); 2450#endif 2451 2452 if (val > shnum) 2453 ERROR (gettext ("\ 2454section [%2d] '%s': section index %Zu out of range\n"), 2455 idx, section_name (ebl, idx), cnt / elsize); 2456 else 2457 { 2458 GElf_Shdr refshdr_mem; 2459 GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val), 2460 &refshdr_mem); 2461 if (refshdr == NULL) 2462 ERROR (gettext ("\ 2463section [%2d] '%s': cannot get section header for element %zu: %s\n"), 2464 idx, section_name (ebl, idx), cnt / elsize, 2465 elf_errmsg (-1)); 2466 else 2467 { 2468 if (refshdr->sh_type == SHT_GROUP) 2469 ERROR (gettext ("\ 2470section [%2d] '%s': section group contains another group [%2d] '%s'\n"), 2471 idx, section_name (ebl, idx), 2472 val, section_name (ebl, val)); 2473 2474 if ((refshdr->sh_flags & SHF_GROUP) == 0) 2475 ERROR (gettext ("\ 2476section [%2d] '%s': element %Zu references section [%2d] '%s' without SHF_GROUP flag set\n"), 2477 idx, section_name (ebl, idx), cnt / elsize, 2478 val, section_name (ebl, val)); 2479 } 2480 2481 if (++scnref[val] == 2) 2482 ERROR (gettext ("\ 2483section [%2d] '%s' is contained in more than one section group\n"), 2484 val, section_name (ebl, val)); 2485 } 2486 } 2487 } 2488} 2489 2490 2491static const char * 2492section_flags_string (GElf_Word flags, char *buf, size_t len) 2493{ 2494 if (flags == 0) 2495 return "none"; 2496 2497 static const struct 2498 { 2499 GElf_Word flag; 2500 const char *name; 2501 } known_flags[] = 2502 { 2503#define NEWFLAG(name) { SHF_##name, #name } 2504 NEWFLAG (WRITE), 2505 NEWFLAG (ALLOC), 2506 NEWFLAG (EXECINSTR), 2507 NEWFLAG (MERGE), 2508 NEWFLAG (STRINGS), 2509 NEWFLAG (INFO_LINK), 2510 NEWFLAG (LINK_ORDER), 2511 NEWFLAG (OS_NONCONFORMING), 2512 NEWFLAG (GROUP), 2513 NEWFLAG (TLS) 2514 }; 2515#undef NEWFLAG 2516 const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]); 2517 2518 char *cp = buf; 2519 2520 for (size_t cnt = 0; cnt < nknown_flags; ++cnt) 2521 if (flags & known_flags[cnt].flag) 2522 { 2523 if (cp != buf && len > 1) 2524 { 2525 *cp++ = '|'; 2526 --len; 2527 } 2528 2529 size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name)); 2530 cp = mempcpy (cp, known_flags[cnt].name, ncopy); 2531 len -= ncopy; 2532 2533 flags ^= known_flags[cnt].flag; 2534 } 2535 2536 if (flags != 0 || cp == buf) 2537 snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags); 2538 2539 *cp = '\0'; 2540 2541 return buf; 2542} 2543 2544 2545static int 2546has_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx) 2547{ 2548 /* First find the relocation section for the symbol table. */ 2549 Elf_Scn *scn = NULL; 2550 GElf_Shdr shdr_mem; 2551 GElf_Shdr *shdr = NULL; 2552 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2553 { 2554 shdr = gelf_getshdr (scn, &shdr_mem); 2555 if (shdr != NULL 2556 && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) 2557 && shdr->sh_link == symscnndx) 2558 /* Found the section. */ 2559 break; 2560 } 2561 2562 if (scn == NULL) 2563 return 0; 2564 2565 Elf_Data *data = elf_getdata (scn, NULL); 2566 if (data == NULL) 2567 return 0; 2568 2569 if (shdr->sh_type == SHT_REL) 2570 for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 2571 { 2572 GElf_Rel rel_mem; 2573 GElf_Rel *rel = gelf_getrel (data, i, &rel_mem); 2574 if (rel == NULL) 2575 continue; 2576 2577 if (GELF_R_SYM (rel->r_info) == symndx 2578 && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) 2579 return 1; 2580 } 2581 else 2582 for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i) 2583 { 2584 GElf_Rela rela_mem; 2585 GElf_Rela *rela = gelf_getrela (data, i, &rela_mem); 2586 if (rela == NULL) 2587 continue; 2588 2589 if (GELF_R_SYM (rela->r_info) == symndx 2590 && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) 2591 return 1; 2592 } 2593 2594 return 0; 2595} 2596 2597 2598static int 2599in_nobits_scn (Ebl *ebl, unsigned int shndx) 2600{ 2601 GElf_Shdr shdr_mem; 2602 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem); 2603 return shdr != NULL && shdr->sh_type == SHT_NOBITS; 2604} 2605 2606 2607static struct version_namelist 2608{ 2609 const char *objname; 2610 const char *name; 2611 GElf_Versym ndx; 2612 enum { ver_def, ver_need } type; 2613 struct version_namelist *next; 2614} *version_namelist; 2615 2616 2617static int 2618add_version (const char *objname, const char *name, GElf_Versym ndx, int type) 2619{ 2620 /* Check that there are no duplications. */ 2621 struct version_namelist *nlp = version_namelist; 2622 while (nlp != NULL) 2623 { 2624 if (((nlp->objname == NULL && objname == NULL) 2625 || (nlp->objname != NULL && objname != NULL 2626 && strcmp (nlp->objname, objname) == 0)) 2627 && strcmp (nlp->name, name) == 0) 2628 return nlp->type == ver_def ? 1 : -1; 2629 nlp = nlp->next; 2630 } 2631 2632 nlp = xmalloc (sizeof (*nlp)); 2633 nlp->objname = objname; 2634 nlp->name = name; 2635 nlp->ndx = ndx; 2636 nlp->type = type; 2637 nlp->next = version_namelist; 2638 version_namelist = nlp; 2639 2640 return 0; 2641} 2642 2643 2644static void 2645check_versym (Ebl *ebl, int idx) 2646{ 2647 Elf_Scn *scn = elf_getscn (ebl->elf, idx); 2648 GElf_Shdr shdr_mem; 2649 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2650 if (shdr == NULL) 2651 /* The error has already been reported. */ 2652 return; 2653 2654 Elf_Data *data = elf_getdata (scn, NULL); 2655 if (data == NULL) 2656 { 2657 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2658 idx, section_name (ebl, idx)); 2659 return; 2660 } 2661 2662 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 2663 GElf_Shdr symshdr_mem; 2664 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 2665 if (symshdr == NULL) 2666 /* The error has already been reported. */ 2667 return; 2668 2669 if (symshdr->sh_type != SHT_DYNSYM) 2670 { 2671 ERROR (gettext ("\ 2672section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"), 2673 idx, section_name (ebl, idx), 2674 shdr->sh_link, section_name (ebl, shdr->sh_link)); 2675 return; 2676 } 2677 2678 /* The number of elements in the version symbol table must be the 2679 same as the number of symbols. */ 2680 if (shdr->sh_size / shdr->sh_entsize 2681 != symshdr->sh_size / symshdr->sh_entsize) 2682 ERROR (gettext ("\ 2683section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"), 2684 idx, section_name (ebl, idx), 2685 shdr->sh_link, section_name (ebl, shdr->sh_link)); 2686 2687 Elf_Data *symdata = elf_getdata (symscn, NULL); 2688 if (symdata == NULL) 2689 /* The error has already been reported. */ 2690 return; 2691 2692 for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 2693 { 2694 GElf_Versym versym_mem; 2695 GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem); 2696 if (versym == NULL) 2697 { 2698 ERROR (gettext ("\ 2699section [%2d] '%s': symbol %d: cannot read version data\n"), 2700 idx, section_name (ebl, idx), cnt); 2701 break; 2702 } 2703 2704 GElf_Sym sym_mem; 2705 GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem); 2706 if (sym == NULL) 2707 /* Already reported elsewhere. */ 2708 continue; 2709 2710 if (*versym == VER_NDX_GLOBAL) 2711 { 2712 /* Global symbol. Make sure it is not defined as local. */ 2713 if (GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2714 ERROR (gettext ("\ 2715section [%2d] '%s': symbol %d: local symbol with global scope\n"), 2716 idx, section_name (ebl, idx), cnt); 2717 } 2718 else if (*versym != VER_NDX_LOCAL) 2719 { 2720 /* Versioned symbol. Make sure it is not defined as local. */ 2721 if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL) 2722 ERROR (gettext ("\ 2723section [%2d] '%s': symbol %d: local symbol with version\n"), 2724 idx, section_name (ebl, idx), cnt); 2725 2726 /* Look through the list of defined versions and locate the 2727 index we need for this symbol. */ 2728 struct version_namelist *runp = version_namelist; 2729 while (runp != NULL) 2730 if (runp->ndx == (*versym & (GElf_Versym) 0x7fff)) 2731 break; 2732 else 2733 runp = runp->next; 2734 2735 if (runp == NULL) 2736 ERROR (gettext ("\ 2737section [%2d] '%s': symbol %d: invalid version index %d\n"), 2738 idx, section_name (ebl, idx), cnt, (int) *versym); 2739 else if (sym->st_shndx == SHN_UNDEF 2740 && runp->type == ver_def) 2741 ERROR (gettext ("\ 2742section [%2d] '%s': symbol %d: version index %d is for defined version\n"), 2743 idx, section_name (ebl, idx), cnt, (int) *versym); 2744 else if (sym->st_shndx != SHN_UNDEF 2745 && runp->type == ver_need) 2746 { 2747 /* Unless this symbol has a copy relocation associated 2748 this must not happen. */ 2749 if (!has_copy_reloc (ebl, shdr->sh_link, cnt) 2750 && !in_nobits_scn (ebl, sym->st_shndx)) 2751 ERROR (gettext ("\ 2752section [%2d] '%s': symbol %d: version index %d is for requested version\n"), 2753 idx, section_name (ebl, idx), cnt, (int) *versym); 2754 } 2755 } 2756 } 2757} 2758 2759 2760static int 2761unknown_dependency_p (Elf *elf, GElf_Ehdr *ehdr, const char *fname) 2762{ 2763 GElf_Phdr phdr_mem; 2764 GElf_Phdr *phdr = NULL; 2765 2766 int i; 2767 for (i = 0; i < ehdr->e_phnum; ++i) 2768 if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL 2769 && phdr->p_type == PT_DYNAMIC) 2770 break; 2771 2772 if (i == ehdr->e_phnum) 2773 return 1; 2774 assert (phdr != NULL); 2775 Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); 2776 GElf_Shdr shdr_mem; 2777 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2778 Elf_Data *data = elf_getdata (scn, NULL); 2779 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL) 2780 for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) 2781 { 2782 GElf_Dyn dyn_mem; 2783 GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); 2784 if (dyn != NULL && dyn->d_tag == DT_NEEDED) 2785 { 2786 const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val); 2787 if (str != NULL && strcmp (str, fname) == 0) 2788 /* Found it. */ 2789 return 0; 2790 } 2791 } 2792 2793 return 1; 2794} 2795 2796 2797static unsigned int nverneed; 2798 2799static void 2800check_verneed (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 2801{ 2802 if (++nverneed == 2) 2803 ERROR (gettext ("more than one version reference section present\n")); 2804 2805 GElf_Shdr strshdr_mem; 2806 GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2807 &strshdr_mem); 2808 if (strshdr == NULL) 2809 return; 2810 if (strshdr->sh_type != SHT_STRTAB) 2811 ERROR (gettext ("\ 2812section [%2d] '%s': sh_link does not link to string table\n"), 2813 idx, section_name (ebl, idx)); 2814 2815 Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2816 if (data == NULL) 2817 { 2818 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2819 idx, section_name (ebl, idx)); 2820 return; 2821 } 2822 unsigned int offset = 0; 2823 for (int cnt = shdr->sh_info; --cnt >= 0; ) 2824 { 2825 /* Get the data at the next offset. */ 2826 GElf_Verneed needmem; 2827 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 2828 if (need == NULL) 2829 break; 2830 2831 unsigned int auxoffset = offset + need->vn_aux; 2832 2833 if (need->vn_version != EV_CURRENT) 2834 ERROR (gettext ("\ 2835section [%2d] '%s': entry %d has wrong version %d\n"), 2836 idx, section_name (ebl, idx), cnt, (int) need->vn_version); 2837 2838 if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED, 2839 1, EV_CURRENT)) 2840 ERROR (gettext ("\ 2841section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 2842 idx, section_name (ebl, idx), cnt); 2843 2844 const char *libname = elf_strptr (ebl->elf, shdr->sh_link, 2845 need->vn_file); 2846 if (libname == NULL) 2847 { 2848 ERROR (gettext ("\ 2849section [%2d] '%s': entry %d has invalid file reference\n"), 2850 idx, section_name (ebl, idx), cnt); 2851 goto next_need; 2852 } 2853 2854 /* Check that there is a DT_NEEDED entry for the referenced library. */ 2855 if (unknown_dependency_p (ebl->elf, ehdr, libname)) 2856 ERROR (gettext ("\ 2857section [%2d] '%s': entry %d references unknown dependency\n"), 2858 idx, section_name (ebl, idx), cnt); 2859 2860 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2861 { 2862 GElf_Vernaux auxmem; 2863 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 2864 if (aux == NULL) 2865 break; 2866 2867 if ((aux->vna_flags & ~VER_FLG_WEAK) != 0) 2868 ERROR (gettext ("\ 2869section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"), 2870 idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2871 2872 const char *verstr = elf_strptr (ebl->elf, shdr->sh_link, 2873 aux->vna_name); 2874 if (verstr == NULL) 2875 ERROR (gettext ("\ 2876section [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"), 2877 idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2878 else 2879 { 2880 GElf_Word hashval = elf_hash (verstr); 2881 if (hashval != aux->vna_hash) 2882 ERROR (gettext ("\ 2883section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"), 2884 idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2885 cnt, (int) hashval, (int) aux->vna_hash); 2886 2887 int res = add_version (libname, verstr, aux->vna_other, 2888 ver_need); 2889 if (unlikely (res !=0)) 2890 { 2891 assert (res > 0); 2892 ERROR (gettext ("\ 2893section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"), 2894 idx, section_name (ebl, idx), need->vn_cnt - cnt2, 2895 cnt, verstr); 2896 } 2897 } 2898 2899 if ((aux->vna_next != 0 || cnt2 > 0) 2900 && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, 2901 EV_CURRENT)) 2902 { 2903 ERROR (gettext ("\ 2904section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"), 2905 idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt); 2906 break; 2907 } 2908 2909 auxoffset += MAX (aux->vna_next, 2910 gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT)); 2911 } 2912 2913 /* Find the next offset. */ 2914 next_need: 2915 offset += need->vn_next; 2916 2917 if ((need->vn_next != 0 || cnt > 0) 2918 && offset < auxoffset) 2919 ERROR (gettext ("\ 2920section [%2d] '%s': entry %d has invalid offset to next entry\n"), 2921 idx, section_name (ebl, idx), cnt); 2922 } 2923} 2924 2925 2926static unsigned int nverdef; 2927 2928static void 2929check_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx) 2930{ 2931 if (++nverdef == 2) 2932 ERROR (gettext ("more than one version definition section present\n")); 2933 2934 GElf_Shdr strshdr_mem; 2935 GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2936 &strshdr_mem); 2937 if (strshdr == NULL) 2938 return; 2939 if (strshdr->sh_type != SHT_STRTAB) 2940 ERROR (gettext ("\ 2941section [%2d] '%s': sh_link does not link to string table\n"), 2942 idx, section_name (ebl, idx)); 2943 2944 Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 2945 if (data == NULL) 2946 { 2947 no_data: 2948 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 2949 idx, section_name (ebl, idx)); 2950 return; 2951 } 2952 2953 /* Iterate over all version definition entries. We check that there 2954 is a BASE entry and that each index is unique. To do the later 2955 we collection the information in a list which is later 2956 examined. */ 2957 struct namelist 2958 { 2959 const char *name; 2960 struct namelist *next; 2961 } *namelist = NULL; 2962 struct namelist *refnamelist = NULL; 2963 2964 bool has_base = false; 2965 unsigned int offset = 0; 2966 for (int cnt = shdr->sh_info; --cnt >= 0; ) 2967 { 2968 /* Get the data at the next offset. */ 2969 GElf_Verdef defmem; 2970 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 2971 if (def == NULL) 2972 goto no_data; 2973 2974 if ((def->vd_flags & VER_FLG_BASE) != 0) 2975 { 2976 if (has_base) 2977 ERROR (gettext ("\ 2978section [%2d] '%s': more than one BASE definition\n"), 2979 idx, section_name (ebl, idx)); 2980 if (def->vd_ndx != VER_NDX_GLOBAL) 2981 ERROR (gettext ("\ 2982section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"), 2983 idx, section_name (ebl, idx)); 2984 has_base = true; 2985 } 2986 if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0) 2987 ERROR (gettext ("\ 2988section [%2d] '%s': entry %d has unknown flag\n"), 2989 idx, section_name (ebl, idx), cnt); 2990 2991 if (def->vd_version != EV_CURRENT) 2992 ERROR (gettext ("\ 2993section [%2d] '%s': entry %d has wrong version %d\n"), 2994 idx, section_name (ebl, idx), cnt, (int) def->vd_version); 2995 2996 if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF, 2997 1, EV_CURRENT)) 2998 ERROR (gettext ("\ 2999section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"), 3000 idx, section_name (ebl, idx), cnt); 3001 3002 unsigned int auxoffset = offset + def->vd_aux; 3003 GElf_Verdaux auxmem; 3004 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 3005 if (aux == NULL) 3006 goto no_data; 3007 3008 const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 3009 if (name == NULL) 3010 { 3011 ERROR (gettext ("\ 3012section [%2d] '%s': entry %d has invalid name reference\n"), 3013 idx, section_name (ebl, idx), cnt); 3014 goto next_def; 3015 } 3016 GElf_Word hashval = elf_hash (name); 3017 if (def->vd_hash != hashval) 3018 ERROR (gettext ("\ 3019section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"), 3020 idx, section_name (ebl, idx), cnt, (int) hashval, 3021 (int) def->vd_hash); 3022 3023 int res = add_version (NULL, name, def->vd_ndx, ver_def); 3024 if (unlikely (res !=0)) 3025 { 3026 assert (res > 0); 3027 ERROR (gettext ("\ 3028section [%2d] '%s': entry %d has duplicate version name '%s'\n"), 3029 idx, section_name (ebl, idx), cnt, name); 3030 } 3031 3032 struct namelist *newname = alloca (sizeof (*newname)); 3033 newname->name = name; 3034 newname->next = namelist; 3035 namelist = newname; 3036 3037 auxoffset += aux->vda_next; 3038 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 3039 { 3040 aux = gelf_getverdaux (data, auxoffset, &auxmem); 3041 if (aux == NULL) 3042 goto no_data; 3043 3044 name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name); 3045 if (name == NULL) 3046 ERROR (gettext ("\ 3047section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"), 3048 idx, section_name (ebl, idx), cnt); 3049 else 3050 { 3051 newname = alloca (sizeof (*newname)); 3052 newname->name = name; 3053 newname->next = refnamelist; 3054 refnamelist = newname; 3055 } 3056 3057 if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt) 3058 && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, 3059 EV_CURRENT)) 3060 { 3061 ERROR (gettext ("\ 3062section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"), 3063 idx, section_name (ebl, idx), cnt); 3064 break; 3065 } 3066 3067 auxoffset += MAX (aux->vda_next, 3068 gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT)); 3069 } 3070 3071 /* Find the next offset. */ 3072 next_def: 3073 offset += def->vd_next; 3074 3075 if ((def->vd_next != 0 || cnt > 0) 3076 && offset < auxoffset) 3077 ERROR (gettext ("\ 3078section [%2d] '%s': entry %d has invalid offset to next entry\n"), 3079 idx, section_name (ebl, idx), cnt); 3080 } 3081 3082 if (!has_base) 3083 ERROR (gettext ("section [%2d] '%s': no BASE definition\n"), 3084 idx, section_name (ebl, idx)); 3085 3086 /* Check whether the referenced names are available. */ 3087 while (namelist != NULL) 3088 { 3089 struct version_namelist *runp = version_namelist; 3090 while (runp != NULL) 3091 { 3092 if (runp->type == ver_def 3093 && strcmp (runp->name, namelist->name) == 0) 3094 break; 3095 runp = runp->next; 3096 } 3097 3098 if (runp == NULL) 3099 ERROR (gettext ("\ 3100section [%2d] '%s': unknown parent version '%s'\n"), 3101 idx, section_name (ebl, idx), namelist->name); 3102 3103 namelist = namelist->next; 3104 } 3105} 3106 3107static void 3108check_attributes (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 3109{ 3110 if (shdr->sh_size == 0) 3111 { 3112 ERROR (gettext ("section [%2d] '%s': empty object attributes section\n"), 3113 idx, section_name (ebl, idx)); 3114 return; 3115 } 3116 3117 Elf_Data *data = elf_rawdata (elf_getscn (ebl->elf, idx), NULL); 3118 if (data == NULL || data->d_size == 0) 3119 { 3120 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 3121 idx, section_name (ebl, idx)); 3122 return; 3123 } 3124 3125 inline size_t pos (const unsigned char *p) 3126 { 3127 return p - (const unsigned char *) data->d_buf; 3128 } 3129 3130 const unsigned char *p = data->d_buf; 3131 if (*p++ != 'A') 3132 { 3133 ERROR (gettext ("section [%2d] '%s': unrecognized attribute format\n"), 3134 idx, section_name (ebl, idx)); 3135 return; 3136 } 3137 3138 inline size_t left (void) 3139 { 3140 return (const unsigned char *) data->d_buf + data->d_size - p; 3141 } 3142 3143 while (left () >= 4) 3144 { 3145 uint32_t len; 3146 memcpy (&len, p, sizeof len); 3147 3148 if (len == 0) 3149 ERROR (gettext ("\ 3150section [%2d] '%s': offset %zu: zero length field in attribute section\n"), 3151 idx, section_name (ebl, idx), pos (p)); 3152 3153 if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 3154 CONVERT (len); 3155 3156 if (len > left ()) 3157 { 3158 ERROR (gettext ("\ 3159section [%2d] '%s': offset %zu: invalid length in attribute section\n"), 3160 idx, section_name (ebl, idx), pos (p)); 3161 break; 3162 } 3163 3164 const unsigned char *name = p + sizeof len; 3165 p += len; 3166 3167 unsigned const char *q = memchr (name, '\0', len); 3168 if (q == NULL) 3169 { 3170 ERROR (gettext ("\ 3171section [%2d] '%s': offset %zu: unterminated vendor name string\n"), 3172 idx, section_name (ebl, idx), pos (p)); 3173 continue; 3174 } 3175 ++q; 3176 3177 if (q - name == sizeof "gnu" && !memcmp (name, "gnu", sizeof "gnu")) 3178 while (q < p) 3179 { 3180 unsigned const char *chunk = q; 3181 3182 unsigned int subsection_tag; 3183 get_uleb128 (subsection_tag, q); 3184 3185 if (q >= p) 3186 { 3187 ERROR (gettext ("\ 3188section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"), 3189 idx, section_name (ebl, idx), pos (chunk)); 3190 break; 3191 } 3192 3193 uint32_t subsection_len; 3194 if (p - q < (ptrdiff_t) sizeof subsection_len) 3195 { 3196 ERROR (gettext ("\ 3197section [%2d] '%s': offset %zu: truncated attribute section\n"), 3198 idx, section_name (ebl, idx), pos (q)); 3199 break; 3200 } 3201 3202 memcpy (&subsection_len, q, sizeof subsection_len); 3203 if (subsection_len == 0) 3204 { 3205 ERROR (gettext ("\ 3206section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"), 3207 idx, section_name (ebl, idx), pos (q)); 3208 3209 q += sizeof subsection_len; 3210 continue; 3211 } 3212 3213 if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 3214 CONVERT (subsection_len); 3215 3216 if (p - chunk < (ptrdiff_t) subsection_len) 3217 { 3218 ERROR (gettext ("\ 3219section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"), 3220 idx, section_name (ebl, idx), pos (q)); 3221 break; 3222 } 3223 3224 const unsigned char *subsection_end = chunk + subsection_len; 3225 chunk = q; 3226 q = subsection_end; 3227 3228 if (subsection_tag != 1) /* Tag_File */ 3229 ERROR (gettext ("\ 3230section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"), 3231 idx, section_name (ebl, idx), pos (chunk), subsection_tag); 3232 else 3233 { 3234 chunk += sizeof subsection_len; 3235 while (chunk < q) 3236 { 3237 unsigned int tag; 3238 get_uleb128 (tag, chunk); 3239 3240 uint64_t value = 0; 3241 const unsigned char *r = chunk; 3242 if (tag == 32 || (tag & 1) == 0) 3243 { 3244 get_uleb128 (value, r); 3245 if (r > q) 3246 { 3247 ERROR (gettext ("\ 3248section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"), 3249 idx, section_name (ebl, idx), pos (chunk)); 3250 break; 3251 } 3252 } 3253 if (tag == 32 || (tag & 1) != 0) 3254 { 3255 r = memchr (r, '\0', q - r); 3256 if (r == NULL) 3257 { 3258 ERROR (gettext ("\ 3259section [%2d] '%s': offset %zu: unterminated string in attribute\n"), 3260 idx, section_name (ebl, idx), pos (chunk)); 3261 break; 3262 } 3263 ++r; 3264 } 3265 3266 const char *tag_name = NULL; 3267 const char *value_name = NULL; 3268 if (!ebl_check_object_attribute (ebl, (const char *) name, 3269 tag, value, 3270 &tag_name, &value_name)) 3271 ERROR (gettext ("\ 3272section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"), 3273 idx, section_name (ebl, idx), pos (chunk), tag); 3274 else if ((tag & 1) == 0 && value_name == NULL) 3275 ERROR (gettext ("\ 3276section [%2d] '%s': offset %zu: unrecognized %s attribute value %" PRIu64 "\n"), 3277 idx, section_name (ebl, idx), pos (chunk), 3278 tag_name, value); 3279 3280 chunk = r; 3281 } 3282 } 3283 } 3284 else 3285 ERROR (gettext ("\ 3286section [%2d] '%s': offset %zu: vendor '%s' unknown\n"), 3287 idx, section_name (ebl, idx), pos (p), name); 3288 } 3289 3290 if (left () != 0) 3291 ERROR (gettext ("\ 3292section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"), 3293 idx, section_name (ebl, idx), pos (p)); 3294} 3295 3296static bool has_loadable_segment; 3297static bool has_interp_segment; 3298 3299static const struct 3300{ 3301 const char *name; 3302 size_t namelen; 3303 GElf_Word type; 3304 enum { unused, exact, atleast, exact_or_gnuld } attrflag; 3305 GElf_Word attr; 3306 GElf_Word attr2; 3307} special_sections[] = 3308 { 3309 /* See figure 4-14 in the gABI. */ 3310 { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3311 { ".comment", 8, SHT_PROGBITS, exact, 0, 0 }, 3312 { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3313 { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3314 { ".debug_str", 11, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 }, 3315 { ".debug", 6, SHT_PROGBITS, exact, 0, 0 }, 3316 { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE }, 3317 { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 }, 3318 { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 }, 3319 { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3320 { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3321 { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info? 3322 { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 }, 3323 { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3324 { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3325 { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests? 3326 { ".line", 6, SHT_PROGBITS, exact, 0, 0 }, 3327 { ".note", 6, SHT_NOTE, atleast, 0, SHF_ALLOC }, 3328 { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests 3329 { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 }, 3330 { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC }, // XXX more tests 3331 { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC }, // XXX more tests 3332 { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 3333 { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS }, 3334 { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 }, 3335 { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 3336 { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests 3337 { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests 3338 { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3339 { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3340 { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 }, 3341 { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 }, 3342 3343 /* The following are GNU extensions. */ 3344 { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 }, 3345 { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 }, 3346 { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 }, 3347 { ".gnu.attributes", 16, SHT_GNU_ATTRIBUTES, exact, 0, 0 }, 3348 }; 3349#define nspecial_sections \ 3350 (sizeof (special_sections) / sizeof (special_sections[0])) 3351 3352#define IS_KNOWN_SPECIAL(idx, string, prefix) \ 3353 (special_sections[idx].namelen == sizeof string - (prefix ? 1 : 0) \ 3354 && !memcmp (special_sections[idx].name, string, \ 3355 sizeof string - (prefix ? 1 : 0))) 3356 3357static void 3358check_sections (Ebl *ebl, GElf_Ehdr *ehdr) 3359{ 3360 if (ehdr->e_shoff == 0) 3361 /* No section header. */ 3362 return; 3363 3364 /* Allocate array to count references in section groups. */ 3365 scnref = (int *) xcalloc (shnum, sizeof (int)); 3366 3367 /* Check the zeroth section first. It must not have any contents 3368 and the section header must contain nonzero value at most in the 3369 sh_size and sh_link fields. */ 3370 GElf_Shdr shdr_mem; 3371 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 3372 if (shdr == NULL) 3373 ERROR (gettext ("cannot get section header of zeroth section\n")); 3374 else 3375 { 3376 if (shdr->sh_name != 0) 3377 ERROR (gettext ("zeroth section has nonzero name\n")); 3378 if (shdr->sh_type != 0) 3379 ERROR (gettext ("zeroth section has nonzero type\n")); 3380 if (shdr->sh_flags != 0) 3381 ERROR (gettext ("zeroth section has nonzero flags\n")); 3382 if (shdr->sh_addr != 0) 3383 ERROR (gettext ("zeroth section has nonzero address\n")); 3384 if (shdr->sh_offset != 0) 3385 ERROR (gettext ("zeroth section has nonzero offset\n")); 3386 if (shdr->sh_info != 0) 3387 ERROR (gettext ("zeroth section has nonzero info field\n")); 3388 if (shdr->sh_addralign != 0) 3389 ERROR (gettext ("zeroth section has nonzero align value\n")); 3390 if (shdr->sh_entsize != 0) 3391 ERROR (gettext ("zeroth section has nonzero entry size value\n")); 3392 3393 if (shdr->sh_size != 0 && ehdr->e_shnum != 0) 3394 ERROR (gettext ("\ 3395zeroth section has nonzero size value while ELF header has nonzero shnum value\n")); 3396 3397 if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX) 3398 ERROR (gettext ("\ 3399zeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n")); 3400 } 3401 3402 int *segment_flags = xcalloc (ehdr->e_phnum, sizeof segment_flags[0]); 3403 3404 bool dot_interp_section = false; 3405 3406 size_t hash_idx = 0; 3407 size_t gnu_hash_idx = 0; 3408 3409 size_t versym_scnndx = 0; 3410 for (size_t cnt = 1; cnt < shnum; ++cnt) 3411 { 3412 shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem); 3413 if (shdr == NULL) 3414 { 3415 ERROR (gettext ("\ 3416cannot get section header for section [%2zu] '%s': %s\n"), 3417 cnt, section_name (ebl, cnt), elf_errmsg (-1)); 3418 continue; 3419 } 3420 3421 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 3422 3423 if (scnname == NULL) 3424 ERROR (gettext ("section [%2zu]: invalid name\n"), cnt); 3425 else 3426 { 3427 /* Check whether it is one of the special sections defined in 3428 the gABI. */ 3429 size_t s; 3430 for (s = 0; s < nspecial_sections; ++s) 3431 if (strncmp (scnname, special_sections[s].name, 3432 special_sections[s].namelen) == 0) 3433 { 3434 char stbuf1[100]; 3435 char stbuf2[100]; 3436 char stbuf3[100]; 3437 3438 GElf_Word good_type = special_sections[s].type; 3439 if (IS_KNOWN_SPECIAL (s, ".plt", false) 3440 && ebl_bss_plt_p (ebl, ehdr)) 3441 good_type = SHT_NOBITS; 3442 3443 /* In a debuginfo file, any normal section can be SHT_NOBITS. 3444 This is only invalid for DWARF sections and .shstrtab. */ 3445 if (shdr->sh_type != good_type 3446 && (shdr->sh_type != SHT_NOBITS 3447 || !is_debuginfo 3448 || IS_KNOWN_SPECIAL (s, ".debug_str", false) 3449 || IS_KNOWN_SPECIAL (s, ".debug", true) 3450 || IS_KNOWN_SPECIAL (s, ".shstrtab", false))) 3451 ERROR (gettext ("\ 3452section [%2d] '%s' has wrong type: expected %s, is %s\n"), 3453 (int) cnt, scnname, 3454 ebl_section_type_name (ebl, special_sections[s].type, 3455 stbuf1, sizeof (stbuf1)), 3456 ebl_section_type_name (ebl, shdr->sh_type, 3457 stbuf2, sizeof (stbuf2))); 3458 3459 if (special_sections[s].attrflag == exact 3460 || special_sections[s].attrflag == exact_or_gnuld) 3461 { 3462 /* Except for the link order and group bit all the 3463 other bits should match exactly. */ 3464 if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP)) 3465 != special_sections[s].attr 3466 && (special_sections[s].attrflag == exact || !gnuld)) 3467 ERROR (gettext ("\ 3468section [%2zu] '%s' has wrong flags: expected %s, is %s\n"), 3469 cnt, scnname, 3470 section_flags_string (special_sections[s].attr, 3471 stbuf1, sizeof (stbuf1)), 3472 section_flags_string (shdr->sh_flags 3473 & ~SHF_LINK_ORDER, 3474 stbuf2, sizeof (stbuf2))); 3475 } 3476 else if (special_sections[s].attrflag == atleast) 3477 { 3478 if ((shdr->sh_flags & special_sections[s].attr) 3479 != special_sections[s].attr 3480 || ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP 3481 | special_sections[s].attr 3482 | special_sections[s].attr2)) 3483 != 0)) 3484 ERROR (gettext ("\ 3485section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"), 3486 cnt, scnname, 3487 section_flags_string (special_sections[s].attr, 3488 stbuf1, sizeof (stbuf1)), 3489 section_flags_string (special_sections[s].attr2, 3490 stbuf2, sizeof (stbuf2)), 3491 section_flags_string (shdr->sh_flags 3492 & ~(SHF_LINK_ORDER 3493 | SHF_GROUP), 3494 stbuf3, sizeof (stbuf3))); 3495 } 3496 3497 if (strcmp (scnname, ".interp") == 0) 3498 { 3499 dot_interp_section = true; 3500 3501 if (ehdr->e_type == ET_REL) 3502 ERROR (gettext ("\ 3503section [%2zu] '%s' present in object file\n"), 3504 cnt, scnname); 3505 3506 if ((shdr->sh_flags & SHF_ALLOC) != 0 3507 && !has_loadable_segment) 3508 ERROR (gettext ("\ 3509section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 3510 cnt, scnname); 3511 else if ((shdr->sh_flags & SHF_ALLOC) == 0 3512 && has_loadable_segment) 3513 ERROR (gettext ("\ 3514section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 3515 cnt, scnname); 3516 } 3517 else 3518 { 3519 if (strcmp (scnname, ".symtab_shndx") == 0 3520 && ehdr->e_type != ET_REL) 3521 ERROR (gettext ("\ 3522section [%2zu] '%s' is extension section index table in non-object file\n"), 3523 cnt, scnname); 3524 3525 /* These sections must have the SHF_ALLOC flag set iff 3526 a loadable segment is available. 3527 3528 .relxxx 3529 .strtab 3530 .symtab 3531 .symtab_shndx 3532 3533 Check that if there is a reference from the 3534 loaded section these sections also have the 3535 ALLOC flag set. */ 3536#if 0 3537 // XXX TODO 3538 if ((shdr->sh_flags & SHF_ALLOC) != 0 3539 && !has_loadable_segment) 3540 ERROR (gettext ("\ 3541section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"), 3542 cnt, scnname); 3543 else if ((shdr->sh_flags & SHF_ALLOC) == 0 3544 && has_loadable_segment) 3545 ERROR (gettext ("\ 3546section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"), 3547 cnt, scnname); 3548#endif 3549 } 3550 3551 break; 3552 } 3553 } 3554 3555 if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize) 3556 ERROR (gettext ("\ 3557section [%2zu] '%s': size not multiple of entry size\n"), 3558 cnt, section_name (ebl, cnt)); 3559 3560 if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL) 3561 ERROR (gettext ("cannot get section header\n")); 3562 3563 if (shdr->sh_type >= SHT_NUM 3564 && shdr->sh_type != SHT_GNU_ATTRIBUTES 3565 && shdr->sh_type != SHT_GNU_LIBLIST 3566 && shdr->sh_type != SHT_CHECKSUM 3567 && shdr->sh_type != SHT_GNU_verdef 3568 && shdr->sh_type != SHT_GNU_verneed 3569 && shdr->sh_type != SHT_GNU_versym 3570 && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL) 3571 ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"), 3572 cnt, section_name (ebl, cnt), 3573 (int) shdr->sh_type); 3574 3575#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ 3576 | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ 3577 | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) 3578 if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS) 3579 { 3580 GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS; 3581 if (sh_flags & SHF_MASKPROC) 3582 { 3583 if (!ebl_machine_section_flag_check (ebl, 3584 sh_flags & SHF_MASKPROC)) 3585 ERROR (gettext ("section [%2zu] '%s'" 3586 " contains invalid processor-specific flag(s)" 3587 " %#" PRIx64 "\n"), 3588 cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC); 3589 sh_flags &= ~(GElf_Xword) SHF_MASKPROC; 3590 } 3591 if (sh_flags != 0) 3592 ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" 3593 " %#" PRIx64 "\n"), 3594 cnt, section_name (ebl, cnt), sh_flags); 3595 } 3596 if (shdr->sh_flags & SHF_TLS) 3597 { 3598 // XXX Correct? 3599 if (shdr->sh_addr != 0 && !gnuld) 3600 ERROR (gettext ("\ 3601section [%2zu] '%s': thread-local data sections address not zero\n"), 3602 cnt, section_name (ebl, cnt)); 3603 3604 // XXX TODO more tests!? 3605 } 3606 3607 if (shdr->sh_link >= shnum) 3608 ERROR (gettext ("\ 3609section [%2zu] '%s': invalid section reference in link value\n"), 3610 cnt, section_name (ebl, cnt)); 3611 3612 if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum) 3613 ERROR (gettext ("\ 3614section [%2zu] '%s': invalid section reference in info value\n"), 3615 cnt, section_name (ebl, cnt)); 3616 3617 if ((shdr->sh_flags & SHF_MERGE) == 0 3618 && (shdr->sh_flags & SHF_STRINGS) != 0 3619 && be_strict) 3620 ERROR (gettext ("\ 3621section [%2zu] '%s': strings flag set without merge flag\n"), 3622 cnt, section_name (ebl, cnt)); 3623 3624 if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0) 3625 ERROR (gettext ("\ 3626section [%2zu] '%s': merge flag set but entry size is zero\n"), 3627 cnt, section_name (ebl, cnt)); 3628 3629 if (shdr->sh_flags & SHF_GROUP) 3630 check_scn_group (ebl, cnt); 3631 3632 if (shdr->sh_flags & SHF_EXECINSTR) 3633 { 3634 switch (shdr->sh_type) 3635 { 3636 case SHT_PROGBITS: 3637 break; 3638 3639 case SHT_NOBITS: 3640 if (is_debuginfo) 3641 break; 3642 default: 3643 ERROR (gettext ("\ 3644section [%2zu] '%s' has unexpected type %d for an executable section\n"), 3645 cnt, section_name (ebl, cnt), shdr->sh_type); 3646 break; 3647 } 3648 3649 if ((shdr->sh_flags & SHF_WRITE) 3650 && !ebl_check_special_section (ebl, cnt, shdr, 3651 section_name (ebl, cnt))) 3652 ERROR (gettext ("\ 3653section [%2zu] '%s' is both executable and writable\n"), 3654 cnt, section_name (ebl, cnt)); 3655 } 3656 3657 if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0) 3658 { 3659 /* Make sure the section is contained in a loaded segment 3660 and that the initialization part matches NOBITS sections. */ 3661 int pcnt; 3662 GElf_Phdr phdr_mem; 3663 GElf_Phdr *phdr; 3664 3665 for (pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 3666 if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL 3667 && ((phdr->p_type == PT_LOAD 3668 && (shdr->sh_flags & SHF_TLS) == 0) 3669 || (phdr->p_type == PT_TLS 3670 && (shdr->sh_flags & SHF_TLS) != 0)) 3671 && phdr->p_offset <= shdr->sh_offset 3672 && (phdr->p_offset + phdr->p_filesz > shdr->sh_offset 3673 || (phdr->p_offset + phdr->p_memsz > shdr->sh_offset 3674 && shdr->sh_type == SHT_NOBITS))) 3675 { 3676 /* Found the segment. */ 3677 if (phdr->p_offset + phdr->p_memsz 3678 < shdr->sh_offset + shdr->sh_size) 3679 ERROR (gettext ("\ 3680section [%2zu] '%s' not fully contained in segment of program header entry %d\n"), 3681 cnt, section_name (ebl, cnt), pcnt); 3682 3683 if (shdr->sh_type == SHT_NOBITS) 3684 { 3685 if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz 3686 && !is_debuginfo) 3687 ERROR (gettext ("\ 3688section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"), 3689 cnt, section_name (ebl, cnt), pcnt); 3690 } 3691 else 3692 { 3693 const GElf_Off end = phdr->p_offset + phdr->p_filesz; 3694 if (shdr->sh_offset > end || 3695 (shdr->sh_offset == end && shdr->sh_size != 0)) 3696 ERROR (gettext ("\ 3697section [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"), 3698 cnt, section_name (ebl, cnt), pcnt); 3699 } 3700 3701 if (shdr->sh_type != SHT_NOBITS) 3702 { 3703 if ((shdr->sh_flags & SHF_EXECINSTR) != 0) 3704 { 3705 segment_flags[pcnt] |= PF_X; 3706 if ((phdr->p_flags & PF_X) == 0) 3707 ERROR (gettext ("\ 3708section [%2zu] '%s' is executable in nonexecutable segment %d\n"), 3709 cnt, section_name (ebl, cnt), pcnt); 3710 } 3711 3712 if ((shdr->sh_flags & SHF_WRITE) != 0) 3713 { 3714 segment_flags[pcnt] |= PF_W; 3715 if (0 /* XXX vdso images have this */ 3716 && (phdr->p_flags & PF_W) == 0) 3717 ERROR (gettext ("\ 3718section [%2zu] '%s' is writable in unwritable segment %d\n"), 3719 cnt, section_name (ebl, cnt), pcnt); 3720 } 3721 } 3722 3723 break; 3724 } 3725 3726 if (pcnt == ehdr->e_phnum) 3727 ERROR (gettext ("\ 3728section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"), 3729 cnt, section_name (ebl, cnt)); 3730 } 3731 3732 if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB) 3733 ERROR (gettext ("\ 3734section [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"), 3735 cnt, section_name (ebl, cnt)); 3736 3737 switch (shdr->sh_type) 3738 { 3739 case SHT_DYNSYM: 3740 if (ehdr->e_type == ET_REL) 3741 ERROR (gettext ("\ 3742section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"), 3743 cnt, section_name (ebl, cnt)); 3744 /* FALLTHROUGH */ 3745 case SHT_SYMTAB: 3746 check_symtab (ebl, ehdr, shdr, cnt); 3747 break; 3748 3749 case SHT_RELA: 3750 check_rela (ebl, ehdr, shdr, cnt); 3751 break; 3752 3753 case SHT_REL: 3754 check_rel (ebl, ehdr, shdr, cnt); 3755 break; 3756 3757 case SHT_DYNAMIC: 3758 check_dynamic (ebl, ehdr, shdr, cnt); 3759 break; 3760 3761 case SHT_SYMTAB_SHNDX: 3762 check_symtab_shndx (ebl, ehdr, shdr, cnt); 3763 break; 3764 3765 case SHT_HASH: 3766 check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); 3767 hash_idx = cnt; 3768 break; 3769 3770 case SHT_GNU_HASH: 3771 check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt); 3772 gnu_hash_idx = cnt; 3773 break; 3774 3775 case SHT_NULL: 3776 check_null (ebl, shdr, cnt); 3777 break; 3778 3779 case SHT_GROUP: 3780 check_group (ebl, ehdr, shdr, cnt); 3781 break; 3782 3783 case SHT_NOTE: 3784 check_note_section (ebl, ehdr, shdr, cnt); 3785 break; 3786 3787 case SHT_GNU_versym: 3788 /* We cannot process this section now since we have no guarantee 3789 that the verneed and verdef sections have already been read. 3790 Just remember the section index. */ 3791 if (versym_scnndx != 0) 3792 ERROR (gettext ("more than one version symbol table present\n")); 3793 versym_scnndx = cnt; 3794 break; 3795 3796 case SHT_GNU_verneed: 3797 check_verneed (ebl, ehdr, shdr, cnt); 3798 break; 3799 3800 case SHT_GNU_verdef: 3801 check_verdef (ebl, shdr, cnt); 3802 break; 3803 3804 case SHT_GNU_ATTRIBUTES: 3805 check_attributes (ebl, ehdr, shdr, cnt); 3806 break; 3807 3808 default: 3809 /* Nothing. */ 3810 break; 3811 } 3812 } 3813 3814 if (has_interp_segment && !dot_interp_section) 3815 ERROR (gettext ("INTERP program header entry but no .interp section\n")); 3816 3817 if (!is_debuginfo) 3818 for (int pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt) 3819 { 3820 GElf_Phdr phdr_mem; 3821 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem); 3822 if (phdr != NULL && (phdr->p_type == PT_LOAD || phdr->p_type == PT_TLS)) 3823 { 3824 if ((phdr->p_flags & PF_X) != 0 3825 && (segment_flags[pcnt] & PF_X) == 0) 3826 ERROR (gettext ("\ 3827loadable segment [%u] is executable but contains no executable sections\n"), 3828 pcnt); 3829 3830 if ((phdr->p_flags & PF_W) != 0 3831 && (segment_flags[pcnt] & PF_W) == 0) 3832 ERROR (gettext ("\ 3833loadable segment [%u] is writable but contains no writable sections\n"), 3834 pcnt); 3835 } 3836 } 3837 3838 free (segment_flags); 3839 3840 if (version_namelist != NULL) 3841 { 3842 if (versym_scnndx == 0) 3843 ERROR (gettext ("\ 3844no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n")); 3845 else 3846 check_versym (ebl, versym_scnndx); 3847 3848 /* Check for duplicate index numbers. */ 3849 do 3850 { 3851 struct version_namelist *runp = version_namelist->next; 3852 while (runp != NULL) 3853 { 3854 if (version_namelist->ndx == runp->ndx) 3855 { 3856 ERROR (gettext ("duplicate version index %d\n"), 3857 (int) version_namelist->ndx); 3858 break; 3859 } 3860 runp = runp->next; 3861 } 3862 3863 struct version_namelist *old = version_namelist; 3864 version_namelist = version_namelist->next; 3865 free (old); 3866 } 3867 while (version_namelist != NULL); 3868 } 3869 else if (versym_scnndx != 0) 3870 ERROR (gettext ("\ 3871.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n")); 3872 3873 if (hash_idx != 0 && gnu_hash_idx != 0) 3874 compare_hash_gnu_hash (ebl, ehdr, hash_idx, gnu_hash_idx); 3875 3876 free (scnref); 3877} 3878 3879 3880static GElf_Off 3881check_note_data (Ebl *ebl, const GElf_Ehdr *ehdr, 3882 Elf_Data *data, int shndx, int phndx, GElf_Off start) 3883{ 3884 size_t offset = 0; 3885 size_t last_offset = 0; 3886 GElf_Nhdr nhdr; 3887 size_t name_offset; 3888 size_t desc_offset; 3889 while (offset < data->d_size 3890 && (offset = gelf_getnote (data, offset, 3891 &nhdr, &name_offset, &desc_offset)) > 0) 3892 { 3893 last_offset = offset; 3894 3895 /* Make sure it is one of the note types we know about. */ 3896 if (ehdr->e_type == ET_CORE) 3897 switch (nhdr.n_type) 3898 { 3899 case NT_PRSTATUS: 3900 case NT_FPREGSET: 3901 case NT_PRPSINFO: 3902 case NT_TASKSTRUCT: /* NT_PRXREG on Solaris. */ 3903 case NT_PLATFORM: 3904 case NT_AUXV: 3905 case NT_GWINDOWS: 3906 case NT_ASRS: 3907 case NT_PSTATUS: 3908 case NT_PSINFO: 3909 case NT_PRCRED: 3910 case NT_UTSNAME: 3911 case NT_LWPSTATUS: 3912 case NT_LWPSINFO: 3913 case NT_PRFPXREG: 3914 /* Known type. */ 3915 break; 3916 3917 default: 3918 if (shndx == 0) 3919 ERROR (gettext ("\ 3920phdr[%d]: unknown core file note type %" PRIu32 " at offset %" PRIu64 "\n"), 3921 phndx, (uint32_t) nhdr.n_type, start + offset); 3922 else 3923 ERROR (gettext ("\ 3924section [%2d] '%s': unknown core file note type %" PRIu32 3925 " at offset %Zu\n"), 3926 shndx, section_name (ebl, shndx), 3927 (uint32_t) nhdr.n_type, offset); 3928 } 3929 else 3930 switch (nhdr.n_type) 3931 { 3932 case NT_GNU_ABI_TAG: 3933 case NT_GNU_HWCAP: 3934 case NT_GNU_BUILD_ID: 3935 break; 3936 3937 case 0: 3938 /* Linux vDSOs use a type 0 note for the kernel version word. */ 3939 if (nhdr.n_namesz == sizeof "Linux" 3940 && !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux")) 3941 break; 3942 3943 default: 3944 if (shndx == 0) 3945 ERROR (gettext ("\ 3946phdr[%d]: unknown object file note type %" PRIu32 " at offset %Zu\n"), 3947 phndx, (uint32_t) nhdr.n_type, offset); 3948 else 3949 ERROR (gettext ("\ 3950section [%2d] '%s': unknown object file note type %" PRIu32 3951 " at offset %Zu\n"), 3952 shndx, section_name (ebl, shndx), 3953 (uint32_t) nhdr.n_type, offset); 3954 } 3955 } 3956 3957 return last_offset; 3958} 3959 3960static void 3961check_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt) 3962{ 3963 if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL 3964 && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 3965 ERROR (gettext ("\ 3966phdr[%d]: no note entries defined for the type of file\n"), 3967 cnt); 3968 3969 if (is_debuginfo) 3970 /* The p_offset values in a separate debug file are bogus. */ 3971 return; 3972 3973 if (phdr->p_filesz == 0) 3974 return; 3975 3976 GElf_Off notes_size = 0; 3977 Elf_Data *data = elf_getdata_rawchunk (ebl->elf, 3978 phdr->p_offset, phdr->p_filesz, 3979 ELF_T_NHDR); 3980 if (data != NULL) 3981 notes_size = check_note_data (ebl, ehdr, data, 0, cnt, phdr->p_offset); 3982 3983 if (notes_size == 0) 3984 ERROR (gettext ("phdr[%d]: cannot get content of note section: %s\n"), 3985 cnt, elf_errmsg (-1)); 3986 else if (notes_size != phdr->p_filesz) 3987 ERROR (gettext ("phdr[%d]: extra %" PRIu64 " bytes after last note\n"), 3988 cnt, phdr->p_filesz - notes_size); 3989} 3990 3991static void 3992check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx) 3993{ 3994 if (shdr->sh_size == 0) 3995 return; 3996 3997 Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL); 3998 if (data == NULL) 3999 { 4000 ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), 4001 idx, section_name (ebl, idx)); 4002 return; 4003 } 4004 4005 if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL 4006 && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) 4007 ERROR (gettext ("\ 4008section [%2d] '%s': no note entries defined for the type of file\n"), 4009 idx, section_name (ebl, idx)); 4010 4011 GElf_Off notes_size = check_note_data (ebl, ehdr, data, idx, 0, 0); 4012 4013 if (notes_size == 0) 4014 ERROR (gettext ("section [%2d] '%s': cannot get content of note section\n"), 4015 idx, section_name (ebl, idx)); 4016 else if (notes_size != shdr->sh_size) 4017 ERROR (gettext ("section [%2d] '%s': extra %" PRIu64 4018 " bytes after last note\n"), 4019 idx, section_name (ebl, idx), shdr->sh_size - notes_size); 4020} 4021 4022static void 4023check_program_header (Ebl *ebl, GElf_Ehdr *ehdr) 4024{ 4025 if (ehdr->e_phoff == 0) 4026 return; 4027 4028 if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 4029 && ehdr->e_type != ET_CORE) 4030 ERROR (gettext ("\ 4031only executables, shared objects, and core files can have program headers\n")); 4032 4033 int num_pt_interp = 0; 4034 int num_pt_tls = 0; 4035 int num_pt_relro = 0; 4036 4037 for (int cnt = 0; cnt < ehdr->e_phnum; ++cnt) 4038 { 4039 GElf_Phdr phdr_mem; 4040 GElf_Phdr *phdr; 4041 4042 phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 4043 if (phdr == NULL) 4044 { 4045 ERROR (gettext ("cannot get program header entry %d: %s\n"), 4046 cnt, elf_errmsg (-1)); 4047 continue; 4048 } 4049 4050 if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME 4051 && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO 4052 /* Check for a known machine-specific type. */ 4053 && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL) 4054 ERROR (gettext ("\ 4055program header entry %d: unknown program header entry type %#" PRIx64 "\n"), 4056 cnt, (uint64_t) phdr->p_type); 4057 4058 if (phdr->p_type == PT_LOAD) 4059 has_loadable_segment = true; 4060 else if (phdr->p_type == PT_INTERP) 4061 { 4062 if (++num_pt_interp != 1) 4063 { 4064 if (num_pt_interp == 2) 4065 ERROR (gettext ("\ 4066more than one INTERP entry in program header\n")); 4067 } 4068 has_interp_segment = true; 4069 } 4070 else if (phdr->p_type == PT_TLS) 4071 { 4072 if (++num_pt_tls == 2) 4073 ERROR (gettext ("more than one TLS entry in program header\n")); 4074 } 4075 else if (phdr->p_type == PT_NOTE) 4076 check_note (ebl, ehdr, phdr, cnt); 4077 else if (phdr->p_type == PT_DYNAMIC) 4078 { 4079 if (ehdr->e_type == ET_EXEC && ! has_interp_segment) 4080 ERROR (gettext ("\ 4081static executable cannot have dynamic sections\n")); 4082 else 4083 { 4084 /* Check that the .dynamic section, if it exists, has 4085 the same address. */ 4086 Elf_Scn *scn = NULL; 4087 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 4088 { 4089 GElf_Shdr shdr_mem; 4090 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 4091 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 4092 { 4093 if (phdr->p_offset != shdr->sh_offset) 4094 ERROR (gettext ("\ 4095dynamic section reference in program header has wrong offset\n")); 4096 if (phdr->p_memsz != shdr->sh_size) 4097 ERROR (gettext ("\ 4098dynamic section size mismatch in program and section header\n")); 4099 break; 4100 } 4101 } 4102 } 4103 } 4104 else if (phdr->p_type == PT_GNU_RELRO) 4105 { 4106 if (++num_pt_relro == 2) 4107 ERROR (gettext ("\ 4108more than one GNU_RELRO entry in program header\n")); 4109 else 4110 { 4111 /* Check that the region is in a writable segment. */ 4112 int inner; 4113 for (inner = 0; inner < ehdr->e_phnum; ++inner) 4114 { 4115 GElf_Phdr phdr2_mem; 4116 GElf_Phdr *phdr2; 4117 4118 phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 4119 if (phdr2 == NULL) 4120 continue; 4121 4122 if (phdr2->p_type == PT_LOAD 4123 && phdr->p_vaddr >= phdr2->p_vaddr 4124 && (phdr->p_vaddr + phdr->p_memsz 4125 <= phdr2->p_vaddr + phdr2->p_memsz)) 4126 { 4127 if ((phdr2->p_flags & PF_W) == 0) 4128 ERROR (gettext ("\ 4129loadable segment GNU_RELRO applies to is not writable\n")); 4130 if ((phdr2->p_flags &~ PF_W) != (phdr->p_flags &~ PF_W)) 4131 ERROR (gettext ("\ 4132loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"), 4133 cnt, inner); 4134 break; 4135 } 4136 } 4137 4138 if (inner >= ehdr->e_phnum) 4139 ERROR (gettext ("\ 4140%s segment not contained in a loaded segment\n"), "GNU_RELRO"); 4141 } 4142 } 4143 else if (phdr->p_type == PT_PHDR) 4144 { 4145 /* Check that the region is in a writable segment. */ 4146 int inner; 4147 for (inner = 0; inner < ehdr->e_phnum; ++inner) 4148 { 4149 GElf_Phdr phdr2_mem; 4150 GElf_Phdr *phdr2; 4151 4152 phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem); 4153 if (phdr2 != NULL 4154 && phdr2->p_type == PT_LOAD 4155 && phdr->p_vaddr >= phdr2->p_vaddr 4156 && (phdr->p_vaddr + phdr->p_memsz 4157 <= phdr2->p_vaddr + phdr2->p_memsz)) 4158 break; 4159 } 4160 4161 if (inner >= ehdr->e_phnum) 4162 ERROR (gettext ("\ 4163%s segment not contained in a loaded segment\n"), "PHDR"); 4164 4165 /* Check that offset in segment corresponds to offset in ELF 4166 header. */ 4167 if (phdr->p_offset != ehdr->e_phoff) 4168 ERROR (gettext ("\ 4169program header offset in ELF header and PHDR entry do not match")); 4170 } 4171 4172 if (phdr->p_filesz > phdr->p_memsz 4173 && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE)) 4174 ERROR (gettext ("\ 4175program header entry %d: file size greater than memory size\n"), 4176 cnt); 4177 4178 if (phdr->p_align > 1) 4179 { 4180 if (!powerof2 (phdr->p_align)) 4181 ERROR (gettext ("\ 4182program header entry %d: alignment not a power of 2\n"), cnt); 4183 else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0) 4184 ERROR (gettext ("\ 4185program header entry %d: file offset and virtual address not module of alignment\n"), cnt); 4186 } 4187 } 4188} 4189 4190 4191/* Process one file. */ 4192static void 4193process_elf_file (Elf *elf, const char *prefix, const char *suffix, 4194 const char *fname, size_t size, bool only_one) 4195{ 4196 /* Reset variables. */ 4197 ndynamic = 0; 4198 nverneed = 0; 4199 nverdef = 0; 4200 textrel = false; 4201 needed_textrel = false; 4202 has_loadable_segment = false; 4203 has_interp_segment = false; 4204 4205 GElf_Ehdr ehdr_mem; 4206 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 4207 Ebl *ebl; 4208 4209 /* Print the file name. */ 4210 if (!only_one) 4211 { 4212 if (prefix != NULL) 4213 printf ("\n%s(%s)%s:\n", prefix, fname, suffix); 4214 else 4215 printf ("\n%s:\n", fname); 4216 } 4217 4218 if (ehdr == NULL) 4219 { 4220 ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1)); 4221 return; 4222 } 4223 4224 ebl = ebl_openbackend (elf); 4225 /* If there is no appropriate backend library we cannot test 4226 architecture and OS specific features. Any encountered extension 4227 is an error. */ 4228 4229 /* Go straight by the gABI, check all the parts in turn. */ 4230 check_elf_header (ebl, ehdr, size); 4231 4232 /* Check the program header. */ 4233 check_program_header (ebl, ehdr); 4234 4235 /* Next the section headers. It is OK if there are no section 4236 headers at all. */ 4237 check_sections (ebl, ehdr); 4238 4239 /* Report if no relocation section needed the text relocation flag. */ 4240 if (textrel && !needed_textrel) 4241 ERROR (gettext ("text relocation flag set but not needed\n")); 4242 4243 /* Free the resources. */ 4244 ebl_closebackend (ebl); 4245} 4246 4247 4248#include "debugpred.h" 4249