elfcmp.c revision de2ed97f33139af5c7a0811e4ec66fc896a13cf2
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Compare relevant content of two ELF files. 23a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper Copyright (C) 2005-2012 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. */ 290e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (strcmp (sname1, sname2) != 0)) 291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2924a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath error (0, 0, gettext ("%s %s differ: section [%zu], [%zu] name"), 2934a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath fname1, fname2, elf_ndxscn (scn1), elf_ndxscn (scn2)); 2944a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We ignore certain sections. */ 298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcmp (sname1, ".gnu_debuglink") == 0 299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || strcmp (sname1, ".gnu.prelink_undo") == 0) 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr1->sh_type != shdr2->sh_type 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX Any flags which should be ignored? 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_flags != shdr2->sh_flags 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_addr != shdr2->sh_addr 306059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath || (shdr1->sh_offset != shdr2->sh_offset 307059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath && (shdr1->sh_flags & SHF_ALLOC) 308059c83e5db89955913a39fe6705acca571c32c3fRoland McGrath && ehdr1->e_type != ET_REL) 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_size != shdr2->sh_size 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_link != shdr2->sh_link 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_info != shdr2->sh_info 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_addralign != shdr2->sh_addralign 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr1->sh_entsize != shdr2->sh_entsize) 3144a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath { 3154a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath error (0, 0, gettext ("%s %s differ: section [%zu] '%s' header"), 3164a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath fname1, fname2, elf_ndxscn (scn1), sname1); 3174a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 3184a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath } 319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data1 = elf_getdata (scn1, NULL); 321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data1 == NULL) 3223614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 323e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get content of section %zu in '%s': %s"), 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ndxscn (scn1), fname1, elf_errmsg (-1)); 325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data2 = elf_getdata (scn2, NULL); 327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data2 == NULL) 3283614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 329e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get content of section %zu in '%s': %s"), 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ndxscn (scn2), fname2, elf_errmsg (-1)); 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (shdr1->sh_type) 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_DYNSYM: 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case SHT_SYMTAB: 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Iterate over the symbol table. We ignore the st_size 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper value of undefined symbols. */ 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int ndx = 0; ndx < (int) (shdr1->sh_size / shdr1->sh_entsize); 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ndx) 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym1_mem; 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym1 = gelf_getsym (data1, ndx, &sym1_mem); 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym1 == NULL) 3443614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 345e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get symbol in '%s': %s"), 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, elf_errmsg (-1)); 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym2_mem; 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym2 = gelf_getsym (data2, ndx, &sym2_mem); 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym2 == NULL) 3503614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 351e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get symbol in '%s': %s"), 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname2, elf_errmsg (-1)); 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name1 = elf_strptr (elf1, shdr1->sh_link, 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym1->st_name); 356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name2 = elf_strptr (elf2, shdr2->sh_link, 357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sym2->st_name); 358e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (strcmp (name1, name2) != 0 359e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || sym1->st_value != sym2->st_value 360e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || (sym1->st_size != sym2->st_size 361e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper && sym1->st_shndx != SHN_UNDEF) 362e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || sym1->st_info != sym2->st_info 363e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || sym1->st_other != sym2->st_other 364e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || sym1->st_shndx != sym1->st_shndx)) 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX Do we want to allow reordered symbol tables? 3677d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper symtab_mismatch: 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 3697d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper { 3707d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper if (elf_ndxscn (scn1) == elf_ndxscn (scn2)) 3717d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper error (0, 0, 3727d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper gettext ("%s %s differ: symbol table [%zu]"), 3737d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper fname1, fname2, elf_ndxscn (scn1)); 3747d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper else 3757d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper error (0, 0, gettext ("\ 3767d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper%s %s differ: symbol table [%zu,%zu]"), 3777d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper fname1, fname2, elf_ndxscn (scn1), 3787d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper elf_ndxscn (scn2)); 3797d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper } 3804a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 3814a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath break; 382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym1->st_shndx == SHN_UNDEF 385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym1->st_size != sym2->st_size) 386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The size of the symbol in the object defining it 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might have changed. That is OK unless the symbol 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is used in a copy relocation. Look over the 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sections in both files and determine which 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper relocation section uses this symbol table 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section. Then look through the relocations to 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper see whether any copy relocation references this 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper symbol. */ 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (search_for_copy_reloc (ebl1, elf_ndxscn (scn1), ndx) 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || search_for_copy_reloc (ebl2, elf_ndxscn (scn2), ndx)) 3977d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper goto symtab_mismatch; 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4021fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath case SHT_NOTE: 4031fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath /* Parse the note format and compare the notes themselves. */ 4041fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4051fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath GElf_Nhdr note1; 4061fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath GElf_Nhdr note2; 4071fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 4081fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath size_t off1 = 0; 4091fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath size_t off2 = 0; 4101fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath size_t name_offset; 4111fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath size_t desc_offset; 4121fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath while (off1 < data1->d_size 4131fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath && (off1 = gelf_getnote (data1, off1, ¬e1, 4141fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath &name_offset, &desc_offset)) > 0) 4151fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4161fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath const char *name1 = data1->d_buf + name_offset; 4171fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath const void *desc1 = data1->d_buf + desc_offset; 4181fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (off2 >= data2->d_size) 4191fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4201fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4211fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4221fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' number of notes"), 4231fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1); 4244a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4251fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4261fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath off2 = gelf_getnote (data2, off2, ¬e2, 4271fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath &name_offset, &desc_offset); 4281fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (off2 == 0) 4291fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (2, 0, gettext ("\ 4301fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrathcannot read note section [%zu] '%s' in '%s': %s"), 4311fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath elf_ndxscn (scn2), sname2, fname2, elf_errmsg (-1)); 4321fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath const char *name2 = data2->d_buf + name_offset; 4331fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath const void *desc2 = data2->d_buf + desc_offset; 4341fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 4351fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_namesz != note2.n_namesz 4361fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath || memcmp (name1, name2, note1.n_namesz)) 4371fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4381fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4391fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4401fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' note name"), 4411fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1); 4424a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4431fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4441fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_type != note2.n_type) 4451fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4461fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4471fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4481fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' note '%s' type"), 4491fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1, name1); 4504a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4511fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4521fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_descsz != note2.n_descsz 4531fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath || memcmp (desc1, desc2, note1.n_descsz)) 4541fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4551fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_type == NT_GNU_BUILD_ID 4561fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath && note1.n_namesz == sizeof "GNU" 4571fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath && !memcmp (name1, "GNU", sizeof "GNU")) 4581fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4591fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (note1.n_descsz != note2.n_descsz) 4601fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4611fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4621fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4631fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: build ID length"), 4641fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2); 4654a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4661fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4671fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath else if (! ignore_build_id) 4681fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4691fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4701fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4711fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: build ID content"), 4721fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2); 4734a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4741fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4751fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4761fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath else 4771fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4781fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4791fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4801fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' note '%s' content"), 4811fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1, 4821fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath name1); 4834a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4841fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4851fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4861fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4871fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (off2 < data2->d_size) 4881fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath { 4891fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath if (! quiet) 4901fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath error (0, 0, gettext ("\ 4911fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath%s %s differ: section [%zu] '%s' number of notes"), 4921fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath fname1, fname2, elf_ndxscn (scn1), sname1); 4934a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 4941fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4951fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath } 4961fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath break; 4971fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compare the section content byte for byte. */ 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (shdr1->sh_type == SHT_NOBITS 501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (data1->d_buf != NULL || data1->d_size == 0)); 502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (shdr2->sh_type == SHT_NOBITS 503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (data2->d_buf != NULL || data1->d_size == 0)); 504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 505e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (data1->d_size != data2->d_size 506e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper || (shdr1->sh_type != SHT_NOBITS 507e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper && memcmp (data1->d_buf, data2->d_buf, 508e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper data1->d_size) != 0))) 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 5104be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (hash_inexact 5114be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath && shdr1->sh_type == SHT_HASH 5124be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath && data1->d_size == data2->d_size 5134be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath && hash_content_equivalent (shdr1->sh_entsize, data1, data2)) 5144be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 5154be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 5177d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper { 5187d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper if (elf_ndxscn (scn1) == elf_ndxscn (scn2)) 5197d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper error (0, 0, gettext ("\ 5207d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper%s %s differ: section [%zu] '%s' content"), 5217d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper fname1, fname2, elf_ndxscn (scn1), sname1); 5227d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper else 5237d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper error (0, 0, gettext ("\ 5247d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper%s %s differ: section [%zu,%zu] '%s' content"), 5257d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper fname1, fname2, elf_ndxscn (scn1), 5267d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper elf_ndxscn (scn2), sname1); 5277d48d6a13fa164209a5c75d27d10cf1cd7b1c4a9Ulrich Drepper } 5284a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 534e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (scn1 != scn2)) 535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, 538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("%s %s differ: unequal amount of important sections"), 539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, fname2); 5404a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We we look at gaps, create artificial ones for the parts of the 544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper program which we are not in sections. */ 545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region ehdr_region; 546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region phdr_region; 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gaps != gaps_ignore) 548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr_region.from = 0; 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr_region.to = ehdr1->e_ehsize; 551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ehdr_region.next = &phdr_region; 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr_region.from = ehdr1->e_phoff; 554bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath phdr_region.to = ehdr1->e_phoff + phnum1 * ehdr1->e_phentsize; 555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper phdr_region.next = regions; 556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper regions = &ehdr_region; 558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper nregions += 2; 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we need to look at the gaps we need access to the file data. */ 562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *raw1 = NULL; 563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t size1 = 0; 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *raw2 = NULL; 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t size2 = 0; 566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct region *regionsarr = alloca (nregions * sizeof (struct region)); 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gaps != gaps_ignore) 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper raw1 = elf_rawfile (elf1, &size1); 570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (raw1 == NULL ) 5713614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot load data of '%s': %s"), 572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, elf_errmsg (-1)); 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper raw2 = elf_rawfile (elf2, &size2); 575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (raw2 == NULL ) 5763614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot load data of '%s': %s"), 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname2, elf_errmsg (-1)); 578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t cnt = 0; cnt < nregions; ++cnt) 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper regionsarr[cnt] = *regions; 582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper regions = regions->next; 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper qsort (regionsarr, nregions, sizeof (regionsarr[0]), regioncompare); 586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compare the program header tables. */ 589bd733cae5159e3a3c4c05f7685559fa3ae8b58c6Roland McGrath for (unsigned int ndx = 0; ndx < phnum1; ++ndx) 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr1_mem; 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr1 = gelf_getphdr (elf1, ndx, &phdr1_mem); 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr1 == NULL) 5943614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 595e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get program header entry %d of '%s': %s"), 596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ndx, fname1, elf_errmsg (-1)); 597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr2_mem; 598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr *phdr2 = gelf_getphdr (elf2, ndx, &phdr2_mem); 599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr2 == NULL) 6003614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 601e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot get program header entry %d of '%s': %s"), 602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ndx, fname2, elf_errmsg (-1)); 603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 604e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (memcmp (phdr1, phdr2, sizeof (GElf_Phdr)) != 0)) 605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (! quiet) 607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s %s differ: program header %d"), 608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, fname2, ndx); 6094a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gaps != gaps_ignore && phdr1->p_type == PT_LOAD) 613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt = 0; 615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (cnt < nregions && regionsarr[cnt].to < phdr1->p_offset) 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++cnt; 617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Off last = phdr1->p_offset; 619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Off end = phdr1->p_offset + phdr1->p_filesz; 620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (cnt < nregions && regionsarr[cnt].from < end) 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (last < regionsarr[cnt].from) 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Compare the [LAST,FROM) region. */ 625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (gaps == gaps_match); 626e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (unlikely (memcmp (raw1 + last, raw2 + last, 627e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper regionsarr[cnt].from - last) != 0)) 628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gapmismatch: 630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!quiet) 631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s %s differ: gap"), 632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname1, fname2); 6334a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath DIFFERENCE; 6344a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath break; 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper last = regionsarr[cnt].to; 639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++cnt; 640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == nregions && last < end) 643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto gapmismatch; 644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out: 648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_end (elf1); 649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_end (elf2); 650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd1); 651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd2); 652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information. */ 658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 661b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper fprintf (stream, "elfcmp (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("\ 663b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCopyright (C) %s Red Hat, Inc.\n\ 664b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions. There is NO\n\ 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 6663a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper"), "2012"); 667b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 671b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments. */ 672b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt (int key, char *arg, 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct argp_state *state __attribute__ ((unused))) 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'q': 679b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper quiet = true; 680b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 681b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6824a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath case 'l': 6834a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath verbose = true; 6844a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath break; 6854a14ef7b9a4b274fd45d17512cf0da42956b672bRoland McGrath 686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case OPT_GAPS: 687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (strcasecmp (arg, "ignore") == 0) 688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gaps = gaps_ignore; 689e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper else if (likely (strcasecmp (arg, "match") == 0)) 690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gaps = gaps_match; 691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stderr, 694e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("Invalid value '%s' for --gaps parameter."), 695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arg); 696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_help (&argp, stderr, ARGP_HELP_SEE, 697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper program_invocation_short_name); 698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper exit (1); 699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 7024be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath case OPT_HASH_INEXACT: 7034be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath hash_inexact = true; 7044be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 7054be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 7061fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath case OPT_IGNORE_BUILD_ID: 7071fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath ignore_build_id = true; 7081fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath break; 7091fb9c917a55fa30c5f6b27c30727a796f9b1e804Roland McGrath 710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Elf * 718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperopen_file (const char *fname, int *fdp, Ebl **eblp) 719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int fd = open (fname, O_RDONLY); 721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (fd == -1)) 7223614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, errno, gettext ("cannot open '%s'"), fname); 723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf == NULL) 7253614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 726e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot create ELF descriptor for '%s': %s"), 727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname, elf_errmsg (-1)); 728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl = ebl_openbackend (elf); 729b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ebl == NULL) 7303614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 731e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper gettext ("cannot create EBL descriptor for '%s'"), fname); 732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *fdp = fd; 734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *eblp = ebl; 735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return elf; 736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool 740b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppersearch_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx) 741b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 742b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn = NULL; 743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr_mem; 746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr == NULL) 7483614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("cannot get section header of section %zu: %s"), 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ndxscn (scn), elf_errmsg (-1)); 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA) 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr->sh_link != scnndx) 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (data == NULL) 7583614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gettext ("cannot get content of section %zu: %s"), 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_ndxscn (scn), elf_errmsg (-1)); 761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr->sh_type == SHT_REL) 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize); 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ndx) 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel rel_mem; 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rel *rel = gelf_getrel (data, ndx, &rel_mem); 768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rel == NULL) 7693614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot get relocation: %s"), 770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((int) GELF_R_SYM (rel->r_info) == symndx 773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info))) 774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize); 778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++ndx) 779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rela rela_mem; 781b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Rela *rela = gelf_getrela (data, ndx, &rela_mem); 782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rela == NULL) 7833614d99198838a888005e923b36e8e0fbd5ec432Roland McGrath error (2, 0, gettext ("cannot get relocation: %s"), 784b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((int) GELF_R_SYM (rela->r_info) == symndx 787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info))) 788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 7964be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic int 797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperregioncompare (const void *p1, const void *p2) 798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const struct region *r1 = (const struct region *) p1; 800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const struct region *r2 = (const struct region *) p2; 801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 802b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (r1->from < r2->from) 803b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return -1; 804b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 805b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 8064be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8074be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8084be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic int 8094be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathcompare_Elf32_Word (const void *p1, const void *p2) 8104be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath{ 8114be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Elf32_Word *w1 = p1; 8124be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Elf32_Word *w2 = p2; 8134be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath assert (sizeof (int) >= sizeof (*w1)); 8144be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return (int) *w1 - (int) *w2; 8154be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath} 8164be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8174be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic int 8184be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathcompare_Elf64_Xword (const void *p1, const void *p2) 8194be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath{ 8204be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Elf64_Xword *w1 = p1; 8214be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Elf64_Xword *w2 = p2; 8224be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return *w1 < *w2 ? -1 : *w1 > *w2 ? 1 : 0; 8234be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath} 8244be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8254be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathstatic bool 8264be1524398af8e24011cfdfa77c66832f8654a56Roland McGrathhash_content_equivalent (size_t entsize, Elf_Data *data1, Elf_Data *data2) 8274be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath{ 8284be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath#define CHECK_HASH(Hash_Word) \ 8294be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { \ 8304be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const hash1 = data1->d_buf; \ 8314be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const hash2 = data2->d_buf; \ 8324be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const size_t nbucket = hash1[0]; \ 8334be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const size_t nchain = hash1[1]; \ 8344be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (data1->d_size != (2 + nbucket + nchain) * sizeof hash1[0] \ 8354be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath || hash2[0] != nbucket || hash2[1] != nchain) \ 8364be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8374be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8384be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const bucket1 = &hash1[2]; \ 8394be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const chain1 = &bucket1[nbucket]; \ 8404be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const bucket2 = &hash2[2]; \ 8414be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath const Hash_Word *const chain2 = &bucket2[nbucket]; \ 8424be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8434be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath bool chain_ok[nchain]; \ 8444be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath Hash_Word temp1[nchain - 1]; \ 8454be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath Hash_Word temp2[nchain - 1]; \ 8464be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath memset (chain_ok, 0, sizeof chain_ok); \ 8474be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (size_t i = 0; i < nbucket; ++i) \ 8484be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { \ 8494be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (bucket1[i] >= nchain || bucket2[i] >= nchain) \ 8504be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8514be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8524be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath size_t b1 = 0; \ 8534be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (size_t p = bucket1[i]; p != STN_UNDEF; p = chain1[p]) \ 8544be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (p >= nchain || b1 >= nchain - 1) \ 8554be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8564be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath else \ 8574be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath temp1[b1++] = p; \ 8584be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8594be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath size_t b2 = 0; \ 8604be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (size_t p = bucket2[i]; p != STN_UNDEF; p = chain2[p]) \ 8614be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (p >= nchain || b2 >= nchain - 1) \ 8624be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8634be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath else \ 8644be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath temp2[b2++] = p; \ 8654be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8664be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (b1 != b2) \ 8674be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8684be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8694be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath qsort (temp1, b1, sizeof temp1[0], compare_##Hash_Word); \ 8704be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath qsort (temp2, b2, sizeof temp2[0], compare_##Hash_Word); \ 8714be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8724be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (b1 = 0; b1 < b2; ++b1) \ 8734be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (temp1[b1] != temp2[b1]) \ 8744be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8754be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath else \ 8764be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath chain_ok[temp1[b1]] = true; \ 8774be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath } \ 8784be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8794be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath for (size_t i = 0; i < nchain; ++i) \ 8804be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath if (!chain_ok[i] && chain1[i] != chain2[i]) \ 8814be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; \ 8824be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath \ 8834be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return true; \ 8844be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath } 8854be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8864be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath switch (entsize) 8874be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { 8884be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath case 4: 8894be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath CHECK_HASH (Elf32_Word); 8904be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 8914be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath case 8: 8924be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath CHECK_HASH (Elf64_Xword); 8934be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 8944be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath } 8954be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 8964be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath return false; 8974be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath} 8983cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 8993cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 9003cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper#include "debugpred.h" 901