1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Compare relevant content of two ELF files. 20d528f9ceff2b96c521cefd75fc62d7151e3e6b1Mark Wielaard Copyright (C) 2005-2012, 2014, 2015 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2005. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of the GNU General Public License as published by 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the Free Software Foundation; either version 3 of the License, or 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard (at your option) any later version. 10361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard GNU General Public License for more details. 15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received a copy of the GNU General Public License 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h> 24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <errno.h> 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h> 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 28f9ece8a9ee7c170c867189b6b2dd9f94124734beRoland McGrath#include <locale.h> 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h> 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 36fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper#include <system.h> 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "../libelf/elf-knowledge.h" 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "../libebl/libeblP.h" 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototypes of local functions. */ 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Elf *open_file (const char *fname, int *fdp, Ebl **eblp); 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx); 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int regioncompare (const void *p1, const void *p2); 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program. */ 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state); 49fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address. */ 52fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Values for the parameters which have no short form. */ 554be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath#define OPT_GAPS 0x100 564be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath#define OPT_HASH_INEXACT 0x101 571fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath#define OPT_IGNORE_BUILD_ID 0x102 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions. */ 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] = 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Control options:"), 0 }, 634a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath { "verbose", 'l', NULL, 0, 644a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath N_("Output all differences, not just the first"), 0 }, 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "gaps", OPT_GAPS, "ACTION", 0, N_("Control treatment of gaps in loadable segments [ignore|match] (default: ignore)"), 0 }, 664be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { "hash-inexact", OPT_HASH_INEXACT, NULL, 0, 674be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath N_("Ignore permutation of buckets in SHT_HASH section"), 0 }, 681fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { "ignore-build-id", OPT_IGNORE_BUILD_ID, NULL, 0, 691fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath N_("Ignore differences in build ID"), 0 }, 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "quiet", 'q', NULL, 0, N_("Output nothing; yield exit status only"), 0 }, 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, NULL, 0 } 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program. */ 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("\ 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCompare relevant parts of two ELF files for equality."); 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts. */ 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("FILE1 FILE2"); 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler. */ 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions. */ 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp = 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper options, parse_opt, args_doc, doc, NULL, NULL, NULL 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* How to treat gaps in loadable segments. */ 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic enum 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gaps_ignore = 0, 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gaps_match 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gaps; 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Structure to hold information about used regions. */ 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct region 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Addr from; 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Addr to; 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region *next; 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Nonzero if only exit status is wanted. */ 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool quiet; 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1124a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath/* True iff multiple differences should be output. */ 1134a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrathstatic bool verbose; 1144a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath 1154be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath/* True iff SHT_HASH treatment should be generous. */ 1164be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic bool hash_inexact; 1174be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 1181fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath/* True iff build ID notes should be ignored. */ 1191fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrathstatic bool ignore_build_id; 1201fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 1214be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic bool hash_content_equivalent (size_t entsize, Elf_Data *, Elf_Data *); 1224be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[]) 126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set locale. */ 128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) setlocale (LC_ALL, ""); 129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the message catalog can be found. */ 131b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Initialize the message catalog. */ 134b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper (void) textdomain (PACKAGE_TARNAME); 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Parse and process arguments. */ 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int remaining; 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We expect exactly two non-option parameters. */ 141e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (remaining + 2 != argc)) 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fputs (gettext ("Invalid number of parameters.\n"), stderr); 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name); 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper exit (1); 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1484a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath if (quiet) 1494a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath verbose = false; 1504a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Comparing the files is done in two phases: 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1. compare all sections. Sections which are irrelevant (i.e., if 1533a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper strip would remove them) are ignored. Some section types are 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper handled special. 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2. all parts of the loadable segments which are not parts of any 1563a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper section is compared according to the rules of the --gaps option. 157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = 0; 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_version (EV_CURRENT); 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *const fname1 = argv[remaining]; 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fd1; 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl1; 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf1 = open_file (fname1, &fd1, &ebl1); 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *const fname2 = argv[remaining + 1]; 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fd2; 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl2; 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf2 = open_file (fname2, &fd2, &ebl2); 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr ehdr1_mem; 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr *ehdr1 = gelf_getehdr (elf1, &ehdr1_mem); 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr1 == NULL) 1743614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot get ELF header of '%s': %s"), 175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, elf_errmsg (-1)); 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr ehdr2_mem; 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr *ehdr2 = gelf_getehdr (elf2, &ehdr2_mem); 178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr2 == NULL) 1793614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot get ELF header of '%s': %s"), 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname2, elf_errmsg (-1)); 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1824a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath#define DIFFERENCE \ 1834a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath do \ 1844a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath { \ 1854a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath result = 1; \ 1864a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath if (! verbose) \ 1874a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath goto out; \ 1884a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath } \ 1894a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath while (0) 1904a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compare the ELF headers. */ 192e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (memcmp (ehdr1->e_ident, ehdr2->e_ident, EI_NIDENT) != 0 193e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_type != ehdr2->e_type 194e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_machine != ehdr2->e_machine 195e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_version != ehdr2->e_version 196e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_entry != ehdr2->e_entry 197e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_phoff != ehdr2->e_phoff 198e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_flags != ehdr2->e_flags 199e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_ehsize != ehdr2->e_ehsize 200e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_phentsize != ehdr2->e_phentsize 201e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_phnum != ehdr2->e_phnum 202e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || ehdr1->e_shentsize != ehdr2->e_shentsize)) 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s %s diff: ELF header"), fname1, fname2); 2064a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 209bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath size_t shnum1; 210bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath size_t shnum2; 211bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (unlikely (elf_getshdrnum (elf1, &shnum1) != 0)) 212bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath error (2, 0, gettext ("cannot get section count of '%s': %s"), 213bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath fname1, elf_errmsg (-1)); 214bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (unlikely (elf_getshdrnum (elf2, &shnum2) != 0)) 215bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath error (2, 0, gettext ("cannot get section count of '%s': %s"), 216bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath fname2, elf_errmsg (-1)); 217bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (unlikely (shnum1 != shnum2)) 218bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath { 219bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (! quiet) 220bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath error (0, 0, gettext ("%s %s diff: section count"), fname1, fname2); 2214a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 222bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath } 223bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath 224bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath size_t phnum1; 225bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath size_t phnum2; 226bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (unlikely (elf_getphdrnum (elf1, &phnum1) != 0)) 227bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath error (2, 0, gettext ("cannot get program header count of '%s': %s"), 228bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath fname1, elf_errmsg (-1)); 229bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (unlikely (elf_getphdrnum (elf2, &phnum2) != 0)) 230bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath error (2, 0, gettext ("cannot get program header count of '%s': %s"), 231bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath fname2, elf_errmsg (-1)); 232bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (unlikely (phnum1 != phnum2)) 233bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath { 234bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath if (! quiet) 235bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath error (0, 0, gettext ("%s %s diff: program header count"), 236bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath fname1, fname2); 2374a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 238bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath } 239bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Iterate over all sections. We expect the sections in the two 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper files to match exactly. */ 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn1 = NULL; 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn2 = NULL; 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region *regions = NULL; 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t nregions = 0; 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (1) 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr1_mem; 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr1; 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *sname1 = NULL; 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scn1 = elf_nextscn (elf1, scn1); 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr1 = gelf_getshdr (scn1, &shdr1_mem); 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr1 != NULL) 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sname1 = elf_strptr (elf1, ehdr1->e_shstrndx, shdr1->sh_name); 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (scn1 != NULL 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_section_strip_p (ebl1, ehdr1, shdr1, sname1, true, false)); 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr2_mem; 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr2; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *sname2 = NULL; 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scn2 = elf_nextscn (elf2, scn2); 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr2 = gelf_getshdr (scn2, &shdr2_mem); 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr2 != NULL) 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sname2 = elf_strptr (elf2, ehdr2->e_shstrndx, shdr2->sh_name); 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (scn2 != NULL 272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_section_strip_p (ebl2, ehdr2, shdr2, sname2, true, false)); 273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scn1 == NULL || scn2 == NULL) 275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gaps != gaps_ignore && (shdr1->sh_flags & SHF_ALLOC) != 0) 278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region *newp = (struct region *) alloca (sizeof (*newp)); 280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->from = shdr1->sh_offset; 281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->to = shdr1->sh_offset + shdr1->sh_size; 282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newp->next = regions; 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper regions = newp; 284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++nregions; 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compare the headers. We allow the name to be at a different 289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper location. */ 290e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard if (unlikely (sname1 == NULL || sname2 == NULL 291e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard || strcmp (sname1, sname2) != 0)) 292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2934a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath error (0, 0, gettext ("%s %s differ: section [%zu], [%zu] name"), 2944a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath fname1, fname2, elf_ndxscn (scn1), elf_ndxscn (scn2)); 2954a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We ignore certain sections. */ 299e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard if ((sname1 != NULL && strcmp (sname1, ".gnu_debuglink") == 0) 300e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard || (sname1 != NULL && strcmp (sname1, ".gnu.prelink_undo") == 0)) 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr1->sh_type != shdr2->sh_type 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX Any flags which should be ignored? 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_flags != shdr2->sh_flags 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_addr != shdr2->sh_addr 307059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath || (shdr1->sh_offset != shdr2->sh_offset 308059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath && (shdr1->sh_flags & SHF_ALLOC) 309059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath && ehdr1->e_type != ET_REL) 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_size != shdr2->sh_size 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_link != shdr2->sh_link 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_info != shdr2->sh_info 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_addralign != shdr2->sh_addralign 314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_entsize != shdr2->sh_entsize) 3154a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath { 3164a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath error (0, 0, gettext ("%s %s differ: section [%zu] '%s' header"), 3174a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath fname1, fname2, elf_ndxscn (scn1), sname1); 3184a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 3194a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath } 320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data1 = elf_getdata (scn1, NULL); 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data1 == NULL) 3233614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 324e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get content of section %zu in '%s': %s"), 325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ndxscn (scn1), fname1, elf_errmsg (-1)); 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data2 = elf_getdata (scn2, NULL); 328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data2 == NULL) 3293614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 330e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get content of section %zu in '%s': %s"), 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ndxscn (scn2), fname2, elf_errmsg (-1)); 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (shdr1->sh_type) 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_DYNSYM: 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_SYMTAB: 337e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard if (shdr1->sh_entsize == 0) 338e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard error (2, 0, 339e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard gettext ("symbol table [%zu] in '%s' has zero sh_entsize"), 340e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard elf_ndxscn (scn1), fname1); 341e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Iterate over the symbol table. We ignore the st_size 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper value of undefined symbols. */ 344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int ndx = 0; ndx < (int) (shdr1->sh_size / shdr1->sh_entsize); 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ndx) 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym1_mem; 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym1 = gelf_getsym (data1, ndx, &sym1_mem); 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym1 == NULL) 3503614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 351e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get symbol in '%s': %s"), 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, elf_errmsg (-1)); 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym2_mem; 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym2 = gelf_getsym (data2, ndx, &sym2_mem); 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym2 == NULL) 3563614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 357e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get symbol in '%s': %s"), 358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname2, elf_errmsg (-1)); 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name1 = elf_strptr (elf1, shdr1->sh_link, 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym1->st_name); 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name2 = elf_strptr (elf2, shdr2->sh_link, 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym2->st_name); 3645c1a45c2d370e7fd1149fa74a9382e202fbfe8feMark Wielaard if (unlikely (name1 == NULL || name2 == NULL 3655c1a45c2d370e7fd1149fa74a9382e202fbfe8feMark Wielaard || strcmp (name1, name2) != 0 366e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || sym1->st_value != sym2->st_value 367e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || (sym1->st_size != sym2->st_size 368e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper && sym1->st_shndx != SHN_UNDEF) 369e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || sym1->st_info != sym2->st_info 370e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || sym1->st_other != sym2->st_other 371e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || sym1->st_shndx != sym1->st_shndx)) 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX Do we want to allow reordered symbol tables? 3747d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper symtab_mismatch: 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 3767d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper { 3777d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper if (elf_ndxscn (scn1) == elf_ndxscn (scn2)) 3787d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper error (0, 0, 3797d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper gettext ("%s %s differ: symbol table [%zu]"), 3807d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper fname1, fname2, elf_ndxscn (scn1)); 3817d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper else 3827d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper error (0, 0, gettext ("\ 3837d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper%s %s differ: symbol table [%zu,%zu]"), 3847d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper fname1, fname2, elf_ndxscn (scn1), 3857d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper elf_ndxscn (scn2)); 3867d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper } 3874a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 3884a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath break; 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym1->st_shndx == SHN_UNDEF 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym1->st_size != sym2->st_size) 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The size of the symbol in the object defining it 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might have changed. That is OK unless the symbol 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is used in a copy relocation. Look over the 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sections in both files and determine which 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper relocation section uses this symbol table 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section. Then look through the relocations to 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper see whether any copy relocation references this 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper symbol. */ 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (search_for_copy_reloc (ebl1, elf_ndxscn (scn1), ndx) 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || search_for_copy_reloc (ebl2, elf_ndxscn (scn2), ndx)) 4047d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper goto symtab_mismatch; 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4091fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath case SHT_NOTE: 4101fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath /* Parse the note format and compare the notes themselves. */ 4111fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4121fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath GElf_Nhdr note1; 4131fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath GElf_Nhdr note2; 4141fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 4151fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath size_t off1 = 0; 4161fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath size_t off2 = 0; 4171fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath size_t name_offset; 4181fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath size_t desc_offset; 4191fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath while (off1 < data1->d_size 4201fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath && (off1 = gelf_getnote (data1, off1, ¬e1, 4211fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath &name_offset, &desc_offset)) > 0) 4221fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4231fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath const char *name1 = data1->d_buf + name_offset; 4241fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath const void *desc1 = data1->d_buf + desc_offset; 4251fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (off2 >= data2->d_size) 4261fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4271fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4281fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4291fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' number of notes"), 4301fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1); 4314a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4321fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4331fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath off2 = gelf_getnote (data2, off2, ¬e2, 4341fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath &name_offset, &desc_offset); 4351fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (off2 == 0) 4361fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (2, 0, gettext ("\ 4371fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrathcannot read note section [%zu] '%s' in '%s': %s"), 4381fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath elf_ndxscn (scn2), sname2, fname2, elf_errmsg (-1)); 4391fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath const char *name2 = data2->d_buf + name_offset; 4401fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath const void *desc2 = data2->d_buf + desc_offset; 4411fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 4421fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_namesz != note2.n_namesz 4431fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath || memcmp (name1, name2, note1.n_namesz)) 4441fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4451fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4461fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4471fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' note name"), 4481fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1); 4494a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4501fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4511fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_type != note2.n_type) 4521fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4531fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4541fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4551fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' note '%s' type"), 4561fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1, name1); 4574a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4581fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4591fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_descsz != note2.n_descsz 4601fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath || memcmp (desc1, desc2, note1.n_descsz)) 4611fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4621fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_type == NT_GNU_BUILD_ID 4631fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath && note1.n_namesz == sizeof "GNU" 4641fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath && !memcmp (name1, "GNU", sizeof "GNU")) 4651fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4661fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_descsz != note2.n_descsz) 4671fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4681fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4691fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4701fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: build ID length"), 4711fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2); 4724a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4731fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4741fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath else if (! ignore_build_id) 4751fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4761fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4771fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4781fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: build ID content"), 4791fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2); 4804a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4811fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4821fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4831fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath else 4841fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4851fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4861fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4871fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' note '%s' content"), 4881fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1, 4891fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath name1); 4904a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4911fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4921fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4931fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4941fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (off2 < data2->d_size) 4951fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4961fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4971fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4981fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' number of notes"), 4991fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1); 5004a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 5011fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 5021fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 5031fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath break; 5041fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compare the section content byte for byte. */ 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (shdr1->sh_type == SHT_NOBITS 508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (data1->d_buf != NULL || data1->d_size == 0)); 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (shdr2->sh_type == SHT_NOBITS 510b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (data2->d_buf != NULL || data1->d_size == 0)); 511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 512e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (data1->d_size != data2->d_size 513e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || (shdr1->sh_type != SHT_NOBITS 5140d528f9ceff2b96c521cefd75fc62d7151e3e6b1Mark Wielaard && data1->d_size != 0 515e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper && memcmp (data1->d_buf, data2->d_buf, 516e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper data1->d_size) != 0))) 517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 5184be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (hash_inexact 5194be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath && shdr1->sh_type == SHT_HASH 5204be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath && data1->d_size == data2->d_size 5214be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath && hash_content_equivalent (shdr1->sh_entsize, data1, data2)) 5224be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 5234be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 5257d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper { 5267d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper if (elf_ndxscn (scn1) == elf_ndxscn (scn2)) 5277d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper error (0, 0, gettext ("\ 5287d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper%s %s differ: section [%zu] '%s' content"), 5297d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper fname1, fname2, elf_ndxscn (scn1), sname1); 5307d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper else 5317d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper error (0, 0, gettext ("\ 5327d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper%s %s differ: section [%zu,%zu] '%s' content"), 5337d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper fname1, fname2, elf_ndxscn (scn1), 5347d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper elf_ndxscn (scn2), sname1); 5357d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper } 5364a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 542e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (scn1 != scn2)) 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, 546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("%s %s differ: unequal amount of important sections"), 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, fname2); 5484a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We we look at gaps, create artificial ones for the parts of the 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper program which we are not in sections. */ 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region ehdr_region; 554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region phdr_region; 555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gaps != gaps_ignore) 556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr_region.from = 0; 558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr_region.to = ehdr1->e_ehsize; 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr_region.next = &phdr_region; 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr_region.from = ehdr1->e_phoff; 562bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath phdr_region.to = ehdr1->e_phoff + phnum1 * ehdr1->e_phentsize; 563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr_region.next = regions; 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper regions = &ehdr_region; 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper nregions += 2; 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we need to look at the gaps we need access to the file data. */ 570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *raw1 = NULL; 571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t size1 = 0; 572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *raw2 = NULL; 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t size2 = 0; 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region *regionsarr = alloca (nregions * sizeof (struct region)); 575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gaps != gaps_ignore) 576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper raw1 = elf_rawfile (elf1, &size1); 578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (raw1 == NULL ) 5793614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot load data of '%s': %s"), 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, elf_errmsg (-1)); 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper raw2 = elf_rawfile (elf2, &size2); 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (raw2 == NULL ) 5843614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot load data of '%s': %s"), 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname2, elf_errmsg (-1)); 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < nregions; ++cnt) 588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper regionsarr[cnt] = *regions; 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper regions = regions->next; 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper qsort (regionsarr, nregions, sizeof (regionsarr[0]), regioncompare); 594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compare the program header tables. */ 597bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (unsigned int ndx = 0; ndx < phnum1; ++ndx) 598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr1_mem; 600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr1 = gelf_getphdr (elf1, ndx, &phdr1_mem); 601e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard if (phdr1 == NULL) 6023614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 603e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get program header entry %d of '%s': %s"), 604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ndx, fname1, elf_errmsg (-1)); 605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr2_mem; 606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr2 = gelf_getphdr (elf2, ndx, &phdr2_mem); 607e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard if (phdr2 == NULL) 6083614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 609e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get program header entry %d of '%s': %s"), 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ndx, fname2, elf_errmsg (-1)); 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 612e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (memcmp (phdr1, phdr2, sizeof (GElf_Phdr)) != 0)) 613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s %s differ: program header %d"), 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, fname2, ndx); 6174a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gaps != gaps_ignore && phdr1->p_type == PT_LOAD) 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt = 0; 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (cnt < nregions && regionsarr[cnt].to < phdr1->p_offset) 624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++cnt; 625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Off last = phdr1->p_offset; 627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Off end = phdr1->p_offset + phdr1->p_filesz; 628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (cnt < nregions && regionsarr[cnt].from < end) 629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (last < regionsarr[cnt].from) 631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compare the [LAST,FROM) region. */ 633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (gaps == gaps_match); 634e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (memcmp (raw1 + last, raw2 + last, 635e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper regionsarr[cnt].from - last) != 0)) 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gapmismatch: 638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!quiet) 639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s %s differ: gap"), 640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, fname2); 6414a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 6424a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath break; 643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper last = regionsarr[cnt].to; 647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++cnt; 648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == nregions && last < end) 651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto gapmismatch; 652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out: 656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_end (elf1); 657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_end (elf2); 658095f53490bcf684a834d835ee8118f1d8ea51698Mark Wielaard ebl_closebackend (ebl1); 659095f53490bcf684a834d835ee8118f1d8ea51698Mark Wielaard ebl_closebackend (ebl2); 660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd1); 661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd2); 662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 666b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information. */ 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 671b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper fprintf (stream, "elfcmp (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("\ 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCopyright (C) %s Red Hat, Inc.\n\ 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions. There is NO\n\ 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 6763a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper"), "2012"); 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments. */ 682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt (int key, char *arg, 684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct argp_state *state __attribute__ ((unused))) 685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'q': 689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper quiet = true; 690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6924a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath case 'l': 6934a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath verbose = true; 6944a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath break; 6954a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath 696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case OPT_GAPS: 697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcasecmp (arg, "ignore") == 0) 698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gaps = gaps_ignore; 699e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper else if (likely (strcasecmp (arg, "match") == 0)) 700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gaps = gaps_match; 701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stderr, 704e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("Invalid value '%s' for --gaps parameter."), 705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arg); 706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_help (&argp, stderr, ARGP_HELP_SEE, 707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper program_invocation_short_name); 708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper exit (1); 709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 7124be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath case OPT_HASH_INEXACT: 7134be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath hash_inexact = true; 7144be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 7154be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 7161fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath case OPT_IGNORE_BUILD_ID: 7171fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath ignore_build_id = true; 7181fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath break; 7191fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Elf * 728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperopen_file (const char *fname, int *fdp, Ebl **eblp) 729b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fd = open (fname, O_RDONLY); 731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (fd == -1)) 7323614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, errno, gettext ("cannot open '%s'"), fname); 733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf == NULL) 7353614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 736e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot create ELF descriptor for '%s': %s"), 737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname, elf_errmsg (-1)); 738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl = ebl_openbackend (elf); 739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ebl == NULL) 7403614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 741e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot create EBL descriptor for '%s'"), fname); 742b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *fdp = fd; 744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *eblp = ebl; 745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return elf; 746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersearch_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx) 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 7583614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("cannot get section header of section %zu: %s"), 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ndxscn (scn), elf_errmsg (-1)); 761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA) 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr->sh_link != scnndx) 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 7683614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("cannot get content of section %zu: %s"), 770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ndxscn (scn), elf_errmsg (-1)); 771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 772e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard if (shdr->sh_type == SHT_REL && shdr->sh_entsize != 0) 773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize); 774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ndx) 775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel rel_mem; 777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel *rel = gelf_getrel (data, ndx, &rel_mem); 778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rel == NULL) 7793614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot get relocation: %s"), 780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 781b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((int) GELF_R_SYM (rel->r_info) == symndx 783b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) 784b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 786e16e14100fe2ff70535977fe9ebd32f8d7ca5146Mark Wielaard else if (shdr->sh_entsize != 0) 787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize); 788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ndx) 789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rela rela_mem; 791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rela *rela = gelf_getrela (data, ndx, &rela_mem); 792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rela == NULL) 7933614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot get relocation: %s"), 794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((int) GELF_R_SYM (rela->r_info) == symndx 797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) 798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 8064be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic int 807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperregioncompare (const void *p1, const void *p2) 808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const struct region *r1 = (const struct region *) p1; 810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const struct region *r2 = (const struct region *) p2; 811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (r1->from < r2->from) 813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 814b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 815b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 8164be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8174be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8184be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic int 8194be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathcompare_Elf32_Word (const void *p1, const void *p2) 8204be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath{ 8214be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Elf32_Word *w1 = p1; 8224be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Elf32_Word *w2 = p2; 823274cbda6f5d5b7c57d488edaeb55876ba8705db3Mark Wielaard return *w1 < *w2 ? -1 : *w1 > *w2 ? 1 : 0; 8244be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath} 8254be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8264be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic int 8274be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathcompare_Elf64_Xword (const void *p1, const void *p2) 8284be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath{ 8294be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Elf64_Xword *w1 = p1; 8304be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Elf64_Xword *w2 = p2; 8314be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return *w1 < *w2 ? -1 : *w1 > *w2 ? 1 : 0; 8324be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath} 8334be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8344be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic bool 8354be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathhash_content_equivalent (size_t entsize, Elf_Data *data1, Elf_Data *data2) 8364be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath{ 8374be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath#define CHECK_HASH(Hash_Word) \ 8384be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { \ 8394be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const hash1 = data1->d_buf; \ 8404be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const hash2 = data2->d_buf; \ 8414be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const size_t nbucket = hash1[0]; \ 8424be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const size_t nchain = hash1[1]; \ 8434be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (data1->d_size != (2 + nbucket + nchain) * sizeof hash1[0] \ 8444be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath || hash2[0] != nbucket || hash2[1] != nchain) \ 8454be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8464be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8474be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const bucket1 = &hash1[2]; \ 8484be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const chain1 = &bucket1[nbucket]; \ 8494be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const bucket2 = &hash2[2]; \ 8504be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const chain2 = &bucket2[nbucket]; \ 8514be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8524be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath bool chain_ok[nchain]; \ 8534be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath Hash_Word temp1[nchain - 1]; \ 8544be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath Hash_Word temp2[nchain - 1]; \ 8554be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath memset (chain_ok, 0, sizeof chain_ok); \ 8564be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (size_t i = 0; i < nbucket; ++i) \ 8574be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { \ 8584be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (bucket1[i] >= nchain || bucket2[i] >= nchain) \ 8594be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8604be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8614be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath size_t b1 = 0; \ 8624be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (size_t p = bucket1[i]; p != STN_UNDEF; p = chain1[p]) \ 8634be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (p >= nchain || b1 >= nchain - 1) \ 8644be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8654be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath else \ 8664be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath temp1[b1++] = p; \ 8674be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8684be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath size_t b2 = 0; \ 8694be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (size_t p = bucket2[i]; p != STN_UNDEF; p = chain2[p]) \ 8704be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (p >= nchain || b2 >= nchain - 1) \ 8714be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8724be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath else \ 8734be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath temp2[b2++] = p; \ 8744be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8754be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (b1 != b2) \ 8764be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8774be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8784be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath qsort (temp1, b1, sizeof temp1[0], compare_##Hash_Word); \ 8794be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath qsort (temp2, b2, sizeof temp2[0], compare_##Hash_Word); \ 8804be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8814be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (b1 = 0; b1 < b2; ++b1) \ 8824be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (temp1[b1] != temp2[b1]) \ 8834be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8844be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath else \ 8854be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath chain_ok[temp1[b1]] = true; \ 8864be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath } \ 8874be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8884be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (size_t i = 0; i < nchain; ++i) \ 8894be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (!chain_ok[i] && chain1[i] != chain2[i]) \ 8904be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8914be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8924be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return true; \ 8934be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath } 8944be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8954be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath switch (entsize) 8964be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { 8974be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath case 4: 8984be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath CHECK_HASH (Elf32_Word); 8994be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 9004be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath case 8: 9014be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath CHECK_HASH (Elf64_Xword); 9024be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 9034be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath } 9044be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 9054be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; 9064be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath} 9073cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 9083cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 9093cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper#include "debugpred.h" 910