strip.c revision 1ccdfb683ad6c7e59793136c3a657ddf131cafd1
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Discard section not used at runtime from object files. 2587c4b3e94c6ef877137d067d5d0f574f69b1391Mark Wielaard Copyright (C) 2000-2012, 2014, 2015 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2000. 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. 10b08d5a8fb42f4586d756068065186b5af7e48daUlrich 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 <byteswap.h> 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <endian.h> 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h> 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <gelf.h> 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libelf.h> 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <locale.h> 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio_ext.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/param.h> 40b337b1fd5f3b3410fe522a690ccee70bce8519eeRoland McGrath#include <sys/stat.h> 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/time.h> 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <elf-knowledge.h> 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libebl.h> 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <system.h> 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 471662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaardtypedef uint8_t GElf_Byte; 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program. */ 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state); 51fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address. */ 54fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Values for the parameters which have no short form. */ 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define OPT_REMOVE_COMMENT 0x100 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define OPT_PERMISSIVE 0x101 600b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath#define OPT_STRIP_SECTIONS 0x102 611662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard#define OPT_RELOC_DEBUG 0x103 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions. */ 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] = 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Output selection:"), 0 }, 684be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { "output", 'o', "FILE", 0, N_("Place stripped output into FILE"), 0 }, 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE"), 0 }, 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 }, 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Output options:"), 0 }, 738f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath { "strip-all", 's', NULL, OPTION_HIDDEN, NULL, 0 }, 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 }, 758f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 }, 768f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 }, 770b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath { "strip-sections", OPT_STRIP_SECTIONS, NULL, 0, 780b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath N_("Remove section headers (not recommended)"), 0 }, 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "preserve-dates", 'p', NULL, 0, 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Copy modified/access timestamps to the output"), 0 }, 811662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { "reloc-debug-sections", OPT_RELOC_DEBUG, NULL, 0, 821662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard N_("Resolve all trivial relocations between debug sections if the removed sections are placed in a debug file (only relevant for ET_REL files, operation is not reversable, needs -f)"), 0 }, 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0, 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Remove .comment section"), 0 }, 858f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath { "remove-section", 'R', "SECTION", OPTION_HIDDEN, NULL, 0 }, 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "permissive", OPT_PERMISSIVE, NULL, 0, 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Relax a few rules to handle slightly broken ELF files"), 0 }, 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, NULL, 0 } 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program. */ 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("Discard symbols from object files."); 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts. */ 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("[FILE...]"); 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler. */ 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions. */ 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp = 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper options, parse_opt, args_doc, doc, NULL, NULL, NULL 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print symbols in file named FNAME. */ 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int process_file (const char *fname); 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle one ELF file. */ 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int handle_elf (int fd, Elf *elf, const char *prefix, 1128c4aa0ef998191ed828a37190dc179b91649938aMax Filippov const char *fname, mode_t mode, struct timespec tvp[2]); 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle all files contained in the archive. */ 115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, 116cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard struct timespec tvp[2]) __attribute__ ((unused)); 117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1186d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaardstatic int debug_fd = -1; 1196d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaardstatic char *tmp_debug_fname = NULL; 1206d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard 1216d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard/* Close debug file descriptor, if opened. And remove temporary debug file. */ 1221ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaardstatic void cleanup_debug (void); 1236d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define INTERNAL_ERROR(fname) \ 1256d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard do { \ 1266d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); \ 1276d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"), \ 1286d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)); \ 1296d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } while (0) 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name of the output file. */ 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char *output_fname; 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name of the debug output file. */ 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char *debug_fname; 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name to pretend the debug output file has. */ 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char *debug_fname_embed; 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If true output files shall have same date as the input file. */ 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool preserve_dates; 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If true .comment sections will be removed. */ 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool remove_comment; 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If true remove all debug sections. */ 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool remove_debug; 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1500b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath/* If true remove all section headers. */ 1510b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrathstatic bool remove_shdrs; 1520b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If true relax some ELF rules for input files. */ 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool permissive; 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1561662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard/* If true perform relocations between debug sections. */ 1571662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaardstatic bool reloc_debug; 1581662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[]) 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int remaining; 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = 0; 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We use no threads here which can interfere with handling a stream. */ 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __fsetlocking (stdin, FSETLOCKING_BYCALLER); 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __fsetlocking (stdout, FSETLOCKING_BYCALLER); 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __fsetlocking (stderr, FSETLOCKING_BYCALLER); 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set locale. */ 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper setlocale (LC_ALL, ""); 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the message catalog can be found. */ 175b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Initialize the message catalog. */ 178b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper textdomain (PACKAGE_TARNAME); 179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Parse and process arguments. */ 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0) 182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return EXIT_FAILURE; 183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1841662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (reloc_debug && debug_fname == NULL) 1851662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard error (EXIT_FAILURE, 0, 1861662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard gettext ("--reloc-debug-sections used without -f")); 1871662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Tell the library which version we are expecting. */ 189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_version (EV_CURRENT); 190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (remaining == argc) 192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The user didn't specify a name so we use a.out. */ 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = process_file ("a.out"); 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have seen the '-o' or '-f' option there must be exactly one 197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper input file. */ 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((output_fname != NULL || debug_fname != NULL) 199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && remaining + 1 < argc) 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (EXIT_FAILURE, 0, gettext ("\ 201b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperOnly one input file allowed together with '-o' and '-f'")); 202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Process all the remaining files. */ 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result |= process_file (argv[remaining]); 206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (++remaining < argc); 207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information. */ 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 217b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper fprintf (stream, "strip (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("\ 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCopyright (C) %s Red Hat, Inc.\n\ 220b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions. There is NO\n\ 221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 2223a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper"), "2012"); 223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments. */ 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 2291c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrathparse_opt (int key, char *arg, struct argp_state *state) 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'f': 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debug_fname != NULL) 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("-f option specified twice")); 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return EINVAL; 238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debug_fname = arg; 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'F': 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debug_fname_embed != NULL) 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("-F option specified twice")); 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return EINVAL; 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debug_fname_embed = arg; 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'o': 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (output_fname != NULL) 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("-o option specified twice")); 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return EINVAL; 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper output_fname = arg; 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'p': 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper preserve_dates = true; 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2641662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard case OPT_RELOC_DEBUG: 2651662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard reloc_debug = true; 2661662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard break; 2671662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case OPT_REMOVE_COMMENT: 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper remove_comment = true; 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2728f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath case 'R': 2738f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath if (!strcmp (arg, ".comment")) 2748f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath remove_comment = true; 2758f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath else 2768f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath { 2778f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath argp_error (state, 2788f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath gettext ("-R option supports only .comment section")); 2798f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath return EINVAL; 2808f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath } 2818f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath break; 2828f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'g': 2848f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath case 'd': 2858f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath case 'S': 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper remove_debug = true; 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2890b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath case OPT_STRIP_SECTIONS: 2900b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath remove_shdrs = true; 2910b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath break; 2920b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath 293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case OPT_PERMISSIVE: 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper permissive = true; 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2978f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath case 's': /* Ignored for compatibility. */ 2988f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath break; 2998f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprocess_file (const char *fname) 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have to preserve the modify and access timestamps get them 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper now. We cannot use fstat() after opening the file since the open 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper would change the access time. */ 313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct stat64 pre_st; 3148c4aa0ef998191ed828a37190dc179b91649938aMax Filippov struct timespec tv[2]; 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper again: 316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (preserve_dates) 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (stat64 (fname, &pre_st) != 0) 319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 320e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper error (0, errno, gettext ("cannot stat input file '%s'"), fname); 321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have to preserve the timestamp, we need it in the 325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper format utimes() understands. */ 3268c4aa0ef998191ed828a37190dc179b91649938aMax Filippov tv[0] = pre_st.st_atim; 3278c4aa0ef998191ed828a37190dc179b91649938aMax Filippov tv[1] = pre_st.st_mtim; 328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Open the file. */ 331095a01b14c2562a33615f079f300ac86da95bc56Roland McGrath int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY); 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fd == -1) 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 334e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper error (0, errno, gettext ("while opening '%s'"), fname); 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We always use fstat() even if we called stat() before. This is 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper done to make sure the information returned by stat() is for the 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper same file. */ 341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct stat64 st; 342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (fstat64 (fd, &st) != 0) 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 344e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper error (0, errno, gettext ("cannot stat input file '%s'"), fname); 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Paranoid mode on. */ 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (preserve_dates 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev)) 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We detected a race. Try again. */ 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto again; 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now get the ELF descriptor. */ 357095a01b14c2562a33615f079f300ac86da95bc56Roland McGrath Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ, 358095a01b14c2562a33615f079f300ac86da95bc56Roland McGrath NULL); 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result; 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (elf_kind (elf)) 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_ELF: 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS, 364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper preserve_dates ? tv : NULL); 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ELF_K_AR: 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* It is not possible to strip the content of an archive direct 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the output to a specific file. */ 3708190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath if (unlikely (output_fname != NULL || debug_fname != NULL)) 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 3728190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath error (0, 0, gettext ("%s: cannot use -o or -f when stripping archive"), 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname); 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 377cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard { 378cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard /* We would like to support ar archives, but currently it just 379cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard doesn't work at all since we call elf_clone on the members 380cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard which doesn't really support ar members. 381cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard result = handle_ar (fd, elf, NULL, fname, 382cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard preserve_dates ? tv : NULL); 383cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard */ 384cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard error (0, 0, gettext ("%s: no support for stripping archive"), 385cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard fname); 386cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard result = 1; 387cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard } 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s: File format not recognized"), fname); 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (elf_end (elf) != 0)) 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Maximum size of array allocated on stack. */ 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define MAX_STACK_ALLOC (400 * 1024) 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperhandle_elf (int fd, Elf *elf, const char *prefix, const char *fname, 4108c4aa0ef998191ed828a37190dc179b91649938aMax Filippov mode_t mode, struct timespec tvp[2]) 411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t fname_len = strlen (fname) + 1; 414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *fullname = alloca (prefix_len + 1 + fname_len); 415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = fullname; 416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *debugelf = NULL; 4176d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard tmp_debug_fname = NULL; 418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = 0; 419e219f1c1b2a5a2e4f248714fdc93d031cdc5ee6aUlrich Drepper size_t shdridx = 0; 420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t shstrndx; 421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct shdr_info 422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn; 424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Shdr shdr; 425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *data; 426521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf_Data *debug_data; 427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name; 428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word idx; /* Index in new file. */ 429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word old_sh_link; /* Original value of shdr.sh_link. */ 430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word symtab_idx; 431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word version_idx; 432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word group_idx; 433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word group_cnt; 434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *newscn; 435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct Ebl_Strent *se; 436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word *newsymidx; 437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } *shdr_info = NULL; 438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Scn *scn; 439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t cnt; 440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t idx; 441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool changes; 442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr newehdr_mem; 443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr *newehdr; 444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr debugehdr_mem; 445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Ehdr *debugehdr; 446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper struct Ebl_Strtab *shst = NULL; 447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data debuglink_crc_data; 448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool any_symtab_changes = false; 449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *shstrtab_data = NULL; 450a58951b183fb3e051870b19c95d8082a3efa3ddbMark Wielaard void *debuglink_buf = NULL; 451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the full name of the file. */ 453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, prefix, prefix_len); 456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = ':'; 457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (cp, fname, fname_len); 459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we are not replacing the input file open a new file here. */ 461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (output_fname != NULL) 462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fd = open (output_fname, O_RDWR | O_CREAT, mode); 464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (fd == -1)) 465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("cannot open '%s'"), output_fname); 467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4716d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard debug_fd = -1; 472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4731662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* Get the EBL handling. Removing all debugging symbols with the -g 4741662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard option or resolving all relocations between debug sections with 4751662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard the --reloc-debug-sections option are currently the only reasons 4766cbd7adf7eeb3f30632b53c8a68c470e0e47252bUlrich Drepper we need EBL so don't open the backend unless necessary. */ 477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Ebl *ebl = NULL; 4781662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (remove_debug || reloc_debug) 479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl = ebl_openbackend (elf); 481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ebl == NULL) 482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("cannot open EBL backend")); 484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail; 486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Open the additional file the debug information will be stored in. */ 490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debug_fname != NULL) 491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create a temporary file name. We do not want to overwrite 493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper the debug file if the file would not contain any 494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper information. */ 495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t debug_fname_len = strlen (debug_fname); 4966d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard tmp_debug_fname = (char *) xmalloc (debug_fname_len + sizeof (".XXXXXX")); 497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len), 498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ".XXXXXX"); 499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debug_fd = mkstemp (tmp_debug_fname); 501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (debug_fd == -1)) 502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("cannot open '%s'"), debug_fname); 504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail; 506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the information from the old file. */ 5101c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath GElf_Ehdr ehdr_mem; 5111c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr == NULL) 513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the section header string table index. */ 516f189493154d0041deced00e6a99cc5426dc9d260Ulrich Drepper if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0)) 5176d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 5186d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 5196d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, 5206d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard gettext ("cannot get section header string table index")); 5216d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 523712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard /* Get the number of phdrs in the old file. */ 524712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard size_t phnum; 525712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard if (elf_getphdrnum (elf, &phnum) != 0) 5266d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 5276d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 5286d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, gettext ("cannot get number of phdrs")); 5296d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 530712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard 531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We now create a new ELF descriptor for the same file. We 532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper construct it almost exactly in the same way with some information 533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper dropped. */ 5341c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Elf *newelf; 535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (output_fname != NULL) 536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL); 537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newelf = elf_clone (elf, ELF_C_EMPTY); 539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0) 541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (ehdr->e_type != ET_REL 542712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard && unlikely (gelf_newphdr (newelf, phnum) == 0))) 543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("cannot create new file '%s': %s"), 5456d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard output_fname ?: fname, elf_errmsg (-1)); 546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail; 547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Copy over the old program header if needed. */ 550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 551712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard for (cnt = 0; cnt < phnum; ++cnt) 552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 5541c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem); 555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr == NULL 556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0)) 557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debug_fname != NULL) 561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Also create an ELF descriptor for the debug file */ 563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL); 564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0) 565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (ehdr->e_type != ET_REL 566712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard && unlikely (gelf_newphdr (debugelf, phnum) == 0))) 567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("cannot create new file '%s': %s"), 569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debug_fname, elf_errmsg (-1)); 570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail_close; 571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Copy over the old program header if needed. */ 574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type != ET_REL) 575712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard for (cnt = 0; cnt < phnum; ++cnt) 576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Phdr phdr_mem; 5781c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem); 579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (phdr == NULL 580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0)) 581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Number of sections. */ 5861c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath size_t shnum; 587f189493154d0041deced00e6a99cc5426dc9d260Ulrich Drepper if (unlikely (elf_getshdrnum (elf, &shnum) < 0)) 588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("cannot determine number of sections: %s"), 590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail_close; 592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 59458d3619facfb708f4998d73270ca4082b20853b9Roland McGrath if (shstrndx >= shnum) 59558d3619facfb708f4998d73270ca4082b20853b9Roland McGrath goto illformed; 59658d3619facfb708f4998d73270ca4082b20853b9Roland McGrath 59758d3619facfb708f4998d73270ca4082b20853b9Roland McGrath#define elf_assert(test) do { if (!(test)) goto illformed; } while (0) 59858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath 599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Storage for section information. We leave room for two more 600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper entries since we unconditionally create a section header string 601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper table. Maybe some weird tool created an ELF file without one. 602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper The other one is used for the debug link section. */ 603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) 604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info = (struct shdr_info *) xcalloc (shnum + 2, 605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sizeof (struct shdr_info)); 606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info = (struct shdr_info *) alloca ((shnum + 2) 609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * sizeof (struct shdr_info)); 610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info)); 611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Prepare section information data structure. */ 614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scn = NULL; 615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt = 1; 616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((scn = elf_nextscn (elf, scn)) != NULL) 617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This should always be true (i.e., there should not be any 619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper holes in the numbering). */ 62058d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (elf_ndxscn (scn) == cnt); 621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].scn = scn; 623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the header. */ 625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL) 626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the name of the section. */ 629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].name = elf_strptr (elf, shstrndx, 630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_name); 631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].name == NULL) 632b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 63358d3619facfb708f4998d73270ca4082b20853b9Roland McGrath illformed: 634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("illformed file '%s'"), fname); 635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail_close; 636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Mark them as present but not yet investigated. */ 639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].idx = 1; 640b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Remember the shdr.sh_link value. */ 642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link; 64358d3619facfb708f4998d73270ca4082b20853b9Roland McGrath if (shdr_info[cnt].old_sh_link >= shnum) 64458d3619facfb708f4998d73270ca4082b20853b9Roland McGrath goto illformed; 645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Sections in files other than relocatable object files which 6476d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard don't contain any file content or are not loaded can be freely 6486d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard moved by us. In relocatable object files everything can be moved. */ 649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ehdr->e_type == ET_REL 6506d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard || shdr_info[cnt].shdr.sh_type == SHT_NOBITS 651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0) 652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_offset = 0; 653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If this is an extended section index table store an 655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper appropriate reference. */ 656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX)) 657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 65858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0); 659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt; 660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 661b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP)) 662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 663b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cross-reference the sections contained in the section 664b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper group. */ 665b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 6666d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (shdr_info[cnt].data == NULL 6676d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard || shdr_info[cnt].data->d_size < sizeof (Elf32_Word)) 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 669b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 670b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* XXX Fix for unaligned access. */ 6711c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; 6721c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath size_t inner; 673b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (inner = 1; 674b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++inner) 67658d3619facfb708f4998d73270ca4082b20853b9Roland McGrath { 67758d3619facfb708f4998d73270ca4082b20853b9Roland McGrath if (grpref[inner] < shnum) 67858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath shdr_info[grpref[inner]].group_idx = cnt; 67958d3619facfb708f4998d73270ca4082b20853b9Roland McGrath else 68058d3619facfb708f4998d73270ca4082b20853b9Roland McGrath goto illformed; 68158d3619facfb708f4998d73270ca4082b20853b9Roland McGrath } 682b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 683b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0)) 684b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If the section group contains only one element and this 685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper is n COMDAT section we can drop it right away. */ 686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].idx = 0; 687b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].group_cnt = inner - 1; 689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)) 691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 69258d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0); 693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt; 694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If this section is part of a group make sure it is not 697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper discarded right away. */ 698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0) 699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 70058d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (shdr_info[cnt].group_idx != 0); 701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[shdr_info[cnt].group_idx].idx == 0) 703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 704b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The section group section will be removed. */ 705b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].group_idx = 0; 706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP; 707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Increment the counter. */ 711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++cnt; 712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now determine which sections can go away. The general rule is that 715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper all sections which are not used at runtime are stripped out. But 716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper there are a few exceptions: 717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper - special sections named ".comment" and ".note" are kept 719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper - OS or architecture specific sections are kept since we might not 720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper know how to handle them 721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper - if a section is referred to from a section which is not removed 722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper in the sh_link or sh_info element it cannot be removed either 723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < shnum; ++cnt) 725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Check whether the section can be removed. */ 726f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath if (remove_shdrs ? !(shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) 727f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath : ebl_section_strip_p (ebl, ehdr, &shdr_info[cnt].shdr, 728f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath shdr_info[cnt].name, remove_comment, 729f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath remove_debug)) 730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* For now assume this section will be removed. */ 732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].idx = 0; 733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx = shdr_info[cnt].group_idx; 735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (idx != 0) 736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 737ce4550aefd57ab68f6f279a5b662eb1716d7b361Roland McGrath /* The section group data is already loaded. */ 7386d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shdr_info[idx].data != NULL 7396d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && shdr_info[idx].data->d_buf != NULL 7406d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && shdr_info[idx].data->d_size >= sizeof (Elf32_Word)); 741ce4550aefd57ab68f6f279a5b662eb1716d7b361Roland McGrath 7421c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath /* If the references section group is a normal section 7431c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath group and has one element remaining, or if it is an 7441c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath empty COMDAT section group it is removed. */ 7451c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0] 7461c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath & GRP_COMDAT) != 0; 747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper --shdr_info[idx].group_cnt; 749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((!is_comdat && shdr_info[idx].group_cnt == 1) 750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (is_comdat && shdr_info[idx].group_cnt == 0)) 751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[idx].idx = 0; 753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Continue recursively. */ 754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper idx = shdr_info[idx].group_idx; 755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Mark the SHT_NULL section as handled. */ 762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[0].idx = 2; 763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Handle exceptions: section groups and cross-references. We might 766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper have to repeat this a few times since the resetting of the flag 767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might propagate. */ 768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper changes = false; 771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < shnum; ++cnt) 773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].idx == 0) 775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If a relocation section is marked as being removed make 777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sure the section it is relocating is removed, too. */ 77858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath if (shdr_info[cnt].shdr.sh_type == SHT_REL 779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr_info[cnt].shdr.sh_type == SHT_RELA) 78058d3619facfb708f4998d73270ca4082b20853b9Roland McGrath { 78158d3619facfb708f4998d73270ca4082b20853b9Roland McGrath if (shdr_info[cnt].shdr.sh_info >= shnum) 78258d3619facfb708f4998d73270ca4082b20853b9Roland McGrath goto illformed; 78358d3619facfb708f4998d73270ca4082b20853b9Roland McGrath else if (shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0) 78458d3619facfb708f4998d73270ca4082b20853b9Roland McGrath shdr_info[cnt].idx = 1; 78558d3619facfb708f4998d73270ca4082b20853b9Roland McGrath } 7867a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard 7877a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard /* If a group section is marked as being removed make 7887a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard sure all the sections it contains are being removed, too. */ 7897a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) 7907a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard { 7917a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard Elf32_Word *grpref; 7927a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; 7937a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard for (size_t in = 1; 7947a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard in < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); 7957a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard ++in) 7966d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (grpref[in] < shnum) 7977a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard { 7986d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (shdr_info[grpref[in]].idx != 0) 7996d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 8006d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard shdr_info[cnt].idx = 1; 8016d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard break; 8026d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 8037a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard } 8046d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard else 8056d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard goto illformed; 8067a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard } 807b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 808b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].idx == 1) 810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The content of symbol tables we don't remove must not 812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reference any section which we do remove. Otherwise 813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper we cannot remove the section. */ 814521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (debug_fname != NULL 815521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath && shdr_info[cnt].debug_data == NULL 816521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath && (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM 817521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)) 818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the data is loaded. */ 820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].data == NULL) 821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].data 823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = elf_getdata (shdr_info[cnt].scn, NULL); 824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].data == NULL) 825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 8271c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Elf_Data *symdata = shdr_info[cnt].data; 828b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If there is an extended section index table load it 830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper as well. */ 831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].symtab_idx != 0 832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && shdr_info[shdr_info[cnt].symtab_idx].data == NULL) 833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 83458d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB); 835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[shdr_info[cnt].symtab_idx].data 837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, 838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NULL); 839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL) 840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 8421c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Elf_Data *xndxdata 8431c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath = shdr_info[shdr_info[cnt].symtab_idx].data; 844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 845b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Go through all symbols and make sure the section they 846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper reference is not removed. */ 847a2b964c7dbbf54162b2c50931c172568fb4cfa70Mark Wielaard size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); 848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t inner = 0; 850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper inner < shdr_info[cnt].data->d_size / elsize; 851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++inner) 852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym_mem; 854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xndx; 8551c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 8561c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath inner, &sym_mem, 8571c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath &xndx); 858b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 860b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 8611c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath size_t scnidx = sym->st_shndx; 862b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scnidx == SHN_UNDEF || scnidx >= shnum 863b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (scnidx >= SHN_LORESERVE 864b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && scnidx <= SHN_HIRESERVE 865b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && scnidx != SHN_XINDEX) 866b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Don't count in the section symbols. */ 867b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || GELF_ST_TYPE (sym->st_info) == STT_SECTION) 868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is no section index, leave it alone. */ 869b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 870b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (scnidx == SHN_XINDEX) 871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scnidx = xndx; 872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 87358d3619facfb708f4998d73270ca4082b20853b9Roland McGrath if (scnidx >= shnum) 87458d3619facfb708f4998d73270ca4082b20853b9Roland McGrath goto illformed; 87558d3619facfb708f4998d73270ca4082b20853b9Roland McGrath 876b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[scnidx].idx == 0) 877521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* This symbol table has a real symbol in 878521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath a discarded section. So preserve the 879521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath original table in the debug file. */ 880521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr_info[cnt].debug_data = symdata; 881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 882b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 883b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cross referencing happens: 885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper - for the cases the ELF specification says. That are 886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + SHT_DYNAMIC in sh_link to string table 887b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + SHT_HASH in sh_link to symbol table 888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + SHT_REL and SHT_RELA in sh_link to symbol table 889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table 890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + SHT_GROUP in sh_link to symbol table 891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + SHT_SYMTAB_SHNDX in sh_link to symbol table 892b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Other (OS or architecture-specific) sections might as 893b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper well use this field so we process it unconditionally. 894b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper - references inside section groups 895b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper - specially marked references in sh_info if the SHF_INFO_LINK 896b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper flag is set 897b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0) 900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1; 902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper changes |= shdr_info[cnt].shdr.sh_link < cnt; 903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Handle references through sh_info. */ 90658d3619facfb708f4998d73270ca4082b20853b9Roland McGrath if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) 907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 90858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath if (shdr_info[cnt].shdr.sh_info >= shnum) 90958d3619facfb708f4998d73270ca4082b20853b9Roland McGrath goto illformed; 91058d3619facfb708f4998d73270ca4082b20853b9Roland McGrath else if ( shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0) 91158d3619facfb708f4998d73270ca4082b20853b9Roland McGrath { 91258d3619facfb708f4998d73270ca4082b20853b9Roland McGrath shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1; 91358d3619facfb708f4998d73270ca4082b20853b9Roland McGrath changes |= shdr_info[cnt].shdr.sh_info < cnt; 91458d3619facfb708f4998d73270ca4082b20853b9Roland McGrath } 915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Mark the section as investigated. */ 918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].idx = 2; 919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 920521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 921521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (debug_fname != NULL 922521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath && (shdr_info[cnt].idx == 0 || shdr_info[cnt].debug_data != NULL)) 923521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 924521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* This section is being preserved in the debug file. 925521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Sections it refers to must be preserved there too. 926521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 927521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath In this pass we mark sections to be preserved in both 928521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath files by setting the .debug_data pointer to the original 929521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath file's .data pointer. Below, we'll copy the section 930521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath contents. */ 931521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 932521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath inline void check_preserved (size_t i) 933521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 9346d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (i != 0 && i < shnum + 2 && shdr_info[i].idx != 0 93504a14163323bc4d2d335909a2af7259bc53ddf8bRoland McGrath && shdr_info[i].debug_data == NULL) 936521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 937521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (shdr_info[i].data == NULL) 938521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL); 939521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (shdr_info[i].data == NULL) 940521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath INTERNAL_ERROR (fname); 941521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 942521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr_info[i].debug_data = shdr_info[i].data; 943521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath changes |= i < cnt; 944521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 945521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 946521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 947521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath check_preserved (shdr_info[cnt].shdr.sh_link); 948521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) 949521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath check_preserved (shdr_info[cnt].shdr.sh_info); 950521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 951b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (changes); 954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 955b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Copy the removed sections to the debug output file. 956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper The ones that are not removed in the stripped file are SHT_NOBITS. */ 957b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debug_fname != NULL) 958b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt < shnum; ++cnt) 960b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 961b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scn = elf_newscn (debugelf); 962b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (scn == NULL) 9636d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 9646d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 9656d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, 9666d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard gettext ("while generating output file: %s"), 9676d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_errmsg (-1)); 9686d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9701c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath bool discard_section = (shdr_info[cnt].idx > 0 971521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath && shdr_info[cnt].debug_data == NULL 9729aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath && shdr_info[cnt].shdr.sh_type != SHT_NOTE 9737a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard && shdr_info[cnt].shdr.sh_type != SHT_GROUP 9741c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath && cnt != ehdr->e_shstrndx); 975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set the section header in the new file. */ 9771c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath GElf_Shdr debugshdr = shdr_info[cnt].shdr; 978b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (discard_section) 979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugshdr.sh_type = SHT_NOBITS; 980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9813cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0)) 982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* There cannot be any overflows. */ 983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the data from the old file if necessary. */ 986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].data == NULL) 987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 988b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 989b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].data == NULL) 990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 991b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 992b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 993b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set the data. This is done by copying from the old file. */ 9941c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Elf_Data *debugdata = elf_newdata (scn); 995b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debugdata == NULL) 996b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 997b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 998b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Copy the structure. This data may be modified in place 999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper before we write out the file. */ 1000b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *debugdata = *shdr_info[cnt].data; 1001b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (discard_section) 1002b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugdata->d_buf = NULL; 10037a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard else if (shdr_info[cnt].debug_data != NULL 10047a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard || shdr_info[cnt].shdr.sh_type == SHT_GROUP) 1005521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1006521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Copy the original data before it gets modified. */ 1007521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr_info[cnt].debug_data = debugdata; 10086d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (debugdata->d_buf == NULL) 10096d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard INTERNAL_ERROR (fname); 1010521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath debugdata->d_buf = memcpy (xmalloc (debugdata->d_size), 1011521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath debugdata->d_buf, debugdata->d_size); 1012521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1013b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1014b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1015b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Finish the ELF header. Fill in the fields not handled by 1016b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper libelf from the old file. */ 1017b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugehdr = gelf_getehdr (debugelf, &debugehdr_mem); 1018b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debugehdr == NULL) 1019b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 1020b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1021b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT); 1022b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugehdr->e_type = ehdr->e_type; 1023b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugehdr->e_machine = ehdr->e_machine; 1024b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugehdr->e_version = ehdr->e_version; 1025b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugehdr->e_entry = ehdr->e_entry; 1026b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugehdr->e_flags = ehdr->e_flags; 1027b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debugehdr->e_shstrndx = ehdr->e_shstrndx; 1028b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 10293cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0)) 1030b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1031b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s: error while creating ELF header: %s"), 1032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debug_fname, elf_errmsg (-1)); 1033b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 1034b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail_close; 1035b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1036b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1037b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1038b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Mark the section header string table as unused, we will create 1039b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper a new one. */ 1040b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[shstrndx].idx = 0; 1041b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1042b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We need a string table for the section headers. */ 1043b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shst = ebl_strtabinit (true); 1044b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shst == NULL) 10456d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 10466d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 10476d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"), 10486d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard output_fname ?: fname); 10496d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 1050b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Assign new section numbers. */ 1052b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[0].idx = 0; 1053b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = idx = 1; cnt < shnum; ++cnt) 1054b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].idx > 0) 1055b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1056b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].idx = idx++; 1057b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create a new section. */ 1059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].newscn = elf_newscn (newelf); 1060b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].newscn == NULL) 10616d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 10626d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 10636d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, 10646d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard gettext ("while generating output file: %s"), 10656d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_errmsg (-1)); 10666d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 1067b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 106858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); 1069b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1070b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Add this name to the section header string table. */ 1071b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0); 1072b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1073b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1074b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Test whether we are doing anything at all. */ 1075b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt == idx) 1076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Nope, all removable sections are already gone. */ 1077b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail_close; 1078b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1079b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the reference to the file with the debug info. */ 1080f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath if (debug_fname != NULL && !remove_shdrs) 1081b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1082b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Add the section header string table section name. */ 1083b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15); 1084b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].idx = idx++; 1085b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1086b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the section header. */ 1087b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_type = SHT_PROGBITS; 1088b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_flags = 0; 1089b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_addr = 0; 1090b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_link = SHN_UNDEF; 1091b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_info = SHN_UNDEF; 1092b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_entsize = 0; 1093b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_addralign = 4; 1094b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We set the offset to zero here. Before we write the ELF file the 1095b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper field must have the correct value. This is done in the final 1096b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loop over all section. Then we have all the information needed. */ 1097b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_offset = 0; 1098b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1099b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the section. */ 1100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].newscn = elf_newscn (newelf); 1101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].newscn == NULL) 11026d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 11036d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 11046d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, 11056d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard gettext ("while create section header section: %s"), 11066d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_errmsg (-1)); 11076d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 110858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); 1109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn); 1111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].data == NULL) 11126d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 11136d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 11146d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"), 11156d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_errmsg (-1)); 11166d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 1117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 11181c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath char *debug_basename = basename (debug_fname_embed ?: debug_fname); 11191c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath off_t crc_offset = strlen (debug_basename) + 1; 1120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Align to 4 byte boundary */ 1121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper crc_offset = ((crc_offset - 1) & ~3) + 4; 1122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].data->d_align = 4; 1124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size 1125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = crc_offset + 4; 1126a58951b183fb3e051870b19c95d8082a3efa3ddbMark Wielaard debuglink_buf = xcalloc (1, shdr_info[cnt].data->d_size); 1127a58951b183fb3e051870b19c95d8082a3efa3ddbMark Wielaard shdr_info[cnt].data->d_buf = debuglink_buf; 1128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper strcpy (shdr_info[cnt].data->d_buf, debug_basename); 1130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Cache this Elf_Data describing the CRC32 word in the section. 1132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper We'll fill this in when we have written the debug file. */ 1133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debuglink_crc_data = *shdr_info[cnt].data; 1134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf 1135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + crc_offset); 1136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debuglink_crc_data.d_size = 4; 1137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* One more section done. */ 1139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++cnt; 1140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Index of the section header table in the shdr_info array. */ 1143e219f1c1b2a5a2e4f248714fdc93d031cdc5ee6aUlrich Drepper shdridx = cnt; 1144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Add the section header string table section name. */ 1146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10); 1147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].idx = idx; 1148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the section header. */ 1150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_type = SHT_STRTAB; 1151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_flags = 0; 1152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_addr = 0; 1153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_link = SHN_UNDEF; 1154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_info = SHN_UNDEF; 1155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_entsize = 0; 1156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We set the offset to zero here. Before we write the ELF file the 1157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper field must have the correct value. This is done in the final 1158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper loop over all section. Then we have all the information needed. */ 1159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_offset = 0; 1160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_addralign = 1; 1161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the section. */ 1163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].newscn = elf_newscn (newelf); 1164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].newscn == NULL) 11656d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 11666d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 11676d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, 11686d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard gettext ("while create section header section: %s"), 11696d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_errmsg (-1)); 11706d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 117158d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx); 1172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Finalize the string table and fill in the correct indices in the 1174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper section headers. */ 1175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shstrtab_data = elf_newdata (shdr_info[cnt].newscn); 1176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shstrtab_data == NULL) 11776d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 11786d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 11796d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, 11806d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard gettext ("while create section header string table: %s"), 11816d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_errmsg (-1)); 11826d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 1183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_strtabfinalize (shst, shstrtab_data); 1184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have to set the section size. */ 1186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size; 1187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Update the section information. */ 1189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Off lastoffset = 0; 1190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt <= shdridx; ++cnt) 1191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].idx > 0) 1192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *newdata; 1194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper scn = elf_getscn (newelf, shdr_info[cnt].idx); 11966d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (scn != NULL); 1197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Update the name. */ 1199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se); 1200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Update the section header from the input file. Some fields 1202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper might be section indeces which now have to be adjusted. */ 1203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].shdr.sh_link != 0) 1204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_link = 1205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[shdr_info[cnt].shdr.sh_link].idx; 1206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) 1208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 12096d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shdr_info[cnt].data != NULL 12106d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && shdr_info[cnt].data->d_buf != NULL); 1211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; 1213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (size_t inner = 0; 1214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); 1215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++inner) 12166d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (grpref[inner] < shnum) 12176d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard grpref[inner] = shdr_info[grpref[inner]].idx; 12186d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard else 12196d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard goto illformed; 1220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */ 1223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) 1224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_info = 1225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[shdr_info[cnt].shdr.sh_info].idx; 1226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the data from the old file if necessary. We already 12283a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper created the data for the section header string table. */ 1229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (cnt < shnum) 1230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].data == NULL) 1232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 1234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].data == NULL) 1235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 1236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set the data. This is done by copying from the old file. */ 1239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newdata = elf_newdata (scn); 1240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (newdata == NULL) 1241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 1242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Copy the structure. */ 1244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *newdata = *shdr_info[cnt].data; 1245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We know the size. */ 1247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size; 1248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1249521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* We have to adjust symbol tables. The st_shndx member might 1250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper have to be updated. */ 1251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM 1252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB) 1253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *versiondata = NULL; 1255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Data *shndxdata = NULL; 1256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1257a2b964c7dbbf54162b2c50931c172568fb4cfa70Mark Wielaard size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); 1258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].symtab_idx != 0) 1260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 12616d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX); 1262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This section has extended section information. 1263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper We have to modify that information, too. */ 1264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, 1265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NULL); 1266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 126758d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert ((versiondata->d_size / sizeof (Elf32_Word)) 12686d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard >= shdr_info[cnt].data->d_size / elsize); 1269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].version_idx != 0) 1272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 127358d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM); 1274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This section has associated version 1275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper information. We have to modify that 1276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper information, too. */ 1277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn, 1278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper NULL); 1279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 12806d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (versiondata != NULL 12816d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && versiondata->d_buf != NULL 12826d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && ((versiondata->d_size / sizeof (GElf_Versym)) 12836d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard >= shdr_info[cnt].data->d_size / elsize)); 1284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].newsymidx 1287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size 1288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper / elsize, sizeof (Elf32_Word)); 1289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bool last_was_local = true; 1291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t destidx; 1292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t inner; 1293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (destidx = inner = 1; 1294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper inner < shdr_info[cnt].data->d_size / elsize; 1295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ++inner) 1296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word sec; 1298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym sym_mem; 1299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word xshndx; 1300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data, 1301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shndxdata, inner, 1302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper &sym_mem, &xshndx); 1303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym == NULL) 1304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 1305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx == SHN_UNDEF 1307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (sym->st_shndx >= shnum 1308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && sym->st_shndx != SHN_XINDEX)) 1309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* This is no section index, leave it alone 1311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unless it is moved. */ 1312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (destidx != inner 1313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && gelf_update_symshndx (shdr_info[cnt].data, 1314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shndxdata, 1315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destidx, sym, 1316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper xshndx) == 0) 1317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 1318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].newsymidx[inner] = destidx++; 1320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (last_was_local 1322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 1323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper last_was_local = false; 1325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_info = destidx - 1; 1326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 1329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get the full section index, if necessary from the 1332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper XINDEX table. */ 1333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sym->st_shndx != SHN_XINDEX) 1334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sec = shdr_info[sym->st_shndx].idx; 1335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 13376d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shndxdata != NULL 13386d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && shndxdata->d_buf != NULL); 1339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper sec = shdr_info[xshndx].idx; 1341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sec != 0) 1344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Section nshndx; 1346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Word nxshndx; 1347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (sec < SHN_LORESERVE) 1349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper nshndx = sec; 1351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper nxshndx = 0; 1352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper nshndx = SHN_XINDEX; 1356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper nxshndx = sec; 1357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 135958d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (sec < SHN_LORESERVE || shndxdata != NULL); 1360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((inner != destidx || nshndx != sym->st_shndx 1362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || (shndxdata != NULL && nxshndx != xshndx)) 1363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && (sym->st_shndx = nshndx, 1364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper gelf_update_symshndx (shdr_info[cnt].data, 1365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shndxdata, 1366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper destidx, sym, 1367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper nxshndx) == 0)) 1368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 1369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].newsymidx[inner] = destidx++; 1371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (last_was_local 1373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 1374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper last_was_local = false; 1376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_info = destidx - 1; 1377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1379521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath else if (debug_fname == NULL 1380521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath || shdr_info[cnt].debug_data == NULL) 13817a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard /* This is a section or group signature symbol 13827a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard for a section which has been removed. */ 13837a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard { 13847a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard size_t sidx = (sym->st_shndx != SHN_XINDEX 13857a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard ? sym->st_shndx : xshndx); 138658d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION 138758d3619facfb708f4998d73270ca4082b20853b9Roland McGrath || ((shdr_info[sidx].shdr.sh_type 138858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath == SHT_GROUP) 138958d3619facfb708f4998d73270ca4082b20853b9Roland McGrath && (shdr_info[sidx].shdr.sh_info 139058d3619facfb708f4998d73270ca4082b20853b9Roland McGrath == inner))); 13917a125b9306c4743eaee062bdab301f890e3c6309Mark Wielaard } 1392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (destidx != inner) 1395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The size of the symbol table changed. */ 1397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_size = newdata->d_size 1398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = destidx * elsize; 1399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper any_symtab_changes = true; 1400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 1402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The symbol table didn't really change. */ 1404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (shdr_info[cnt].newsymidx); 1405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].newsymidx = NULL; 1406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If we have to, compute the offset of the section. */ 1411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info[cnt].shdr.sh_offset == 0) 1412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[cnt].shdr.sh_offset 1413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1) 1414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1))); 1415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set the section header in the new file. */ 1417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0)) 1418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* There cannot be any overflows. */ 1419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 1420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Remember the last section written so far. */ 1422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS 1423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ? shdr_info[cnt].shdr.sh_size : 0); 1424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz) 1425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper lastoffset = shdr_info[cnt].shdr.sh_offset + filesz; 1426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Adjust symbol references if symbol tables changed. */ 1429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (any_symtab_changes) 1430521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Find all relocation sections which use this symbol table. */ 1431521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath for (cnt = 1; cnt <= shdridx; ++cnt) 1432521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1433521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Update section headers when the data size has changed. 1434521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath We also update the SHT_NOBITS section in the debug 1435521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath file so that the section headers match in sh_size. */ 1436521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath inline void update_section_size (const Elf_Data *newdata) 1437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1438521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Shdr shdr_mem; 1439521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1440521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr->sh_size = newdata->d_size; 1441521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath (void) gelf_update_shdr (scn, shdr); 1442521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (debugelf != NULL) 14439aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath { 1444521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* libelf will use d_size to set sh_size. */ 1445521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf, 1446521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath cnt), NULL); 14476d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (debugdata == NULL) 14486d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard INTERNAL_ERROR (fname); 1449521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath debugdata->d_size = newdata->d_size; 14509aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath } 1451521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 14529aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath 1453521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (shdr_info[cnt].idx == 0 && debug_fname == NULL) 1454521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Ignore sections which are discarded. When we are saving a 1455521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath relocation section in a separate debug file, we must fix up 1456521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath the symbol table references. */ 1457521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath continue; 1458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1459521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath const Elf32_Word symtabidx = shdr_info[cnt].old_sh_link; 14606d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (symtabidx < shnum + 2); 1461521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx; 1462521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath switch (shdr_info[cnt].shdr.sh_type) 1463521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1464521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath inline bool no_symtab_updates (void) 1465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If the symbol table hasn't changed, do not do anything. */ 1467521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (shdr_info[symtabidx].newsymidx == NULL) 1468521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath return true; 1469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1470521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* If the symbol table is not discarded, but additionally 1471521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath duplicated in the separate debug file and this section 1472521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath is discarded, don't adjust anything. */ 1473521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath return (shdr_info[cnt].idx == 0 1474521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath && shdr_info[symtabidx].debug_data != NULL); 1475521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1477521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath case SHT_REL: 1478521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath case SHT_RELA: 1479521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (no_symtab_updates ()) 1480521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath break; 1481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1482521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0 1483521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath ? elf_getscn (debugelf, cnt) 1484521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath : elf_getscn (newelf, 1485521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr_info[cnt].idx), 1486521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath NULL); 14876d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (d != NULL && d->d_buf != NULL 14886d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && shdr_info[cnt].shdr.sh_entsize != 0); 1489521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath size_t nrels = (shdr_info[cnt].shdr.sh_size 1490521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath / shdr_info[cnt].shdr.sh_entsize); 1491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 14926d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard size_t symsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); 14936d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard const Elf32_Word symidxn = (shdr_info[symtabidx].data->d_size 14946d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard / symsize); 1495521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (shdr_info[cnt].shdr.sh_type == SHT_REL) 1496521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath for (size_t relidx = 0; relidx < nrels; ++relidx) 1497521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1498521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Rel rel_mem; 1499521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (gelf_getrel (d, relidx, &rel_mem) == NULL) 1500521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath INTERNAL_ERROR (fname); 1501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1502521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath size_t symidx = GELF_R_SYM (rel_mem.r_info); 15036d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (symidx < symidxn); 1504521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (newsymidx[symidx] != symidx) 1505521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1506521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath rel_mem.r_info 1507521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath = GELF_R_INFO (newsymidx[symidx], 1508521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GELF_R_TYPE (rel_mem.r_info)); 1509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1510521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (gelf_update_rel (d, relidx, &rel_mem) == 0) 1511521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath INTERNAL_ERROR (fname); 1512521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1513521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1514521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath else 1515521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath for (size_t relidx = 0; relidx < nrels; ++relidx) 1516521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1517521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Rela rel_mem; 1518521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (gelf_getrela (d, relidx, &rel_mem) == NULL) 1519521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath INTERNAL_ERROR (fname); 1520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1521521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath size_t symidx = GELF_R_SYM (rel_mem.r_info); 15226d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (symidx < symidxn); 1523521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (newsymidx[symidx] != symidx) 1524521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1525521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath rel_mem.r_info 1526521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath = GELF_R_INFO (newsymidx[symidx], 1527521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GELF_R_TYPE (rel_mem.r_info)); 1528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1529521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (gelf_update_rela (d, relidx, &rel_mem) == 0) 1530521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath INTERNAL_ERROR (fname); 1531521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1532521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1533521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath break; 1534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1535521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath case SHT_HASH: 1536521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (no_symtab_updates ()) 1537521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath break; 1538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1539521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* We have to recompute the hash table. */ 1540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 15416d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shdr_info[cnt].idx > 0); 1542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1543521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* The hash section in the new file. */ 1544521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath scn = elf_getscn (newelf, shdr_info[cnt].idx); 1545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1546521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* The symbol table data. */ 1547521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf_Data *symd = elf_getdata (elf_getscn (newelf, 1548521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr_info[symtabidx].idx), 1549521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath NULL); 15506d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (symd != NULL && symd->d_buf != NULL); 1551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1552521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* The hash table data. */ 1553521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf_Data *hashd = elf_getdata (scn, NULL); 15546d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (hashd != NULL && hashd->d_buf != NULL); 1555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1556521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word)) 1557521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1558521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Sane arches first. */ 15596d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (hashd->d_size >= 2 * sizeof (Elf32_Word)); 1560521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf; 1561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1562521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath size_t strshndx = shdr_info[symtabidx].old_sh_link; 1563a2b964c7dbbf54162b2c50931c172568fb4cfa70Mark Wielaard size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); 1564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 15656d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard Elf32_Word nchain = bucket[1]; 15666d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard Elf32_Word nbucket = bucket[0]; 15676d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard uint64_t used_buf = ((2ULL + nchain + nbucket) 15686d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard * sizeof (Elf32_Word)); 15696d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (used_buf <= hashd->d_size); 15706d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard 1571521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Adjust the nchain value. The symbol table size 1572521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath changed. We keep the same size for the bucket array. */ 1573521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath bucket[1] = symd->d_size / elsize; 1574521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath bucket += 2; 1575521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf32_Word *chain = bucket + nbucket; 1576521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1577521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* New size of the section. */ 15786d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard size_t n_size = ((2 + symd->d_size / elsize + nbucket) 1579521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath * sizeof (Elf32_Word)); 15806d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (n_size <= hashd->d_size); 15816d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard hashd->d_size = n_size; 1582521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath update_section_size (hashd); 1583521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1584521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Clear the arrays. */ 1585521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath memset (bucket, '\0', 1586521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath (symd->d_size / elsize + nbucket) 1587521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath * sizeof (Elf32_Word)); 1588521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1589521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath for (size_t inner = shdr_info[symtabidx].shdr.sh_info; 1590521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath inner < symd->d_size / elsize; ++inner) 1591521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1592521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Sym sym_mem; 1593521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); 159458d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (sym != NULL); 1595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1596521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath const char *name = elf_strptr (elf, strshndx, 1597521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath sym->st_name); 15986d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (name != NULL && nbucket != 0); 1599521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath size_t hidx = elf_hash (name) % nbucket; 1600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1601521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (bucket[hidx] == 0) 1602521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath bucket[hidx] = inner; 1603521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath else 1604521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1605521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath hidx = bucket[hidx]; 1606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 16076d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard while (chain[hidx] != 0 && chain[hidx] < nchain) 1608521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath hidx = chain[hidx]; 1609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1610521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath chain[hidx] = inner; 1611521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1612521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1613521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1614521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath else 1615521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1616521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */ 161758d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (shdr_info[cnt].shdr.sh_entsize 161858d3619facfb708f4998d73270ca4082b20853b9Roland McGrath == sizeof (Elf64_Xword)); 1619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1620521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf; 1621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1622521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath size_t strshndx = shdr_info[symtabidx].old_sh_link; 1623a2b964c7dbbf54162b2c50931c172568fb4cfa70Mark Wielaard size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); 1624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 16256d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (symd->d_size >= 2 * sizeof (Elf64_Xword)); 16266d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard Elf64_Xword nbucket = bucket[0]; 16276d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard Elf64_Xword nchain = bucket[1]; 16286d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard uint64_t maxwords = hashd->d_size / sizeof (Elf64_Xword); 16296d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (maxwords >= 2 16306d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && maxwords - 2 >= nbucket 16316d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard && maxwords - 2 - nbucket >= nchain); 16326d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard 1633521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Adjust the nchain value. The symbol table size 1634521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath changed. We keep the same size for the bucket array. */ 1635521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath bucket[1] = symd->d_size / elsize; 1636521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath bucket += 2; 1637521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf64_Xword *chain = bucket + nbucket; 1638521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1639521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* New size of the section. */ 16406d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard size_t n_size = ((2 + symd->d_size / elsize + nbucket) 1641521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath * sizeof (Elf64_Xword)); 16426d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (n_size <= hashd->d_size); 16436d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard hashd->d_size = n_size; 1644521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath update_section_size (hashd); 1645521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1646521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Clear the arrays. */ 1647521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath memset (bucket, '\0', 1648521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath (symd->d_size / elsize + nbucket) 1649521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath * sizeof (Elf64_Xword)); 1650521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1651521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath for (size_t inner = shdr_info[symtabidx].shdr.sh_info; 1652521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath inner < symd->d_size / elsize; ++inner) 1653521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1654521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Sym sym_mem; 1655521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); 165658d3619facfb708f4998d73270ca4082b20853b9Roland McGrath elf_assert (sym != NULL); 1657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1658521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath const char *name = elf_strptr (elf, strshndx, 1659521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath sym->st_name); 16606d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (name != NULL && nbucket != 0); 1661521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath size_t hidx = elf_hash (name) % nbucket; 1662b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1663521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (bucket[hidx] == 0) 1664521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath bucket[hidx] = inner; 1665521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath else 1666521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 1667521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath hidx = bucket[hidx]; 1668521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 16696d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard while (chain[hidx] != 0 && chain[hidx] < nchain) 1670521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath hidx = chain[hidx]; 1671521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1672521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath chain[hidx] = inner; 1673521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1674521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1675521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1676521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath break; 1677521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1678521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath case SHT_GNU_versym: 1679521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* If the symbol table changed we have to adjust the entries. */ 1680521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (no_symtab_updates ()) 1681521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath break; 1682521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 16836d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shdr_info[cnt].idx > 0); 1684521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1685521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* The symbol version section in the new file. */ 1686521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath scn = elf_getscn (newelf, shdr_info[cnt].idx); 1687521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1688521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* The symbol table data. */ 1689521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx), 1690521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath NULL); 16916d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (symd != NULL && symd->d_buf != NULL); 16926d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard size_t symz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); 16936d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard const Elf32_Word syms = (shdr_info[symtabidx].data->d_size / symz); 1694521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1695521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* The version symbol data. */ 1696521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Elf_Data *verd = elf_getdata (scn, NULL); 16976d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (verd != NULL && verd->d_buf != NULL); 1698521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1699521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* The symbol version array. */ 1700521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Half *verstab = (GElf_Half *) verd->d_buf; 1701521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1702521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Walk through the list and */ 1703a2b964c7dbbf54162b2c50931c172568fb4cfa70Mark Wielaard size_t elsize = gelf_fsize (elf, verd->d_type, 1, EV_CURRENT); 17046d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard Elf32_Word vers = verd->d_size / elsize; 17056d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard for (size_t inner = 1; inner < vers && inner < syms; ++inner) 17066d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (newsymidx[inner] != 0 && newsymidx[inner] < vers) 1707521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Overwriting the same array works since the 1708521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath reordering can only move entries to lower indices 1709521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath in the array. */ 1710521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath verstab[newsymidx[inner]] = verstab[inner]; 1711521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1712521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* New size of the section. */ 1713521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath verd->d_size = gelf_fsize (newelf, verd->d_type, 1714521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath symd->d_size 1715521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath / gelf_fsize (elf, symd->d_type, 1, 1716a2b964c7dbbf54162b2c50931c172568fb4cfa70Mark Wielaard EV_CURRENT), 1717a2b964c7dbbf54162b2c50931c172568fb4cfa70Mark Wielaard EV_CURRENT); 1718521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath update_section_size (verd); 1719521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath break; 1720521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1721521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath case SHT_GROUP: 1722521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (no_symtab_updates ()) 1723521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath break; 1724521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1725521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath /* Yes, the symbol table changed. 1726521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath Update the section header of the section group. */ 1727521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath scn = elf_getscn (newelf, shdr_info[cnt].idx); 1728521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Shdr shdr_mem; 1729521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 17306d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shdr != NULL); 1731521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 17326d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard size_t symsz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT); 17336d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard const Elf32_Word symn = (shdr_info[symtabidx].data->d_size 17346d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard / symsz); 17356d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shdr->sh_info < symn); 1736521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath shdr->sh_info = newsymidx[shdr->sh_info]; 1737521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath 1738521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath (void) gelf_update_shdr (scn, shdr); 1739521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath break; 1740521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1741521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 1742b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 17431662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* Remove any relocations between debug sections in ET_REL 17441662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard for the debug file when requested. These relocations are always 17451662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard zero based between the unallocated sections. */ 17461662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (debug_fname != NULL && reloc_debug && ehdr->e_type == ET_REL) 17471662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 17481662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard scn = NULL; 17491662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard cnt = 0; 17501662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard while ((scn = elf_nextscn (debugelf, scn)) != NULL) 17511662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 17521662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard cnt++; 17531662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* We need the actual section and header from the debugelf 17541662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard not just the cached original in shdr_info because we 17551662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard might want to change the size. */ 17561662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Shdr shdr_mem; 17571662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 17581662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) 17591662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 17601662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* Make sure that this relocation section points to a 17611662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard section to relocate with contents, that isn't 17621662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard allocated and that is a debug section. */ 17631662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard Elf_Scn *tscn = elf_getscn (debugelf, shdr->sh_info); 17641662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Shdr tshdr_mem; 17651662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem); 17661662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (tshdr->sh_type == SHT_NOBITS 17671662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard || tshdr->sh_size == 0 17681662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard || (tshdr->sh_flags & SHF_ALLOC) != 0) 17691662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard continue; 17701662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 17711662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard const char *tname = elf_strptr (debugelf, shstrndx, 17721662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard tshdr->sh_name); 17731662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (! tname || ! ebl_debugscn_p (ebl, tname)) 17741662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard continue; 17751662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 17761662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* OK, lets relocate all trivial cross debug section 17771662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard relocations. */ 17781662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard Elf_Data *reldata = elf_getdata (scn, NULL); 17796d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (reldata == NULL || reldata->d_buf == NULL) 17806d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard INTERNAL_ERROR (fname); 17811662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* We actually wanted the rawdata, but since we already 17821662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard accessed it earlier as elf_getdata () that won't 17831662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard work. But debug sections are all ELF_T_BYTE, so it 17841662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard doesn't really matter. */ 17851662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard Elf_Data *tdata = elf_getdata (tscn, NULL); 17866d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (tdata == NULL || tdata->d_buf == NULL 17876d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard || tdata->d_type != ELF_T_BYTE) 17881662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard INTERNAL_ERROR (fname); 17891662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 17901662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* Pick up the symbol table and shndx table to 17911662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard resolve relocation symbol indexes. */ 17921662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard Elf64_Word symt = shdr->sh_link; 17931662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard Elf_Data *symdata, *xndxdata; 17946d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (symt < shnum + 2); 17956d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard elf_assert (shdr_info[symt].symtab_idx < shnum + 2); 17961662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard symdata = (shdr_info[symt].debug_data 17971662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard ?: shdr_info[symt].data); 17981662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard xndxdata = (shdr_info[shdr_info[symt].symtab_idx].debug_data 17991662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard ?: shdr_info[shdr_info[symt].symtab_idx].data); 18001662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 18011662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* Apply one relocation. Returns true when trivial 18021662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard relocation actually done. */ 18031662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard bool relocate (GElf_Addr offset, const GElf_Sxword addend, 180463868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard bool is_rela, int rtype, int symndx) 18051662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 18061662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* R_*_NONE relocs can always just be removed. */ 18071662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (rtype == 0) 18081662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard return true; 18091662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 18101662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* We only do simple absolute relocations. */ 18111662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard Elf_Type type = ebl_reloc_simple_type (ebl, rtype); 18121662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (type == ELF_T_NUM) 18131662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard return false; 18141662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 18151662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* These are the types we can relocate. */ 18161662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard#define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \ 18171662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \ 18181662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword) 18191662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 18201662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* And only for relocations against other debug sections. */ 18211662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Sym sym_mem; 18221662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard Elf32_Word xndx; 18231662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 18241662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard symndx, &sym_mem, 18251662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard &xndx); 182663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard Elf32_Word sec = (sym->st_shndx == SHN_XINDEX 182763868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard ? xndx : sym->st_shndx); 18286d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (sec >= shnum + 2) 18296d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard INTERNAL_ERROR (fname); 18306d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard 183163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard if (ebl_debugscn_p (ebl, shdr_info[sec].name)) 18321662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 183363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard size_t size; 18341662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 18351662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard#define DO_TYPE(NAME, Name) GElf_##Name Name; 183663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard union { TYPES; } tmpbuf; 18371662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard#undef DO_TYPE 18381662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 183963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard switch (type) 184063868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard { 18411662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard#define DO_TYPE(NAME, Name) \ 184263868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard case ELF_T_##NAME: \ 184363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard size = sizeof (GElf_##Name); \ 184463868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard tmpbuf.Name = 0; \ 184563868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard break; 184663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard TYPES; 18471662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard#undef DO_TYPE 184863868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard default: 184963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard return false; 185063868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard } 185163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard 185202a958bc2662c1c9c2d6b663742b9c8e720e25b2Mark Wielaard if (offset > tdata->d_size 185302a958bc2662c1c9c2d6b663742b9c8e720e25b2Mark Wielaard || tdata->d_size - offset < size) 18546d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 18556d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 18566d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (EXIT_FAILURE, 0, gettext ("bad relocation")); 18576d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 18581662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 185963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard /* When the symbol value is zero then for SHT_REL 186063868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard sections this is all that needs to be checked. 186163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard The addend is contained in the original data at 186263868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard the offset already. So if the (section) symbol 186363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard address is zero and the given addend is zero 186463868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard just remove the relocation, it isn't needed 186563868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard anymore. */ 186663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard if (addend == 0 && sym->st_value == 0) 186763868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard return true; 186863868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard 186963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard Elf_Data tmpdata = 187063868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard { 187163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard .d_type = type, 187263868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard .d_buf = &tmpbuf, 187363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard .d_size = size, 187463868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard .d_version = EV_CURRENT, 187563868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard }; 187663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard Elf_Data rdata = 187763868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard { 187863868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard .d_type = type, 187963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard .d_buf = tdata->d_buf + offset, 188063868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard .d_size = size, 188163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard .d_version = EV_CURRENT, 188263868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard }; 188363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard 188463868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard GElf_Addr value = sym->st_value; 188563868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard if (is_rela) 188663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard { 188763868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard /* For SHT_RELA sections we just take the 188863868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard given addend and add it to the value. */ 188963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard value += addend; 189063868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard } 189163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard else 189263868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard { 189363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard /* For SHT_REL sections we have to peek at 189463868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard what is already in the section at the given 189563868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard offset to get the addend. */ 189663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard Elf_Data *d = gelf_xlatetom (debugelf, &tmpdata, 189763868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard &rdata, 18981662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard ehdr->e_ident[EI_DATA]); 189963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard if (d == NULL) 19001662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard INTERNAL_ERROR (fname); 190163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard assert (d == &tmpdata); 190263868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard } 19031662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 190463868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard switch (type) 190563868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard { 190663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard#define DO_TYPE(NAME, Name) \ 190763868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard case ELF_T_##NAME: \ 190863868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard tmpbuf.Name += (GElf_##Name) value; \ 190963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard break; 191063868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard TYPES; 191163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard#undef DO_TYPE 191263868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard default: 191363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard abort (); 19141662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 191563868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard 191663868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard /* Now finally put in the new value. */ 191763868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard Elf_Data *s = gelf_xlatetof (debugelf, &rdata, 191863868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard &tmpdata, 191963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard ehdr->e_ident[EI_DATA]); 192063868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard if (s == NULL) 192163868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard INTERNAL_ERROR (fname); 192263868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard assert (s == &rdata); 192363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard 192463868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard return true; 19251662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19261662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard return false; 19271662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19281662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 19296d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (shdr->sh_entsize == 0) 19306d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard INTERNAL_ERROR (fname); 19316d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard 19321662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard size_t nrels = shdr->sh_size / shdr->sh_entsize; 19331662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard size_t next = 0; 19341662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (shdr->sh_type == SHT_REL) 19351662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard for (size_t relidx = 0; relidx < nrels; ++relidx) 19361662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 19371662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Rel rel_mem; 19381662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem); 193963868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard if (! relocate (r->r_offset, 0, false, 19401662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GELF_R_TYPE (r->r_info), 19411662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GELF_R_SYM (r->r_info))) 19421662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 19431662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (relidx != next) 19441662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard gelf_update_rel (reldata, next, r); 19451662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard ++next; 19461662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19471662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19481662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard else 19491662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard for (size_t relidx = 0; relidx < nrels; ++relidx) 19501662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 19511662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Rela rela_mem; 19521662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem); 195363868c2afb1123bf8ac2f99048e6f3f70dcf4c0eMark Wielaard if (! relocate (r->r_offset, r->r_addend, true, 19541662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GELF_R_TYPE (r->r_info), 19551662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard GELF_R_SYM (r->r_info))) 19561662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard { 19571662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard if (relidx != next) 19581662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard gelf_update_rela (reldata, next, r); 19591662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard ++next; 19601662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19611662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19621662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 19631662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard nrels = next; 19641662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize; 19651662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard gelf_update_shdr (scn, shdr); 19661662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19671662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19681662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 19691662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 1970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now that we have done all adjustments to the data, 1971b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper we can actually write out the debug file. */ 1972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debug_fname != NULL) 1973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1974b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Finally write the file. */ 19753cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1)) 1976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1977b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("while writing '%s': %s"), 19786d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard tmp_debug_fname, elf_errmsg (-1)); 1979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 1980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail_close; 1981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the real output file. First rename, then change the 1984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper mode. */ 1985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (rename (tmp_debug_fname, debug_fname) != 0 1986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || fchmod (debug_fd, mode) != 0) 1987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1988b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("while creating '%s'"), debug_fname); 1989b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 1990b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto fail_close; 1991b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1992b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1993b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The temporary file does not exist anymore. */ 19946d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard free (tmp_debug_fname); 1995b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper tmp_debug_fname = NULL; 1996b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1997f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath if (!remove_shdrs) 1998b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1999f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath uint32_t debug_crc; 2000f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath Elf_Data debug_crc_data = 2001f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath { 2002f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath .d_type = ELF_T_WORD, 2003f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath .d_buf = &debug_crc, 2004f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath .d_size = sizeof (debug_crc), 2005f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath .d_version = EV_CURRENT 2006f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath }; 2007f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath 2008f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath /* Compute the checksum which we will add to the executable. */ 2009f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath if (crc32_file (debug_fd, &debug_crc) != 0) 2010f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath { 2011f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath error (0, errno, gettext ("\ 2012f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrathwhile computing checksum for debug information")); 2013f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath unlink (debug_fname); 2014f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath result = 1; 2015f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath goto fail_close; 2016f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath } 2017b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2018f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath /* Store it in the debuglink section data. */ 2019f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data, 2020f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath &debug_crc_data, ehdr->e_ident[EI_DATA]) 2021f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath != &debuglink_crc_data)) 2022f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath INTERNAL_ERROR (fname); 2023f151b7d4b103b6d07ac510833cb2550de064621cRoland McGrath } 2024b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2025b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2026b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Finally finish the ELF header. Fill in the fields not handled by 2027b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper libelf from the old file. */ 2028b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr = gelf_getehdr (newelf, &newehdr_mem); 2029b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (newehdr == NULL) 2030b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 2031b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT); 2033b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_type = ehdr->e_type; 2034b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_machine = ehdr->e_machine; 2035b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_version = ehdr->e_version; 2036b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_entry = ehdr->e_entry; 2037b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_flags = ehdr->e_flags; 2038b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_phoff = ehdr->e_phoff; 20390b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath 2040b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We need to position the section header table. */ 2041b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT); 2042b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset 2043b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper + shdr_info[shdridx].shdr.sh_size + offsize - 1) 2044b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper & ~((GElf_Off) (offsize - 1))); 2045b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT); 2046b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2047b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The new section header string table index. */ 2048b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX)) 2049b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_shstrndx = idx; 2050b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 2051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2052b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The index does not fit in the ELF header field. */ 2053b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[0].scn = elf_getscn (elf, 0); 2054b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2055b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL) 2056b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 2057b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2058b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper shdr_info[0].shdr.sh_link = idx; 2059b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr); 2060b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2061b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper newehdr->e_shstrndx = SHN_XINDEX; 2062b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2063b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2064b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (gelf_update_ehdr (newelf, newehdr) == 0) 2065b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2066b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s: error while creating ELF header: %s"), 20676d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard output_fname ?: fname, elf_errmsg (-1)); 20686d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 2069b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 2070b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2071b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2072b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We have everything from the old file. */ 2073b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_cntl (elf, ELF_C_FDDONE) != 0) 2074b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2075b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("%s: error while reading the file: %s"), 2076b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fname, elf_errmsg (-1)); 20776d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 2078b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 2079b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2080b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2081b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The ELF library better follows our layout when this is not a 2082b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper relocatable object file. */ 2083b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_flagelf (newelf, ELF_C_SET, 2084b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0) 2085b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper | (permissive ? ELF_F_PERMISSIVE : 0)); 2086b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2087b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Finally write the file. */ 2088b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_update (newelf, ELF_C_WRITE) == -1) 2089b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2090b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("while writing '%s': %s"), 20916d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard output_fname ?: fname, elf_errmsg (-1)); 2092b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 2093b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 20940b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath 20950b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath if (remove_shdrs) 20960b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath { 20970b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath /* libelf can't cope without the section headers being properly intact. 20980b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath So we just let it write them normally, and then we nuke them later. */ 20990b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath 21000b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath if (newehdr->e_ident[EI_CLASS] == ELFCLASS32) 21010b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath { 21020b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath assert (offsetof (Elf32_Ehdr, e_shentsize) + sizeof (Elf32_Half) 21030b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath == offsetof (Elf32_Ehdr, e_shnum)); 21040b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath assert (offsetof (Elf32_Ehdr, e_shnum) + sizeof (Elf32_Half) 21050b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath == offsetof (Elf32_Ehdr, e_shstrndx)); 21060b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath const Elf32_Off zero_off = 0; 21070b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath const Elf32_Half zero[3] = { 0, 0, SHN_UNDEF }; 21080b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath if (pwrite_retry (fd, &zero_off, sizeof zero_off, 21090b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath offsetof (Elf32_Ehdr, e_shoff)) != sizeof zero_off 21100b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath || (pwrite_retry (fd, zero, sizeof zero, 21110b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath offsetof (Elf32_Ehdr, e_shentsize)) 21120b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath != sizeof zero) 21130b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath || ftruncate64 (fd, shdr_info[shdridx].shdr.sh_offset) < 0) 21140b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath { 21150b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath error (0, errno, gettext ("while writing '%s'"), 21166d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard output_fname ?: fname); 21170b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath result = 1; 21180b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath } 21190b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath } 21200b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath else 21210b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath { 21220b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath assert (offsetof (Elf64_Ehdr, e_shentsize) + sizeof (Elf64_Half) 21230b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath == offsetof (Elf64_Ehdr, e_shnum)); 21240b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath assert (offsetof (Elf64_Ehdr, e_shnum) + sizeof (Elf64_Half) 21250b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath == offsetof (Elf64_Ehdr, e_shstrndx)); 21260b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath const Elf64_Off zero_off = 0; 21270b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath const Elf64_Half zero[3] = { 0, 0, SHN_UNDEF }; 21280b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath if (pwrite_retry (fd, &zero_off, sizeof zero_off, 21290b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath offsetof (Elf64_Ehdr, e_shoff)) != sizeof zero_off 21300b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath || (pwrite_retry (fd, zero, sizeof zero, 21310b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath offsetof (Elf64_Ehdr, e_shentsize)) 21320b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath != sizeof zero) 21330b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath || ftruncate64 (fd, shdr_info[shdridx].shdr.sh_offset) < 0) 21340b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath { 21350b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath error (0, errno, gettext ("while writing '%s'"), 21366d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard output_fname ?: fname); 21370b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath result = 1; 21380b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath } 21390b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath } 21400b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath } 2141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fail_close: 2143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shdr_info != NULL) 2144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* For some sections we might have created an table to map symbol 2146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper table indices. */ 2147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (any_symtab_changes) 2148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (cnt = 1; cnt <= shdridx; ++cnt) 2149521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath { 2150521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath free (shdr_info[cnt].newsymidx); 2151521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath if (shdr_info[cnt].debug_data != NULL) 2152521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath free (shdr_info[cnt].debug_data->d_buf); 2153521c47d2a216fc64098c024fc5ed53532b485f32Roland McGrath } 2154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2155a58951b183fb3e051870b19c95d8082a3efa3ddbMark Wielaard /* Free data we allocated for the .gnu_debuglink section. */ 2156a58951b183fb3e051870b19c95d8082a3efa3ddbMark Wielaard free (debuglink_buf); 2157a58951b183fb3e051870b19c95d8082a3efa3ddbMark Wielaard 2158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Free the memory. */ 2159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) 2160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (shdr_info); 2161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Free other resources. */ 2164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shstrtab_data != NULL) 2165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (shstrtab_data->d_buf); 2166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (shst != NULL) 2167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_strtabfree (shst); 2168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* That was it. Close the descriptors. */ 2170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_end (newelf) != 0) 2171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 21726d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard error (0, 0, gettext ("error while finishing '%s': %s"), 21736d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard output_fname ?: fname, elf_errmsg (-1)); 2174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 2175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (debugelf != NULL && elf_end (debugelf) != 0) 2178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname, 2180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper elf_errmsg (-1)); 2181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 2182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fail: 2185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Close the EBL backend. */ 2186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (ebl != NULL) 2187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ebl_closebackend (ebl); 2188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 21896d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard cleanup_debug (); 2190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* If requested, preserve the timestamp. */ 2192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (tvp != NULL) 2193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 21948c4aa0ef998191ed828a37190dc179b91649938aMax Filippov if (futimens (fd, tvp) != 0) 2195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("\ 2197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercannot set access and modification date of '%s'"), 2198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper output_fname ?: fname); 2199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 2200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Close the file descriptor if we created a new file. */ 2204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (output_fname != NULL) 2205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper close (fd); 2206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 2208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 2209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 22106d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaardstatic void 22111ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaardcleanup_debug (void) 22126d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard{ 22136d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (debug_fd >= 0) 22146d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 22156d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (tmp_debug_fname != NULL) 22166d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard { 22176d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard unlink (tmp_debug_fname); 22186d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard free (tmp_debug_fname); 22196d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard tmp_debug_fname = NULL; 22206d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 22216d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard close (debug_fd); 22226d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard debug_fd = -1; 22236d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 22246d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard} 2225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int 2227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperhandle_ar (int fd, Elf *elf, const char *prefix, const char *fname, 22288c4aa0ef998191ed828a37190dc179b91649938aMax Filippov struct timespec tvp[2]) 2229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 2230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 2231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t fname_len = strlen (fname) + 1; 2232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char new_prefix[prefix_len + 1 + fname_len]; 2233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = new_prefix; 2234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Create the full name of the file. */ 2236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (prefix != NULL) 2237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = mempcpy (cp, prefix, prefix_len); 2239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper *cp++ = ':'; 2240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy (cp, fname, fname_len); 2242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Process all the files contained in the archive. */ 2245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf *subelf; 2246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Cmd cmd = ELF_C_RDWR; 2247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = 0; 2248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 2249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* The the header for this element. */ 2251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf_Arhdr *arhdr = elf_getarhdr (subelf); 2252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (elf_kind (subelf) == ELF_K_ELF) 2254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL); 2255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else if (elf_kind (subelf) == ELF_K_AR) 2256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL); 2257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Get next archive element. */ 2259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cmd = elf_next (subelf); 2260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (elf_end (subelf) != 0)) 2261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper INTERNAL_ERROR (fname); 2262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (tvp != NULL) 2265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 22668c4aa0ef998191ed828a37190dc179b91649938aMax Filippov if (unlikely (futimens (fd, tvp) != 0)) 2267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (0, errno, gettext ("\ 2269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercannot set access and modification date of '%s'"), fname); 2270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper result = 1; 2271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (unlikely (close (fd) != 0)) 2275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname); 2276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 2278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 22793cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 22803cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 22813cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper#include "debugpred.h" 2282