125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Copyright (C) 2001-2011 Red Hat, Inc. 203333823c75a1c1887e923828113a1b0fd12020cElliott Hughes This file is part of elfutils. 325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Written by Ulrich Drepper <drepper@redhat.com>, 2001. 425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 503333823c75a1c1887e923828113a1b0fd12020cElliott Hughes This file is free software; you can redistribute it and/or modify 603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes it under the terms of the GNU General Public License as published by 703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes the Free Software Foundation; either version 3 of the License, or 803333823c75a1c1887e923828113a1b0fd12020cElliott Hughes (at your option) any later version. 925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1003333823c75a1c1887e923828113a1b0fd12020cElliott Hughes elfutils is distributed in the hope that it will be useful, but 1125b3c049e70834cf33790a28643ab058b507b35cBen Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 1203333823c75a1c1887e923828113a1b0fd12020cElliott Hughes MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1303333823c75a1c1887e923828113a1b0fd12020cElliott Hughes GNU General Public License for more details. 1425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1503333823c75a1c1887e923828113a1b0fd12020cElliott Hughes You should have received a copy of the GNU General Public License 1603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes along with this program. If not, see <http://www.gnu.org/licenses/>. */ 1725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef HAVE_CONFIG_H 1925b3c049e70834cf33790a28643ab058b507b35cBen Cheng# include <config.h> 2025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 2125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <assert.h> 2325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <ctype.h> 2425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <dlfcn.h> 2525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <errno.h> 2625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <error.h> 2725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <fcntl.h> 2825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <fnmatch.h> 2925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <gelf.h> 3025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <inttypes.h> 3125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libintl.h> 3225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdbool.h> 3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdio_ext.h> 3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdlib.h> 3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <string.h> 3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <unistd.h> 3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/param.h> 3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/stat.h> 3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <elf-knowledge.h> 4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "ld.h" 4225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "list.h" 4325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <md5.h> 4425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sha1.h> 4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <system.h> 4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Header of .eh_frame_hdr section. */ 4925b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct unw_eh_frame_hdr 5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 5125b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char version; 5225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char eh_frame_ptr_enc; 5325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char fde_count_enc; 5425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char table_enc; 5525b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 5625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define EH_FRAME_HDR_VERSION 1 5725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Prototypes for local functions. */ 6025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char **ld_generic_lib_extensions (struct ld_state *) 6125b3c049e70834cf33790a28643ab058b507b35cBen Cheng __attribute__ ((__const__)); 6225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int ld_generic_file_close (struct usedfiles *fileinfo, 6325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct ld_state *statep); 6425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int ld_generic_file_process (int fd, struct usedfiles *fileinfo, 6525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct ld_state *statep, 6625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles **nextp); 6725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_generate_sections (struct ld_state *statep); 6825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_create_sections (struct ld_state *statep); 6925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int ld_generic_flag_unresolved (struct ld_state *statep); 7025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int ld_generic_open_outfile (struct ld_state *statep, int machine, 7125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int class, int data); 7225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int ld_generic_create_outfile (struct ld_state *statep); 7325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_relocate_section (struct ld_state *statep, 7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *outscn, 7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *firstp, 7625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Elf32_Word *dblindirect); 7725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int ld_generic_finalize (struct ld_state *statep); 7825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool ld_generic_special_section_number_p (struct ld_state *statep, 7925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t number); 8025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool ld_generic_section_type_p (struct ld_state *statep, 8125b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Word type); 8225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic XElf_Xword ld_generic_dynamic_section_flags (struct ld_state *statep); 8325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_initialize_plt (struct ld_state *statep, Elf_Scn *scn); 8425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_initialize_pltrel (struct ld_state *statep, 8525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn); 8625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_initialize_got (struct ld_state *statep, Elf_Scn *scn); 8725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_initialize_gotplt (struct ld_state *statep, 8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn); 8925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_finalize_plt (struct ld_state *statep, size_t nsym, 9025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsym_dyn, 9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol **ndxtosymp); 9225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int ld_generic_rel_type (struct ld_state *statep); 9325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_count_relocations (struct ld_state *statep, 9425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *scninfo); 9525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void ld_generic_create_relocations (struct ld_state *statep, 9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Elf32_Word *dblindirect); 9725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int file_process2 (struct usedfiles *fileinfo); 9925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void mark_section_used (struct scninfo *scninfo, Elf32_Word shndx, 10025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo **grpscnp); 10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Map symbol index to struct symbol record. */ 10425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct symbol **ndxtosym; 10525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* String table reference to all symbols in the symbol table. */ 10725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct Ebl_Strent **symstrent; 10825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Check whether file associated with FD is a DSO. */ 11125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool 11225b3c049e70834cf33790a28643ab058b507b35cBen Chengis_dso_p (int fd) 11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 11425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to read the 'e_type' field. It has the same size (16 11525b3c049e70834cf33790a28643ab058b507b35cBen Cheng bits) in 32- and 64-bit ELF. */ 11625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Half e_type; 11725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return (pread (fd, &e_type, sizeof (e_type), offsetof (XElf_Ehdr, e_type)) 11925b3c049e70834cf33790a28643ab058b507b35cBen Cheng == sizeof (e_type) 12025b3c049e70834cf33790a28643ab058b507b35cBen Cheng && e_type == ET_DYN); 12125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 12225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the complete name of a file, including the archive it is 12525b3c049e70834cf33790a28643ab058b507b35cBen Cheng contained in. */ 12625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 12725b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_file_name (FILE *s, struct usedfiles *fileinfo, int first_level, 12825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int newline) 12925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 13025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int npar = 0; 13125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->archive_file != NULL) 13325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 13425b3c049e70834cf33790a28643ab058b507b35cBen Cheng npar = print_file_name (s, fileinfo->archive_file, 0, 0) + 1; 13525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked ('(', s); 13625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (fileinfo->rfname, s); 13725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first_level) 13925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (npar-- > 0) 14025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked (')', s); 14125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 14225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 14325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (fileinfo->rfname, s); 14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first_level && newline) 14625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputc_unlocked ('\n', s); 14725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return npar; 14925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 15025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Function to determine whether an object will be dynamically linked. */ 15325b3c049e70834cf33790a28643ab058b507b35cBen Chengbool 15425b3c049e70834cf33790a28643ab058b507b35cBen Chengdynamically_linked_p (void) 15525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return (ld_state.file_type == dso_file_type || ld_state.nplt > 0 15725b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ld_state.ngot > 0); 15825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 15925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16125b3c049e70834cf33790a28643ab058b507b35cBen Chengbool 16225b3c049e70834cf33790a28643ab058b507b35cBen Chenglinked_from_dso_p (struct scninfo *scninfo, size_t symidx) 16325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 16425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *file = scninfo->fileinfo; 16525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If this symbol is not undefined in this file it cannot come from 16725b3c049e70834cf33790a28643ab058b507b35cBen Cheng a DSO. */ 16825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symidx < file->nlocalsymbols) 16925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 17025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *sym = file->symref[symidx]; 17225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return sym->defined && sym->in_dso; 17425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 17525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Initialize state object. This callback function is called after the 17825b3c049e70834cf33790a28643ab058b507b35cBen Cheng parameters are parsed but before any file is searched for. */ 17925b3c049e70834cf33790a28643ab058b507b35cBen Chengint 18025b3c049e70834cf33790a28643ab058b507b35cBen Chengld_prepare_state (const char *emulation) 18125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 18225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When generating DSO we normally allow undefined symbols. */ 18325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.nodefs = true; 18425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* To be able to detect problems we add a .comment section entry by 18625b3c049e70834cf33790a28643ab058b507b35cBen Cheng default. */ 18725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.add_ld_comment = true; 18825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX We probably should find a better place for this. The index 19025b3c049e70834cf33790a28643ab058b507b35cBen Cheng of the first user-defined version is 2. */ 19125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.nextveridx = 2; 19225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 19325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Pick an not too small number for the initial size of the tables. */ 19425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_symbol_tab_init (&ld_state.symbol_tab, 1027); 19525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_section_tab_init (&ld_state.section_tab, 67); 19625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_version_str_tab_init (&ld_state.version_str_tab, 67); 19725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 19825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Initialize the section header string table. */ 19925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.shstrtab = ebl_strtabinit (true); 20025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.shstrtab == NULL) 20125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("cannot create string table")); 20225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Initialize the callbacks. These are the defaults, the appropriate 20425b3c049e70834cf33790a28643ab058b507b35cBen Cheng backend can later install its own callbacks. */ 20525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.lib_extensions = ld_generic_lib_extensions; 20625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.file_process = ld_generic_file_process; 20725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.file_close = ld_generic_file_close; 20825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.generate_sections = ld_generic_generate_sections; 20925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.create_sections = ld_generic_create_sections; 21025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.flag_unresolved = ld_generic_flag_unresolved; 21125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.open_outfile = ld_generic_open_outfile; 21225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.create_outfile = ld_generic_create_outfile; 21325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.relocate_section = ld_generic_relocate_section; 21425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.finalize = ld_generic_finalize; 21525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.special_section_number_p = 21625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_generic_special_section_number_p; 21725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.section_type_p = ld_generic_section_type_p; 21825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.dynamic_section_flags = ld_generic_dynamic_section_flags; 21925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.initialize_plt = ld_generic_initialize_plt; 22025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.initialize_pltrel = ld_generic_initialize_pltrel; 22125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.initialize_got = ld_generic_initialize_got; 22225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.initialize_gotplt = ld_generic_initialize_gotplt; 22325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.finalize_plt = ld_generic_finalize_plt; 22425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.rel_type = ld_generic_rel_type; 22525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.count_relocations = ld_generic_count_relocations; 22625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.callbacks.create_relocations = ld_generic_create_relocations; 22725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef BASE_ELF_NAME 22925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the ld backend library. Use EBL to determine the name if 23025b3c049e70834cf33790a28643ab058b507b35cBen Cheng the user hasn't provided one on the command line. */ 23125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (emulation == NULL) 23225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 23325b3c049e70834cf33790a28643ab058b507b35cBen Cheng emulation = ebl_backend_name (ld_state.ebl); 23425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (emulation != NULL); 23525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 23625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t emulation_len = strlen (emulation); 23725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Construct the file name. */ 23925b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *fname = (char *) alloca (sizeof "libld_" - 1 + emulation_len 24025b3c049e70834cf33790a28643ab058b507b35cBen Cheng + sizeof ".so"); 24125b3c049e70834cf33790a28643ab058b507b35cBen Cheng strcpy (mempcpy (stpcpy (fname, "libld_"), emulation, emulation_len), ".so"); 24225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 24325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Try loading. */ 24425b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *h = dlopen (fname, RTLD_LAZY); 24525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (h == NULL) 24625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 24725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot load ld backend library '%s': %s"), 24825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname, dlerror ()); 24925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the initializer. It must be present. */ 25125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *initname = (char *) alloca (emulation_len + sizeof "_ld_init"); 25225b3c049e70834cf33790a28643ab058b507b35cBen Cheng strcpy (mempcpy (initname, emulation, emulation_len), "_ld_init"); 25325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int (*initfct) (struct ld_state *) 25425b3c049e70834cf33790a28643ab058b507b35cBen Cheng = (int (*) (struct ld_state *)) dlsym (h, initname); 25525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (initfct == NULL) 25725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 25825b3c049e70834cf33790a28643ab058b507b35cBen Chengcannot find init function in ld backend library '%s': %s"), 25925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname, dlerror ()); 26025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the handle. */ 26225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.ldlib = h; 26325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Call the init function. */ 26525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return initfct (&ld_state); 26625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 26725b3c049e70834cf33790a28643ab058b507b35cBen Cheng# define INIT_FCT_NAME(base) _INIT_FCT_NAME(base) 26825b3c049e70834cf33790a28643ab058b507b35cBen Cheng# define _INIT_FCT_NAME(base) base##_ld_init 26925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Declare and call the initialization function. */ 27025b3c049e70834cf33790a28643ab058b507b35cBen Cheng extern int INIT_FCT_NAME(BASE_ELF_NAME) (struct ld_state *); 27125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return INIT_FCT_NAME(BASE_ELF_NAME) (&ld_state); 27225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 27325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 27425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 27725b3c049e70834cf33790a28643ab058b507b35cBen Chengcheck_for_duplicate2 (struct usedfiles *newp, struct usedfiles *list) 27825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 27925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *first; 28025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (list == NULL) 28225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 28325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28425b3c049e70834cf33790a28643ab058b507b35cBen Cheng list = first = list->next; 28525b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 28625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 28725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When searching the needed list we might come across entries 28825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for files which are not yet opened. Stop then, there is 28925b3c049e70834cf33790a28643ab058b507b35cBen Cheng nothing more to test. */ 29025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (list->status == not_opened)) 29125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 29225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 29325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (list->ino == newp->ino) 29425b3c049e70834cf33790a28643ab058b507b35cBen Cheng && unlikely (list->dev == newp->dev)) 29525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 29625b3c049e70834cf33790a28643ab058b507b35cBen Cheng close (newp->fd); 29725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->fd = -1; 29825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->status = closed; 29925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (newp->file_type == relocatable_file_type) 30025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("%s listed more than once as input"), 30125b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->rfname); 30225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 30325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 30425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 30525b3c049e70834cf33790a28643ab058b507b35cBen Cheng list = list->next; 30625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 30725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (likely (list != first)); 30825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 30925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 31025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 31125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 31225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 31325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 31425b3c049e70834cf33790a28643ab058b507b35cBen Chengcheck_for_duplicate (struct usedfiles *newp) 31525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 31625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct stat st; 31725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 31825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (fstat (newp->fd, &st) < 0)) 31925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 32025b3c049e70834cf33790a28643ab058b507b35cBen Cheng close (newp->fd); 32125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return errno; 32225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 32325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 32425b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->dev = st.st_dev; 32525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->ino = st.st_ino; 32625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 32725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return (check_for_duplicate2 (newp, ld_state.relfiles) 32825b3c049e70834cf33790a28643ab058b507b35cBen Cheng || check_for_duplicate2 (newp, ld_state.dsofiles) 32925b3c049e70834cf33790a28643ab058b507b35cBen Cheng || check_for_duplicate2 (newp, ld_state.needed)); 33025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 33125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 33225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 33325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Find a file along the path described in the state. */ 33425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 33525b3c049e70834cf33790a28643ab058b507b35cBen Chengopen_along_path2 (struct usedfiles *fileinfo, struct pathelement *path) 33625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 33725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *fname = fileinfo->fname; 33825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t fnamelen = strlen (fname); 33925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int err = ENOENT; 34025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct pathelement *firstp = path; 34125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 34225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (path == NULL) 34325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Cannot find anything since we have no path. */ 34425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ENOENT; 34525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 34625b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 34725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 34825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (path->exist >= 0)) 34925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 35025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the file name. */ 35125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *rfname = NULL; 35225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t dirlen = strlen (path->pname); 35325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int fd = -1; 35425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 35525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->file_type == archive_file_type) 35625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 35725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char **exts = (ld_state.statically 35825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? (const char *[2]) { ".a", NULL } 35925b3c049e70834cf33790a28643ab058b507b35cBen Cheng : LIB_EXTENSION (&ld_state)); 36025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 36125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to create the actual file name. We prepend "lib" 36225b3c049e70834cf33790a28643ab058b507b35cBen Cheng and add one of the extensions the platform has. */ 36325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (*exts != NULL) 36425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 36525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t extlen = strlen (*exts); 36625b3c049e70834cf33790a28643ab058b507b35cBen Cheng rfname = (char *) alloca (dirlen + 5 + fnamelen + extlen); 36725b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (mempcpy (stpcpy (mempcpy (rfname, path->pname, 36825b3c049e70834cf33790a28643ab058b507b35cBen Cheng dirlen), 36925b3c049e70834cf33790a28643ab058b507b35cBen Cheng "/lib"), 37025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname, fnamelen), 37125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *exts, extlen + 1); 37225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 37325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fd = open (rfname, O_RDONLY); 37425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fd != -1) || errno != ENOENT) 37525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 37625b3c049e70834cf33790a28643ab058b507b35cBen Cheng err = fd == -1 ? errno : 0; 37725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 37825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 37925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 38025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Next extension. */ 38125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++exts; 38225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 38325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 38425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 38525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 38625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fileinfo->file_type == dso_file_type 38725b3c049e70834cf33790a28643ab058b507b35cBen Cheng || fileinfo->file_type == dso_needed_file_type); 38825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 38925b3c049e70834cf33790a28643ab058b507b35cBen Cheng rfname = (char *) alloca (dirlen + 1 + fnamelen + 1); 39025b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (stpcpy (mempcpy (rfname, path->pname, dirlen), "/"), 39125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fname, fnamelen + 1); 39225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 39325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fd = open (rfname, O_RDONLY); 39425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (fd == -1)) 39525b3c049e70834cf33790a28643ab058b507b35cBen Cheng err = errno; 39625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 39725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 39825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fd != -1)) 39925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 40025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We found the file. This also means the directory 40125b3c049e70834cf33790a28643ab058b507b35cBen Cheng exists. */ 40225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fd = fd; 40325b3c049e70834cf33790a28643ab058b507b35cBen Cheng path->exist = 1; 40425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 40525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether we have this file already loaded. */ 40625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (check_for_duplicate (fileinfo) != 0)) 40725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return EAGAIN; 40825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 40925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make a copy of the name. */ 41025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname = obstack_strdup (&ld_state.smem, rfname); 41125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 41225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_state.trace_files)) 41325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (fileinfo->file_type == archive_file_type 41425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? gettext ("%s (for -l%s)\n") 41525b3c049e70834cf33790a28643ab058b507b35cBen Cheng : gettext ("%s (for DT_NEEDED %s)\n"), 41625b3c049e70834cf33790a28643ab058b507b35cBen Cheng rfname, fname); 41725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 41825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 41925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 42025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 42125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The file does not exist. Maybe the whole directory doesn't. 42225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Check it unless we know it exists. */ 42325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (path->exist == 0)) 42425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 42525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct stat st; 42625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 42725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Keep only the directory name. Note that the path 42825b3c049e70834cf33790a28643ab058b507b35cBen Cheng might be relative. This doesn't matter here. We do 42925b3c049e70834cf33790a28643ab058b507b35cBen Cheng the test in any case even if there is the chance that 43025b3c049e70834cf33790a28643ab058b507b35cBen Cheng somebody wants to change the programs working 43125b3c049e70834cf33790a28643ab058b507b35cBen Cheng directory at some point which would make the result 43225b3c049e70834cf33790a28643ab058b507b35cBen Cheng of this test void. Since changing the working 43325b3c049e70834cf33790a28643ab058b507b35cBen Cheng directory is completely wrong we are not taking this 43425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case into account. */ 43525b3c049e70834cf33790a28643ab058b507b35cBen Cheng rfname[dirlen] = '\0'; 43625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (stat (rfname, &st) < 0) || ! S_ISDIR (st.st_mode)) 43725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The directory does not exist or the named file is no 43825b3c049e70834cf33790a28643ab058b507b35cBen Cheng directory. */ 43925b3c049e70834cf33790a28643ab058b507b35cBen Cheng path->exist = -1; 44025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 44125b3c049e70834cf33790a28643ab058b507b35cBen Cheng path->exist = 1; 44225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 44525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Next path element. */ 44625b3c049e70834cf33790a28643ab058b507b35cBen Cheng path = path->next; 44725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (likely (err == ENOENT && path != firstp)); 44925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 45025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return err; 45125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 45225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 45325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 45425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 45525b3c049e70834cf33790a28643ab058b507b35cBen Chengopen_along_path (struct usedfiles *fileinfo) 45625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 45725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *fname = fileinfo->fname; 45825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int err = ENOENT; 45925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 46025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->file_type == relocatable_file_type) 46125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 46225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Only libraries are searched along the path. */ 46325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fd = open (fname, O_RDONLY); 46425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 46525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fileinfo->fd != -1)) 46625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 46725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We found the file. */ 46825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_state.trace_files)) 46925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_name (stdout, fileinfo, 1, 1); 47025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 47125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return check_for_duplicate (fileinfo); 47225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 47325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 47425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the name is an absolute path we are done. */ 47525b3c049e70834cf33790a28643ab058b507b35cBen Cheng err = errno; 47625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 47725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 47825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 47925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the user specified two parts to the LD_LIBRARY_PATH variable 48025b3c049e70834cf33790a28643ab058b507b35cBen Cheng try the first part now. */ 48125b3c049e70834cf33790a28643ab058b507b35cBen Cheng err = open_along_path2 (fileinfo, ld_state.ld_library_path1); 48225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 48325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Try the user-specified path next. */ 48425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (err == ENOENT) 48525b3c049e70834cf33790a28643ab058b507b35cBen Cheng err = open_along_path2 (fileinfo, 48625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->file_type == archive_file_type 48725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ld_state.paths : ld_state.rpath_link); 48825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 48925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Then the second part of the LD_LIBRARY_PATH value. */ 49025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (err == ENOENT)) 49125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 49225b3c049e70834cf33790a28643ab058b507b35cBen Cheng err = open_along_path2 (fileinfo, ld_state.ld_library_path2); 49325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 49425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* In case we look for a DSO handle now the RUNPATH. */ 49525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (err == ENOENT) 49625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 49725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->file_type == dso_file_type) 49825b3c049e70834cf33790a28643ab058b507b35cBen Cheng err = open_along_path2 (fileinfo, ld_state.runpath_link); 49925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 50025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Finally the path from the default linker script. */ 50125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (err == ENOENT) 50225b3c049e70834cf33790a28643ab058b507b35cBen Cheng err = open_along_path2 (fileinfo, ld_state.default_paths); 50325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 50425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 50525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 50625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 50725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (err != 0) 50825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (err != EAGAIN || fileinfo->file_type == relocatable_file_type)) 50925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, err, gettext ("cannot open %s"), fileinfo->fname); 51025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 51125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return err; 51225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 51325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 51425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 51525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 51625b3c049e70834cf33790a28643ab058b507b35cBen Chengmatching_group_comdat_scn (const XElf_Sym *sym, size_t shndx, 51725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *fileinfo, struct symbol *oldp) 51825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 51925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((shndx >= SHN_LORESERVE && shndx <= SHN_HIRESERVE) 52025b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (oldp->scndx >= SHN_LORESERVE && oldp->scndx <= SHN_HIRESERVE)) 52125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Cannot be a group COMDAT section. */ 52225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 52325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 52425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t newgrpid = fileinfo->scninfo[shndx].grpid; 52525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t oldgrpid = oldp->file->scninfo[oldp->scndx].grpid; 52625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (newgrpid == 0 || oldgrpid == 0) 52725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 52825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 52925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (SCNINFO_SHDR (fileinfo->scninfo[newgrpid].shdr).sh_type 53025b3c049e70834cf33790a28643ab058b507b35cBen Cheng == SHT_GROUP); 53125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (SCNINFO_SHDR (oldp->file->scninfo[oldgrpid].shdr).sh_type 53225b3c049e70834cf33790a28643ab058b507b35cBen Cheng == SHT_GROUP); 53325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 53425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! fileinfo->scninfo[newgrpid].comdat_group 53525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ! oldp->file->scninfo[oldgrpid].comdat_group) 53625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 53725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 53825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (fileinfo->scninfo[newgrpid].symbols->name, 53925b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->file->scninfo[oldgrpid].symbols->name) != 0) 54025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 54125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 54225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is a matching, duplicate COMDAT group section. Ignore it. */ 54325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 54425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 54525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 54625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 54725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 54825b3c049e70834cf33790a28643ab058b507b35cBen Chengcheck_type_and_size (const XElf_Sym *sym, struct usedfiles *fileinfo, 54925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *oldp) 55025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 55125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We check the type and size of the symbols. In both cases the 55225b3c049e70834cf33790a28643ab058b507b35cBen Cheng information can be missing (size is zero, type is STT_NOTYPE) in 55325b3c049e70834cf33790a28643ab058b507b35cBen Cheng which case we issue no warnings. Otherwise everything must 55425b3c049e70834cf33790a28643ab058b507b35cBen Cheng match. If the type does not match there is no point in checking 55525b3c049e70834cf33790a28643ab058b507b35cBen Cheng the size. */ 55625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 55725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (XELF_ST_TYPE (sym->st_info) != STT_NOTYPE && oldp->type != STT_NOTYPE 55825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && unlikely (oldp->type != XELF_ST_TYPE (sym->st_info))) 55925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 56025b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf1[64]; 56125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf2[64]; 56225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 56325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("\ 56425b3c049e70834cf33790a28643ab058b507b35cBen ChengWarning: type of `%s' changed from %s in %s to %s in %s"), 56525b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->name, 56625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_symbol_type_name (ld_state.ebl, oldp->type, 56725b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf1, sizeof (buf1)), 56825b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->file->rfname, 56925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_symbol_type_name (ld_state.ebl, XELF_ST_TYPE (sym->st_info), 57025b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf2, sizeof (buf2)), 57125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname); 57225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 57325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (XELF_ST_TYPE (sym->st_info) == STT_OBJECT 57425b3c049e70834cf33790a28643ab058b507b35cBen Cheng && oldp->size != 0 57525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && unlikely (oldp->size != sym->st_size)) 57625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("\ 57725b3c049e70834cf33790a28643ab058b507b35cBen ChengWarning: size of `%s' changed from %" PRIu64 " in %s to %" PRIu64 " in %s"), 57825b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->name, (uint64_t) oldp->size, oldp->file->rfname, 57925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) sym->st_size, fileinfo->rfname); 58025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 58125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 58225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 58325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 58425b3c049e70834cf33790a28643ab058b507b35cBen Chengcheck_definition (const XElf_Sym *sym, size_t shndx, size_t symidx, 58525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *fileinfo, struct symbol *oldp) 58625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 58725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int result = 0; 58825b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool old_in_dso = FILEINFO_EHDR (oldp->file->ehdr).e_type == ET_DYN; 58925b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool new_in_dso = FILEINFO_EHDR (fileinfo->ehdr).e_type == ET_DYN; 59025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool use_new_def = false; 59125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 59225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shndx != SHN_UNDEF 59325b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (! oldp->defined 59425b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (shndx != SHN_COMMON && oldp->common && ! new_in_dso) 59525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (old_in_dso && ! new_in_dso))) 59625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 59725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We found a definition for a previously undefined symbol or a 59825b3c049e70834cf33790a28643ab058b507b35cBen Cheng real definition for a previous common-only definition or a 59925b3c049e70834cf33790a28643ab058b507b35cBen Cheng redefinition of a symbol definition in an object file 60025b3c049e70834cf33790a28643ab058b507b35cBen Cheng previously defined in a DSO. First perform some tests which 60125b3c049e70834cf33790a28643ab058b507b35cBen Cheng will show whether the common is really matching the 60225b3c049e70834cf33790a28643ab058b507b35cBen Cheng definition. */ 60325b3c049e70834cf33790a28643ab058b507b35cBen Cheng check_type_and_size (sym, fileinfo, oldp); 60425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 60525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We leave the next element intact to not interrupt the list 60625b3c049e70834cf33790a28643ab058b507b35cBen Cheng with the unresolved symbols. Whoever walks the list will 60725b3c049e70834cf33790a28643ab058b507b35cBen Cheng have to check the `defined' flag. But we remember that this 60825b3c049e70834cf33790a28643ab058b507b35cBen Cheng list element is not unresolved anymore. */ 60925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! oldp->defined) 61025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 61125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remove from the list. */ 61225b3c049e70834cf33790a28643ab058b507b35cBen Cheng --ld_state.nunresolved; 61325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! oldp->weak) 61425b3c049e70834cf33790a28643ab058b507b35cBen Cheng --ld_state.nunresolved_nonweak; 61525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CDBL_LIST_DEL (ld_state.unresolved, oldp); 61625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 61725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (oldp->common) 61825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remove from the list. */ 61925b3c049e70834cf33790a28643ab058b507b35cBen Cheng CDBL_LIST_DEL (ld_state.common_syms, oldp); 62025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 62125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use the values of the definition from now on. */ 62225b3c049e70834cf33790a28643ab058b507b35cBen Cheng use_new_def = true; 62325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 62425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (shndx != SHN_UNDEF 62525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && oldp->defined 62625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && matching_group_comdat_scn (sym, shndx, fileinfo, oldp)) 62725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The duplicate symbol is in a group COMDAT section with the same 62825b3c049e70834cf33790a28643ab058b507b35cBen Cheng signature as the one containing the original definition. 62925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Just ignore the second definition. */ 63025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* nothing */; 63125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (shndx != SHN_UNDEF 63225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && unlikely (! oldp->common) 63325b3c049e70834cf33790a28643ab058b507b35cBen Cheng && oldp->defined 63425b3c049e70834cf33790a28643ab058b507b35cBen Cheng && shndx != SHN_COMMON 63525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Multiple definitions are no fatal errors if the -z muldefs flag 63625b3c049e70834cf33790a28643ab058b507b35cBen Cheng is used. We don't warn about the multiple definition unless we 63725b3c049e70834cf33790a28643ab058b507b35cBen Cheng are told to be verbose. */ 63825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (!ld_state.muldefs || verbose) 63925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && ! old_in_dso && fileinfo->file_type == relocatable_file_type) 64025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 64125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have a double definition. This is a problem. */ 64225b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[64]; 64325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (oldsym); 64425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *oldfile; 64525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *scnname; 64625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word xndx; 64725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shnum; 64825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 64925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_getshdrnum (fileinfo->elf, &shnum) < 0) 65025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 65125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot determine number of sections: %s"), 65225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 65325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 65425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Use only ebl_section_name. */ 65525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shndx < SHN_LORESERVE || (shndx > SHN_HIRESERVE && shndx < shnum)) 65625b3c049e70834cf33790a28643ab058b507b35cBen Cheng scnname = elf_strptr (fileinfo->elf, 65725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->shstrndx, 65825b3c049e70834cf33790a28643ab058b507b35cBen Cheng SCNINFO_SHDR (fileinfo->scninfo[shndx].shdr).sh_name); 65925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 66025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX extended section 66125b3c049e70834cf33790a28643ab058b507b35cBen Cheng scnname = ebl_section_name (ld_state.ebl, shndx, 0, buf, sizeof (buf), 66225b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL, shnum); 66325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 66425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Print source file and line number. */ 66525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_name (stderr, fileinfo, 1, 0); 66625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, 66725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("(%s+%#" PRIx64 "): multiple definition of %s `%s'\n"), 66825b3c049e70834cf33790a28643ab058b507b35cBen Cheng scnname, 66925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) sym->st_value, 67025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_symbol_type_name (ld_state.ebl, XELF_ST_TYPE (sym->st_info), 67125b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf)), 67225b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->name); 67325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 67425b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldfile = oldp->file; 67525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsymshndx (oldfile->symtabdata, oldfile->xndxdata, oldp->symidx, 67625b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldsym, xndx); 67725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (oldsym != NULL); 67825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 67925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Use only ebl_section_name. */ 68025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (oldp->scndx < SHN_LORESERVE || oldp->scndx > SHN_HIRESERVE) 68125b3c049e70834cf33790a28643ab058b507b35cBen Cheng scnname = elf_strptr (oldfile->elf, 68225b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldfile->shstrndx, 68325b3c049e70834cf33790a28643ab058b507b35cBen Cheng SCNINFO_SHDR (oldfile->scninfo[shndx].shdr).sh_name); 68425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 68525b3c049e70834cf33790a28643ab058b507b35cBen Cheng scnname = ebl_section_name (ld_state.ebl, oldp->scndx, oldp->scndx, 68625b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf), NULL, shnum); 68725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 68825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Print source file and line number. */ 68925b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_name (stderr, oldfile, 1, 0); 69025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("(%s+%#" PRIx64 "): first defined here\n"), 69125b3c049e70834cf33790a28643ab058b507b35cBen Cheng scnname, (uint64_t) oldsym->st_value); 69225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 69325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (!ld_state.muldefs)) 69425b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = 1; 69525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 69625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (old_in_dso && fileinfo->file_type == relocatable_file_type 69725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && shndx != SHN_UNDEF) 69825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We use the definition from a normal relocatable file over the 69925b3c049e70834cf33790a28643ab058b507b35cBen Cheng definition in a DSO. This is what the dynamic linker would 70025b3c049e70834cf33790a28643ab058b507b35cBen Cheng do, too. */ 70125b3c049e70834cf33790a28643ab058b507b35cBen Cheng use_new_def = true; 70225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (old_in_dso && !new_in_dso && oldp->defined && !oldp->on_dsolist) 70325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 70425b3c049e70834cf33790a28643ab058b507b35cBen Cheng CDBL_LIST_ADD_REAR (ld_state.from_dso, oldp); 70525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nfrom_dso; 70625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 70725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the object is a function we allocate a PLT entry, 70825b3c049e70834cf33790a28643ab058b507b35cBen Cheng otherwise only a GOT entry. */ 70925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (oldp->type == STT_FUNC) 71025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nplt; 71125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 71225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.ngot; 71325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 71425b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->on_dsolist = 1; 71525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 71625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (oldp->common && shndx == SHN_COMMON) 71725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 71825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The symbol size is the largest of all common definitions. */ 71925b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->size = MAX (oldp->size, sym->st_size); 72025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Similarly for the alignment. */ 72125b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->merge.value = MAX (oldp->merge.value, sym->st_value); 72225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 72325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 72425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (use_new_def)) 72525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 72625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Adjust the symbol record appropriately and remove 72725b3c049e70834cf33790a28643ab058b507b35cBen Cheng the symbol from the list of symbols which are taken from DSOs. */ 72825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (old_in_dso && fileinfo->file_type == relocatable_file_type) 72925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 73025b3c049e70834cf33790a28643ab058b507b35cBen Cheng CDBL_LIST_DEL (ld_state.from_dso, oldp); 73125b3c049e70834cf33790a28643ab058b507b35cBen Cheng --ld_state.nfrom_dso; 73225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 73325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (oldp->type == STT_FUNC)) 73425b3c049e70834cf33790a28643ab058b507b35cBen Cheng --ld_state.nplt; 73525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 73625b3c049e70834cf33790a28643ab058b507b35cBen Cheng --ld_state.ngot; 73725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 73825b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->on_dsolist = 0; 73925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 74025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 74125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use the values of the definition from now on. */ 74225b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->size = sym->st_size; 74325b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->type = XELF_ST_TYPE (sym->st_info); 74425b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->symidx = symidx; 74525b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->scndx = shndx; 74625b3c049e70834cf33790a28643ab058b507b35cBen Cheng //oldp->symscndx = THESYMSCNDX must be passed; 74725b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->file = fileinfo; 74825b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->defined = 1; 74925b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->in_dso = new_in_dso; 75025b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->common = shndx == SHN_COMMON; 75125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fileinfo->file_type == relocatable_file_type)) 75225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 75325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the definition comes from a DSO we pertain the weak flag 75425b3c049e70834cf33790a28643ab058b507b35cBen Cheng and it's indicating whether the reference is weak or not. */ 75525b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->weak = XELF_ST_BIND (sym->st_info) == STB_WEAK; 75625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 75725b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Really exclude SHN_ABS? 75825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shndx != SHN_COMMON && shndx != SHN_ABS) 75925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 76025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *ignore; 76125b3c049e70834cf33790a28643ab058b507b35cBen Cheng mark_section_used (&fileinfo->scninfo[shndx], shndx, &ignore); 76225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 76325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 76425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 76525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add to the list of symbols used from DSOs if necessary. */ 76625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (new_in_dso && !old_in_dso) 76725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 76825b3c049e70834cf33790a28643ab058b507b35cBen Cheng CDBL_LIST_ADD_REAR (ld_state.from_dso, oldp); 76925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nfrom_dso; 77025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 77125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the object is a function we allocate a PLT entry, 77225b3c049e70834cf33790a28643ab058b507b35cBen Cheng otherwise only a GOT entry. */ 77325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (oldp->type == STT_FUNC) 77425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nplt; 77525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 77625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.ngot; 77725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 77825b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->on_dsolist = 1; 77925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 78025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (shndx == SHN_COMMON) 78125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 78225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the alignment. */ 78325b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->merge.value = sym->st_value; 78425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 78525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CDBL_LIST_ADD_REAR (ld_state.common_syms, oldp); 78625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 78725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 78825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 78925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 79025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 79125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 79225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 79325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct scninfo * 79425b3c049e70834cf33790a28643ab058b507b35cBen Chengfind_section_group (struct usedfiles *fileinfo, Elf32_Word shndx, 79525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data **datap) 79625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 79725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *runp; 79825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 79925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (runp = fileinfo->groups; runp != NULL; runp = runp->next) 80025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!runp->used) 80125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 80225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *grpref; 80325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 80425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data; 80525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 80625b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = elf_getdata (runp->scn, NULL); 80725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 80825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 80925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s: cannot get section group data: %s"), 81025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname, elf_errmsg (-1)); 81125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 81225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There cannot be another data block. */ 81325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (elf_getdata (runp->scn, data) == NULL); 81425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 81525b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpref = (Elf32_Word *) data->d_buf; 81625b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt = data->d_size / sizeof (Elf32_Word); 81725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note that we stop after looking at index 1 since index 0 81825b3c049e70834cf33790a28643ab058b507b35cBen Cheng contains the flags for the section group. */ 81925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (cnt > 1) 82025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (grpref[--cnt] == shndx) 82125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 82225b3c049e70834cf33790a28643ab058b507b35cBen Cheng *datap = data; 82325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return runp; 82425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 82525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 82625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 82725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we come here no section group contained the given section 82825b3c049e70834cf33790a28643ab058b507b35cBen Cheng despite the SHF_GROUP flag. This is an error in the input 82925b3c049e70834cf33790a28643ab058b507b35cBen Cheng file. */ 83025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 83125b3c049e70834cf33790a28643ab058b507b35cBen Cheng%s: section '%s' with group flag set does not belong to any group"), 83225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname, 83325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (fileinfo->elf, fileinfo->shstrndx, 83425b3c049e70834cf33790a28643ab058b507b35cBen Cheng SCNINFO_SHDR (fileinfo->scninfo[shndx].shdr).sh_name)); 83525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return NULL; 83625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 83725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 83825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 83925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Mark all sections which belong to the same group as section SHNDX 84025b3c049e70834cf33790a28643ab058b507b35cBen Cheng as used. */ 84125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 84225b3c049e70834cf33790a28643ab058b507b35cBen Chengmark_section_group (struct usedfiles *fileinfo, Elf32_Word shndx, 84325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo **grpscnp) 84425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 84525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First locate the section group. There can be several (many) of 84625b3c049e70834cf33790a28643ab058b507b35cBen Cheng them. */ 84725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 84825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *grpref; 84925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data; 85025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *grpscn = find_section_group (fileinfo, shndx, &data); 85125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *grpscnp = grpscn; 85225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 85325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Mark all the sections as used. 85425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 85525b3c049e70834cf33790a28643ab058b507b35cBen Cheng XXX Two possible problems here: 85625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 85725b3c049e70834cf33790a28643ab058b507b35cBen Cheng - the gABI says "The section must be referenced by a section of type 85825b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHT_GROUP". I hope everybody reads this as "exactly one section". 85925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 86025b3c049e70834cf33790a28643ab058b507b35cBen Cheng - section groups are also useful to mark the debugging section which 86125b3c049e70834cf33790a28643ab058b507b35cBen Cheng belongs to a text section. Unconditionally adding debugging sections 86225b3c049e70834cf33790a28643ab058b507b35cBen Cheng is therefore probably not what is wanted if stripping is required. */ 86325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 86425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Mark the section group as handled. */ 86525b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpscn->used = true; 86625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 86725b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpref = (Elf32_Word *) data->d_buf; 86825b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt = data->d_size / sizeof (Elf32_Word); 86925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (cnt > 1) 87025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 87125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word idx = grpref[--cnt]; 87225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr *shdr = &SCNINFO_SHDR (fileinfo->scninfo[idx].shdr); 87325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 87425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->scninfo[idx].grpid != grpscn->grpid) 87525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 87625b3c049e70834cf33790a28643ab058b507b35cBen Cheng%s: section [%2d] '%s' is not in the correct section group"), 87725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname, (int) idx, 87825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (fileinfo->elf, fileinfo->shstrndx, shdr->sh_name)); 87925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 88025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.strip == strip_none 88125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we are stripping, remove debug sections. */ 88225b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (!ebl_debugscn_p (ld_state.ebl, 88325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (fileinfo->elf, fileinfo->shstrndx, 88425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name)) 88525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And the relocation sections for the debug sections. */ 88625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && ((shdr->sh_type != SHT_RELA && shdr->sh_type != SHT_REL) 88725b3c049e70834cf33790a28643ab058b507b35cBen Cheng || !ebl_debugscn_p (ld_state.ebl, 88825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (fileinfo->elf, 88925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->shstrndx, 89025b3c049e70834cf33790a28643ab058b507b35cBen Cheng SCNINFO_SHDR (fileinfo->scninfo[shdr->sh_info].shdr).sh_name))))) 89125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 89225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *ignore; 89325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 89425b3c049e70834cf33790a28643ab058b507b35cBen Cheng mark_section_used (&fileinfo->scninfo[idx], idx, &ignore); 89525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 89625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 89725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 89825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 89925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 90025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 90125b3c049e70834cf33790a28643ab058b507b35cBen Chengmark_section_used (struct scninfo *scninfo, Elf32_Word shndx, 90225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo **grpscnp) 90325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 90425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (scninfo->used)) 90525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Nothing to be done. */ 90625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 90725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 90825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We need this section. */ 90925b3c049e70834cf33790a28643ab058b507b35cBen Cheng scninfo->used = true; 91025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 91125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make sure the section header has been read from the file. */ 91225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr *shdr = &SCNINFO_SHDR (scninfo->shdr); 91325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF 91425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (scninfo->shdr == NULL)) 91525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 91625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (scninfo->shdr.sh_type == SHT_NULL)) 91725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 91825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 91925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF != 0 92025b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr = xelf_getshdr (scninfo->scn, scninfo->shdr); 92125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 92225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr_copy (scninfo->scn, shdr, scninfo->shdr); 92325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 92425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr == NULL)) 92525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Something is very wrong. The calling code will notice it 92625b3c049e70834cf33790a28643ab058b507b35cBen Cheng soon and print a message. */ 92725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 92825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 92925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 93025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle section linked by 'sh_link'. */ 93125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr->sh_link != 0)) 93225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 93325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *ignore; 93425b3c049e70834cf33790a28643ab058b507b35cBen Cheng mark_section_used (&scninfo->fileinfo->scninfo[shdr->sh_link], 93525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link, &ignore); 93625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 93725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 93825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle section linked by 'sh_info'. */ 93925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr->sh_info != 0) && (shdr->sh_flags & SHF_INFO_LINK)) 94025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 94125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *ignore; 94225b3c049e70834cf33790a28643ab058b507b35cBen Cheng mark_section_used (&scninfo->fileinfo->scninfo[shdr->sh_info], 94325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info, &ignore); 94425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 94525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 94625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr->sh_flags & SHF_GROUP) && ld_state.gc_sections) 94725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the section group which contains this section. */ 94825b3c049e70834cf33790a28643ab058b507b35cBen Cheng mark_section_group (scninfo->fileinfo, shndx, grpscnp); 94925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 95025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 95125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 95225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* We collect all sections in a hashing table. All sections with the 95325b3c049e70834cf33790a28643ab058b507b35cBen Cheng same name are collected in a list. Note that we do not determine 95425b3c049e70834cf33790a28643ab058b507b35cBen Cheng which sections are finally collected in the same output section 95525b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. This would be terribly inefficient. It will be done later. */ 95625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 95725b3c049e70834cf33790a28643ab058b507b35cBen Chengadd_section (struct usedfiles *fileinfo, struct scninfo *scninfo) 95825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 95925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead *queued; 96025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead search; 96125b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned long int hval; 96225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr *shdr = &SCNINFO_SHDR (scninfo->shdr); 96325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *grpscn = NULL; 96425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *grpscndata = NULL; 96525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 96625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* See whether we can determine right away whether we need this 96725b3c049e70834cf33790a28643ab058b507b35cBen Cheng section in the output. 96825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 96925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XXX I assume here that --gc-sections only affects extraction 97025b3c049e70834cf33790a28643ab058b507b35cBen Cheng from an archive. If it also affects objects files given on 97125b3c049e70834cf33790a28643ab058b507b35cBen Cheng the command line then somebody must explain to me how the 97225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dependency analysis should work. Should the entry point be 97325b3c049e70834cf33790a28643ab058b507b35cBen Cheng the root? What if it is a numeric value? */ 97425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!scninfo->used 97525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (ld_state.strip == strip_none 97625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (shdr->sh_flags & SHF_ALLOC) != 0 97725b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shdr->sh_type == SHT_NOTE 97825b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (shdr->sh_type == SHT_PROGBITS 97925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && strcmp (elf_strptr (fileinfo->elf, 98025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->shstrndx, 98125b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name), ".comment") == 0)) 98225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (fileinfo->status != in_archive || !ld_state.gc_sections)) 98325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Mark as used and handle reference recursively if necessary. */ 98425b3c049e70834cf33790a28643ab058b507b35cBen Cheng mark_section_used (scninfo, elf_ndxscn (scninfo->scn), &grpscn); 98525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 98625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((shdr->sh_flags & SHF_GROUP) && grpscn == NULL) 98725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the symbol which name constitutes the signature 98825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for the section group. */ 98925b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpscn = find_section_group (fileinfo, elf_ndxscn (scninfo->scn), 99025b3c049e70834cf33790a28643ab058b507b35cBen Cheng &grpscndata); 99125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (grpscn == NULL || grpscn->symbols->name != NULL); 99225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 99325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the section name. */ 99425b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.name = elf_strptr (fileinfo->elf, fileinfo->shstrndx, shdr->sh_name); 99525b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.type = shdr->sh_type; 99625b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.flags = shdr->sh_flags; 99725b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.entsize = shdr->sh_entsize; 99825b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.grp_signature = grpscn != NULL ? grpscn->symbols->name : NULL; 99925b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.kind = scn_normal; 100025b3c049e70834cf33790a28643ab058b507b35cBen Cheng hval = elf_hash (search.name); 100125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 100225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find already queued sections. */ 100325b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued = ld_section_tab_find (&ld_state.section_tab, hval, &search); 100425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (queued != NULL) 100525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 100625b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool is_comdat = false; 100725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 100825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If this section is part of a COMDAT section group we simply 100925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ignore it since we already have a copy. */ 101025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr->sh_flags & SHF_GROUP)) 101125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 101225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data of the section group section. */ 101325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (grpscndata == NULL) 101425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 101525b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpscndata = elf_getdata (grpscn->scn, NULL); 101625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (grpscndata != NULL); 101725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 101825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 101925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Possibly unaligned memory access. */ 102025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((((Elf32_Word *) grpscndata->d_buf)[0] & GRP_COMDAT) != 0) 102125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 102225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to compare the group signatures. There might 102325b3c049e70834cf33790a28643ab058b507b35cBen Cheng be sections with the same name but belonging to 102425b3c049e70834cf33790a28643ab058b507b35cBen Cheng groups with different signatures. This means we have 102525b3c049e70834cf33790a28643ab058b507b35cBen Cheng to compare the new group signature with all those 102625b3c049e70834cf33790a28643ab058b507b35cBen Cheng already collected. There might also be some 102725b3c049e70834cf33790a28643ab058b507b35cBen Cheng non-group sections in the mix. */ 102825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *runp = queued->last; 102925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 103025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 103125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (SCNINFO_SHDR (runp->shdr).sh_flags & SHF_GROUP) 103225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 103325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *grpscn2 103425b3c049e70834cf33790a28643ab058b507b35cBen Cheng = find_section_group (runp->fileinfo, 103525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (runp->scn), 103625b3c049e70834cf33790a28643ab058b507b35cBen Cheng &grpscndata); 103725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 103825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (grpscn->symbols->name, 103925b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpscn2->symbols->name) == 0) 104025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 104125b3c049e70834cf33790a28643ab058b507b35cBen Cheng scninfo->unused_comdat = is_comdat = true; 104225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 104325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 104425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 104525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 104625b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = runp->next; 104725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 104825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (runp != queued->last); 104925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 105025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 105125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 105225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!is_comdat) 105325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 105425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No COMDAT section, we use the data. */ 105525b3c049e70834cf33790a28643ab058b507b35cBen Cheng scninfo->next = queued->last->next; 105625b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->last = queued->last->next = scninfo; 105725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 105825b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->flags = ebl_sh_flags_combine (ld_state.ebl, queued->flags, 105925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_flags); 106025b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->align = MAX (queued->align, shdr->sh_addralign); 106125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 106225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 106325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 106425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 106525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We do not use obstacks here since the memory might be 106625b3c049e70834cf33790a28643ab058b507b35cBen Cheng deallocated. */ 106725b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued = (struct scnhead *) xcalloc (sizeof (struct scnhead), 1); 106825b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->kind = scn_normal; 106925b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->name = search.name; 107025b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->type = shdr->sh_type; 107125b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->flags = shdr->sh_flags; 107225b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->align = shdr->sh_addralign; 107325b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->entsize = shdr->sh_entsize; 107425b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->grp_signature = grpscn != NULL ? grpscn->symbols->name : NULL; 107525b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->segment_nr = ~0; 107625b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->last = scninfo->next = scninfo; 107725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 107825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether we need a TLS segment. */ 107925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.need_tls |= (shdr->sh_flags & SHF_TLS) != 0; 108025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 108125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add to the hash table and possibly overwrite existing value. */ 108225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_section_tab_insert (&ld_state.section_tab, hval, queued); 108325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 108425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 108525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 108625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 108725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 108825b3c049e70834cf33790a28643ab058b507b35cBen Chengadd_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype) 108925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 109025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t scncnt; 109125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 109225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *symtabdata = NULL; 109325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *xndxdata = NULL; 109425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *versymdata = NULL; 109525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *verdefdata = NULL; 109625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *verneeddata = NULL; 109725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t symstridx = 0; 109825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsymbols = 0; 109925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nlocalsymbols = 0; 110025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool has_merge_sections = false; 110125b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool has_tls_symbols = false; 110225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Unless we have different information we assume the code needs 110325b3c049e70834cf33790a28643ab058b507b35cBen Cheng an executable stack. */ 110425b3c049e70834cf33790a28643ab058b507b35cBen Cheng enum execstack execstack = execstack_true; 110525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 110625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Prerequisites. */ 110725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fileinfo->elf != NULL); 110825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 110925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Allocate memory for the sections. */ 111025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrnum (fileinfo->elf, &scncnt) < 0)) 111125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 111225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot determine number of sections: %s"), 111325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 111425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 111525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo = (struct scninfo *) 111625b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, scncnt * sizeof (struct scninfo)); 111725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 111825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Read all the section headers and find the symbol table. Note 111925b3c049e70834cf33790a28643ab058b507b35cBen Cheng that we don't skip the section with index zero. Even though the 112025b3c049e70834cf33790a28643ab058b507b35cBen Cheng section itself is always empty the section header contains 112125b3c049e70834cf33790a28643ab058b507b35cBen Cheng informaton for the case when the section index for the section 112225b3c049e70834cf33790a28643ab058b507b35cBen Cheng header string table is too large to fit in the ELF header. */ 112325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < scncnt; ++cnt) 112425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 112525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the handle for the section. */ 112625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[cnt].scn = elf_getscn (fileinfo->elf, cnt); 112725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 112825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the ELF section header and data. */ 112925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr *shdr; 113025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF != 0 113125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->scninfo[cnt].shdr == NULL) 113225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 113325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->scninfo[cnt].shdr.sh_type == SHT_NULL) 113425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 113525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 113625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF != 0 113725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr = xelf_getshdr (fileinfo->scninfo[cnt].scn, 113825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[cnt].shdr); 113925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 114025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr_copy (fileinfo->scninfo[cnt].scn, shdr, 114125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[cnt].shdr); 114225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 114325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL) 114425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 114525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This should never happen. */ 114625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("%s: invalid ELF file (%s:%d)\n"), 114725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, __FILE__, __LINE__); 114825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 114925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 115025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 115125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 115225b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr = &SCNINFO_SHDR (fileinfo->scninfo[cnt].shdr); 115325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 115425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (fileinfo->scninfo[cnt].scn, NULL); 115525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 115625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether this section is marked as merge-able. */ 115725b3c049e70834cf33790a28643ab058b507b35cBen Cheng has_merge_sections |= (shdr->sh_flags & SHF_MERGE) != 0; 115825b3c049e70834cf33790a28643ab058b507b35cBen Cheng has_tls_symbols |= (shdr->sh_flags & SHF_TLS) != 0; 115925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 116025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the ELF section header and data. */ 116125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make the file structure available. */ 116225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[cnt].fileinfo = fileinfo; 116325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 116425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr->sh_type == SHT_SYMTAB) 116525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || unlikely (shdr->sh_type == SHT_DYNSYM)) 116625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 116725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type == SHT_SYMTAB) 116825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 116925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fileinfo->symtabdata == NULL); 117025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->symtabdata = data; 117125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->nsymtab = shdr->sh_size / shdr->sh_entsize; 117225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->nlocalsymbols = shdr->sh_info; 117325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->symstridx = shdr->sh_link; 117425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 117525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 117625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 117725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fileinfo->dynsymtabdata == NULL); 117825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->dynsymtabdata = data; 117925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->ndynsymtab = shdr->sh_size / shdr->sh_entsize; 118025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->dynsymstridx = shdr->sh_link; 118125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 118225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 118325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we are looking for the normal symbol table we just 118425b3c049e70834cf33790a28643ab058b507b35cBen Cheng found it. */ 118525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (secttype == shdr->sh_type) 118625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 118725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (symtabdata == NULL); 118825b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtabdata = data; 118925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstridx = shdr->sh_link; 119025b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsymbols = shdr->sh_size / shdr->sh_entsize; 119125b3c049e70834cf33790a28643ab058b507b35cBen Cheng nlocalsymbols = shdr->sh_info; 119225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 119325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 119425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (shdr->sh_type == SHT_SYMTAB_SHNDX)) 119525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 119625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (xndxdata == NULL); 119725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->xndxdata = xndxdata = data; 119825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 119925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (shdr->sh_type == SHT_GNU_versym)) 120025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 120125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (versymdata == 0); 120225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->versymdata = versymdata = data; 120325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 120425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (shdr->sh_type == SHT_GNU_verdef)) 120525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 120625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nversions; 120725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 120825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (verdefdata == 0); 120925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->verdefdata = verdefdata = data; 121025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 121125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Allocate the arrays flagging the use of the version and 121225b3c049e70834cf33790a28643ab058b507b35cBen Cheng to track of allocated names. */ 121325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->nverdef = nversions = shdr->sh_info; 121425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have NVERSIONS + 1 because the indeces used to access the 121525b3c049e70834cf33790a28643ab058b507b35cBen Cheng sectino start with one; zero represents local binding. */ 121625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->verdefused = (XElf_Versym *) 121725b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, 121825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (XElf_Versym) * (nversions + 1)); 121925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->verdefent = (struct Ebl_Strent **) 122025b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_alloc (&ld_state.smem, 122125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (struct Ebl_Strent *) * (nversions + 1)); 122225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 122325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (shdr->sh_type == SHT_GNU_verneed)) 122425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 122525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (verneeddata == 0); 122625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->verneeddata = verneeddata = data; 122725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 122825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (shdr->sh_type == SHT_DYNAMIC)) 122925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 123025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fileinfo->dynscn == NULL); 123125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->dynscn = fileinfo->scninfo[cnt].scn; 123225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 123325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (shdr->sh_type == SHT_GROUP)) 123425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 123525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *symscn; 123625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr_vardef (symshdr); 123725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *symdata; 123825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 123925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (FILEINFO_EHDR (fileinfo->ehdr).e_type != ET_REL) 124025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 124125b3c049e70834cf33790a28643ab058b507b35cBen Cheng%s: only files of type ET_REL might contain section groups"), 124225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname); 124325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 124425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[cnt].next = fileinfo->groups; 124525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[cnt].grpid = cnt; 124625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->groups = &fileinfo->scninfo[cnt]; 124725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 124825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the signature. We create a symbol record for 124925b3c049e70834cf33790a28643ab058b507b35cBen Cheng it. Only the name element is important. */ 125025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[cnt].symbols = (struct symbol *) 125125b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, sizeof (struct symbol)); 125225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 125325b3c049e70834cf33790a28643ab058b507b35cBen Cheng symscn = elf_getscn (fileinfo->elf, shdr->sh_link); 125425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (symscn, symshdr); 125525b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata = elf_getdata (symscn, NULL); 125625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 125725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symshdr != NULL) 125825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 125925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 126025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 126125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't need the section index and therefore we don't 126225b3c049e70834cf33790a28643ab058b507b35cBen Cheng have to use 'xelf_getsymshndx'. */ 126325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, shdr->sh_info, sym); 126425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym != NULL) 126525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 126625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *symbol = fileinfo->scninfo[cnt].symbols; 126725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 126825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NO_HACKS 126925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (XELF_ST_TYPE (sym->st_info) == STT_SECTION) 127025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 127125b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr_vardef (buggyshdr); 127225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (fileinfo->elf, sym->st_shndx), 127325b3c049e70834cf33790a28643ab058b507b35cBen Cheng buggyshdr); 127425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 127525b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol->name = elf_strptr (fileinfo->elf, 127625b3c049e70834cf33790a28643ab058b507b35cBen Cheng FILEINFO_EHDR (fileinfo->ehdr).e_shstrndx, 127725b3c049e70834cf33790a28643ab058b507b35cBen Cheng buggyshdr->sh_name); 127825b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol->symidx = -1; 127925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 128025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 128125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 128225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 128325b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol->name = elf_strptr (fileinfo->elf, 128425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symshdr->sh_link, 128525b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_name); 128625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol->symidx = shdr->sh_info; 128725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 128825b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol->file = fileinfo; 128925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 129025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 129125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->scninfo[cnt].symbols->name == NULL) 129225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 129325b3c049e70834cf33790a28643ab058b507b35cBen Cheng%s: cannot determine signature of section group [%2zd] '%s': %s"), 129425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname, 129525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_ndxscn (fileinfo->scninfo[cnt].scn), 129625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (fileinfo->elf, fileinfo->shstrndx, 129725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name), 129825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 129925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 130025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 130125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* For all the sections which are part of this group, add 130225b3c049e70834cf33790a28643ab058b507b35cBen Cheng the reference. */ 130325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 130425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 130525b3c049e70834cf33790a28643ab058b507b35cBen Cheng%s: cannot get content of section group [%2zd] '%s': %s'"), 130625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname, elf_ndxscn (fileinfo->scninfo[cnt].scn), 130725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (fileinfo->elf, fileinfo->shstrndx, 130825b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name), 130925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 131025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 131125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *grpdata = (Elf32_Word *) data->d_buf; 131225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (grpdata[0] & GRP_COMDAT) 131325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[cnt].comdat_group = true; 131425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word); 131525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++inner) 131625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 131725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (grpdata[inner] >= scncnt) 131825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 131925b3c049e70834cf33790a28643ab058b507b35cBen Cheng%s: group member %zu of section group [%2zd] '%s' has too high index: %" PRIu32), 132025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname, 132125b3c049e70834cf33790a28643ab058b507b35cBen Cheng inner, elf_ndxscn (fileinfo->scninfo[cnt].scn), 132225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (fileinfo->elf, fileinfo->shstrndx, 132325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name), 132425b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpdata[inner]); 132525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 132625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[grpdata[inner]].grpid = cnt; 132725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 132825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 132925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The 'used' flag is used to indicate when the information 133025b3c049e70834cf33790a28643ab058b507b35cBen Cheng in the section group is used to mark all other sections 133125b3c049e70834cf33790a28643ab058b507b35cBen Cheng as used. So it must not be true yet. */ 133225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fileinfo->scninfo[cnt].used == false); 133325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 133425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (! SECTION_TYPE_P (&ld_state, shdr->sh_type) 133525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && unlikely ((shdr->sh_flags & SHF_OS_NONCONFORMING) != 0)) 133625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* According to the gABI it is a fatal error if the file contains 133725b3c049e70834cf33790a28643ab058b507b35cBen Cheng a section with unknown type and the SHF_OS_NONCONFORMING flag 133825b3c049e70834cf33790a28643ab058b507b35cBen Cheng set. */ 133925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 134025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("%s: section '%s' has unknown type: %d"), 134125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname, 134225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (fileinfo->elf, fileinfo->shstrndx, 134325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name), 134425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) shdr->sh_type); 134525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't have to add a few section types here. These will be 134625b3c049e70834cf33790a28643ab058b507b35cBen Cheng generated from scratch for the new output file. We also 134725b3c049e70834cf33790a28643ab058b507b35cBen Cheng don't add the sections of DSOs here since these sections are 134825b3c049e70834cf33790a28643ab058b507b35cBen Cheng not used in the resulting object file. */ 134925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (likely (fileinfo->file_type == relocatable_file_type) 135025b3c049e70834cf33790a28643ab058b507b35cBen Cheng && likely (cnt > 0) 135125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && likely (shdr->sh_type == SHT_PROGBITS 135225b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shdr->sh_type == SHT_RELA 135325b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shdr->sh_type == SHT_REL 135425b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shdr->sh_type == SHT_NOTE 135525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shdr->sh_type == SHT_NOBITS 135625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shdr->sh_type == SHT_INIT_ARRAY 135725b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shdr->sh_type == SHT_FINI_ARRAY 135825b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shdr->sh_type == SHT_PREINIT_ARRAY)) 135925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 136025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether the section needs to be executable. */ 136125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type == SHT_PROGBITS 136225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shdr->sh_flags & SHF_EXECINSTR) == 0 136325b3c049e70834cf33790a28643ab058b507b35cBen Cheng && strcmp (elf_strptr (fileinfo->elf, fileinfo->shstrndx, 136425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name), 136525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ".note.GNU-stack") == 0) 136625b3c049e70834cf33790a28643ab058b507b35cBen Cheng execstack = execstack_false; 136725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 136825b3c049e70834cf33790a28643ab058b507b35cBen Cheng add_section (fileinfo, &fileinfo->scninfo[cnt]); 136925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 137025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 137125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 137225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now we know more about the requirements for an executable stack 137325b3c049e70834cf33790a28643ab058b507b35cBen Cheng of the result. */ 137425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->file_type == relocatable_file_type 137525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && execstack == execstack_true 137625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && ld_state.execstack != execstack_false_force) 137725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.execstack = execstack_true; 137825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 137925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle the symbols. Record defined and undefined symbols in the 138025b3c049e70834cf33790a28643ab058b507b35cBen Cheng hash table. In theory there can be a file without any symbol 138125b3c049e70834cf33790a28643ab058b507b35cBen Cheng table. */ 138225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (symtabdata != NULL)) 138325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 138425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* In case this file contains merge-able sections we have to 138525b3c049e70834cf33790a28643ab058b507b35cBen Cheng locate the symbols which are in these sections. */ 138625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->has_merge_sections = has_merge_sections; 138725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (has_merge_sections || has_tls_symbols)) 138825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 138925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->symref = (struct symbol **) 139025b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, 139125b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsymbols * sizeof (struct symbol *)); 139225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 139325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Only handle the local symbols here. */ 139425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < nlocalsymbols; ++cnt) 139525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 139625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word shndx; 139725b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 139825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 139925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsymshndx (symtabdata, xndxdata, cnt, sym, shndx); 140025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym == NULL) 140125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 140225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This should never happen. */ 140325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("%s: invalid ELF file (%s:%d)\n"), 140425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, __FILE__, __LINE__); 140525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 140625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 140725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 140825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (shndx != SHN_XINDEX)) 140925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shndx = sym->st_shndx; 141025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (shndx == 0)) 141125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 141225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("%s: invalid ELF file (%s:%d)\n"), 141325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, __FILE__, __LINE__); 141425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 141525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 141625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 141725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (XELF_ST_TYPE (sym->st_info) != STT_SECTION 141825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shndx < SHN_LORESERVE || shndx > SHN_HIRESERVE) 141925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && ((SCNINFO_SHDR (fileinfo->scninfo[shndx].shdr).sh_flags 142025b3c049e70834cf33790a28643ab058b507b35cBen Cheng & SHF_MERGE) 142125b3c049e70834cf33790a28643ab058b507b35cBen Cheng || XELF_ST_TYPE (sym->st_info) == STT_TLS)) 142225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 142325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create a symbol record for this symbol and add it 142425b3c049e70834cf33790a28643ab058b507b35cBen Cheng to the list for this section. */ 142525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *newp; 142625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 142725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = (struct symbol *) 142825b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, sizeof (struct symbol)); 142925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 143025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->symidx = cnt; 143125b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->scndx = shndx; 143225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->file = fileinfo; 143325b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->defined = 1; 143425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->symref[cnt] = newp; 143525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 143625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->scninfo[shndx].symbols == NULL) 143725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[shndx].symbols = newp->next_in_scn 143825b3c049e70834cf33790a28643ab058b507b35cBen Cheng = newp; 143925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 144025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 144125b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->next_in_scn 144225b3c049e70834cf33790a28643ab058b507b35cBen Cheng = fileinfo->scninfo[shndx].symbols->next_in_scn; 144325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[shndx].symbols 144425b3c049e70834cf33790a28643ab058b507b35cBen Cheng = fileinfo->scninfo[shndx].symbols->next_in_scn = newp; 144525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 144625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 144725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 144825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 144925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 145025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create array with pointers to the symbol definitions. Note 145125b3c049e70834cf33790a28643ab058b507b35cBen Cheng that we only allocate memory for the non-local symbols 145225b3c049e70834cf33790a28643ab058b507b35cBen Cheng since we have no merge-able sections. But we store the 145325b3c049e70834cf33790a28643ab058b507b35cBen Cheng pointer as if it was for the whole symbol table. This 145425b3c049e70834cf33790a28643ab058b507b35cBen Cheng saves some memory. */ 145525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->symref = (struct symbol **) 145625b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, ((nsymbols - nlocalsymbols) 145725b3c049e70834cf33790a28643ab058b507b35cBen Cheng * sizeof (struct symbol *))) 145825b3c049e70834cf33790a28643ab058b507b35cBen Cheng - nlocalsymbols; 145925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 146025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Don't handle local symbols here. It's either not necessary 146125b3c049e70834cf33790a28643ab058b507b35cBen Cheng at all or has already happened. */ 146225b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = nlocalsymbols; cnt < nsymbols; ++cnt) 146325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 146425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 146525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word shndx; 146625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsymshndx (symtabdata, xndxdata, cnt, sym, shndx); 146725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 146825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym == NULL) 146925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 147025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This should never happen. */ 147125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("%s: invalid ELF file (%s:%d)\n"), 147225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, __FILE__, __LINE__); 147325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 147425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 147525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 147625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (shndx != SHN_XINDEX)) 147725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shndx = sym->st_shndx; 147825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (shndx == 0)) 147925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 148025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("%s: invalid ELF file (%s:%d)\n"), 148125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, __FILE__, __LINE__); 148225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 148325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 148425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 148525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We ignore ABS symbols from DSOs. */ 148625b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Is this correct? 148725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shndx == SHN_ABS) && secttype == SHT_DYNSYM) 148825b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 148925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 149025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((shndx < SHN_LORESERVE || shndx > SHN_HIRESERVE) 149125b3c049e70834cf33790a28643ab058b507b35cBen Cheng && fileinfo->scninfo[shndx].unused_comdat) 149225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The symbol is not used. */ 149325b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 149425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 149525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the DSO uses symbol versions determine whether this is 149625b3c049e70834cf33790a28643ab058b507b35cBen Cheng the default version. Otherwise we'll ignore the symbol. */ 149725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (versymdata != NULL) 149825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 149925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Versym versym; 150025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 150125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (xelf_getversym_copy (versymdata, cnt, versym) == NULL) 150225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Should we handle faulty input files more graceful? */ 150325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (! "xelf_getversym failed"); 150425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 150525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((versym & 0x8000) != 0) 150625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Ignore the symbol, it's not the default version. */ 150725b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 150825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 150925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 151025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* See whether we know anything about this symbol. */ 151125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol search; 151225b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.name = elf_strptr (fileinfo->elf, symstridx, sym->st_name); 151325b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned long int hval = elf_hash (search.name); 151425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 151525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We ignore the symbols the linker generates. This are 151625b3c049e70834cf33790a28643ab058b507b35cBen Cheng _GLOBAL_OFFSET_TABLE_, _DYNAMIC. */ 151725b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX This loop is hot and the following tests hardly ever match. 151825b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Maybe move the tests somewhere they are executed less often. 151925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (((unlikely (hval == 165832675ul) 152025b3c049e70834cf33790a28643ab058b507b35cBen Cheng && strcmp (search.name, "_DYNAMIC") == 0) 152125b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (unlikely (hval == 102264335ul) 152225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && strcmp (search.name, "_GLOBAL_OFFSET_TABLE_") == 0)) 152325b3c049e70834cf33790a28643ab058b507b35cBen Cheng && sym->st_shndx != SHN_UNDEF 152425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If somebody defines such a variable in a relocatable we 152525b3c049e70834cf33790a28643ab058b507b35cBen Cheng don't ignore it. Let the user get what s/he deserves. */ 152625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && fileinfo->file_type != relocatable_file_type) 152725b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 152825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 152925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *oldp = ld_symbol_tab_find (&ld_state.symbol_tab, 153025b3c049e70834cf33790a28643ab058b507b35cBen Cheng hval, &search); 153125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *newp; 153225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (oldp == NULL)) 153325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 153425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No symbol of this name known. Add it. */ 153525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = (struct symbol *) obstack_alloc (&ld_state.smem, 153625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (*newp)); 153725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->name = search.name; 153825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->size = sym->st_size; 153925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->type = XELF_ST_TYPE (sym->st_info); 154025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->symidx = cnt; 154125b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->outsymidx = 0; 154225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->outdynsymidx = 0; 154325b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->scndx = shndx; 154425b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->file = fileinfo; 154525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->defined = newp->scndx != SHN_UNDEF; 154625b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->common = newp->scndx == SHN_COMMON; 154725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->weak = XELF_ST_BIND (sym->st_info) == STB_WEAK; 154825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->added = 0; 154925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->merged = 0; 155025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->local = 0; 155125b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->hidden = 0; 155225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->need_copy = 0; 155325b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->on_dsolist = 0; 155425b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->in_dso = secttype == SHT_DYNSYM; 155525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->next_in_scn = NULL; 155625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 155725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->next = NULL; 155825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->previous = NULL; 155925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 156025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 156125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (newp->scndx == SHN_UNDEF) 156225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 156325b3c049e70834cf33790a28643ab058b507b35cBen Cheng CDBL_LIST_ADD_REAR (ld_state.unresolved, newp); 156425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nunresolved; 156525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! newp->weak) 156625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nunresolved_nonweak; 156725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 156825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (newp->scndx == SHN_COMMON) 156925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 157025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the alignment requirement. */ 157125b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->merge.value = sym->st_value; 157225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 157325b3c049e70834cf33790a28643ab058b507b35cBen Cheng CDBL_LIST_ADD_REAR (ld_state.common_syms, newp); 157425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 157525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 157625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Insert the new symbol. */ 157725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_symbol_tab_insert (&ld_state.symbol_tab, 157825b3c049e70834cf33790a28643ab058b507b35cBen Cheng hval, newp) != 0)) 157925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot happen. */ 158025b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 158125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 158225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->symref[cnt] = newp; 158325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 158425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have a few special symbols to recognize. The symbols 158525b3c049e70834cf33790a28643ab058b507b35cBen Cheng _init and _fini are the initialization and finalization 158625b3c049e70834cf33790a28643ab058b507b35cBen Cheng functions respectively. They have to be made known in 158725b3c049e70834cf33790a28643ab058b507b35cBen Cheng the dynamic section and therefore we have to find out 158825b3c049e70834cf33790a28643ab058b507b35cBen Cheng now whether these functions exist or not. */ 158925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (hval == 6685956 && strcmp (newp->name, "_init") == 0) 159025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.init_symbol = newp; 159125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (hval == 6672457 && strcmp (newp->name, "_fini") == 0) 159225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.fini_symbol = newp; 159325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 159425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (check_definition (sym, shndx, cnt, fileinfo, oldp) 159525b3c049e70834cf33790a28643ab058b507b35cBen Cheng != 0)) 159625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* A fatal error (multiple definition of a symbol) 159725b3c049e70834cf33790a28643ab058b507b35cBen Cheng occurred, no need to continue. */ 159825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 159925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 160025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use the previously allocated symbol record. It has 160125b3c049e70834cf33790a28643ab058b507b35cBen Cheng been updated in check_definition(), if necessary. */ 160225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = fileinfo->symref[cnt] = oldp; 160325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 160425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Mark the section the symbol we need comes from as used. */ 160525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shndx != SHN_UNDEF 160625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shndx < SHN_LORESERVE || shndx > SHN_HIRESERVE)) 160725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 160825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *ignore; 160925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 161025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 161125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shnum; 161225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (elf_getshdrnum (fileinfo->elf, &shnum) == 0); 161325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shndx < shnum); 161425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 161525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 161625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Mark section (and all dependencies) as used. */ 161725b3c049e70834cf33790a28643ab058b507b35cBen Cheng mark_section_used (&fileinfo->scninfo[shndx], shndx, &ignore); 161825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 161925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether the section is merge-able. In this case we 162025b3c049e70834cf33790a28643ab058b507b35cBen Cheng have to record the symbol. */ 162125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (SCNINFO_SHDR (fileinfo->scninfo[shndx].shdr).sh_flags 162225b3c049e70834cf33790a28643ab058b507b35cBen Cheng & SHF_MERGE) 162325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 162425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->scninfo[shndx].symbols == NULL) 162525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[shndx].symbols = newp->next_in_scn 162625b3c049e70834cf33790a28643ab058b507b35cBen Cheng = newp; 162725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 162825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 162925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->next_in_scn 163025b3c049e70834cf33790a28643ab058b507b35cBen Cheng = fileinfo->scninfo[shndx].symbols->next_in_scn; 163125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->scninfo[shndx].symbols 163225b3c049e70834cf33790a28643ab058b507b35cBen Cheng = fileinfo->scninfo[shndx].symbols->next_in_scn = newp; 163325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 163425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 163525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 163625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 163725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 163825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This file is used. */ 163925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fileinfo->file_type == relocatable_file_type)) 164025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 164125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_state.relfiles == NULL)) 164225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.relfiles = fileinfo->next = fileinfo; 164325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 164425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 164525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->next = ld_state.relfiles->next; 164625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.relfiles = ld_state.relfiles->next = fileinfo; 164725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 164825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 164925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Update some summary information in the state structure. */ 165025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.nsymtab += fileinfo->nsymtab; 165125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.nlocalsymbols += fileinfo->nlocalsymbols; 165225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 165325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (likely (fileinfo->file_type == dso_file_type)) 165425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 165525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CSNGL_LIST_ADD_REAR (ld_state.dsofiles, fileinfo); 165625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.ndsofiles; 165725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 165825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->lazyload) 165925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to create another dynamic section entry for the 166025b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_POSFLAG_1 entry. 166125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 166225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XXX Once more functionality than the lazyloading flag 166325b3c049e70834cf33790a28643ab058b507b35cBen Cheng are suppported the test must be extended. */ 166425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.ndsofiles; 166525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 166625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 166725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 166825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 166925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 167025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 167125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 167225b3c049e70834cf33790a28643ab058b507b35cBen Chengint 167325b3c049e70834cf33790a28643ab058b507b35cBen Chengld_handle_filename_list (struct filename_list *fnames) 167425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 167525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct filename_list *runp; 167625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int res = 0; 167725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 167825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (runp = fnames; runp != NULL; runp = runp->next) 167925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 168025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *curp; 168125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 168225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create a record for the new file. */ 168325b3c049e70834cf33790a28643ab058b507b35cBen Cheng curp = runp->real = ld_new_inputfile (runp->name, relocatable_file_type); 168425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 168525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set flags for group handling. */ 168625b3c049e70834cf33790a28643ab058b507b35cBen Cheng curp->group_start = runp->group_start; 168725b3c049e70834cf33790a28643ab058b507b35cBen Cheng curp->group_end = runp->group_end; 168825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 168925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set as-needed flag from the file, not the command line. */ 169025b3c049e70834cf33790a28643ab058b507b35cBen Cheng curp->as_needed = runp->as_needed; 169125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 169225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Read the file and everything else which comes up, including 169325b3c049e70834cf33790a28643ab058b507b35cBen Cheng handling groups. */ 169425b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 169525b3c049e70834cf33790a28643ab058b507b35cBen Cheng res |= FILE_PROCESS (-1, curp, &ld_state, &curp); 169625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (curp != NULL); 169725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 169825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 169925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Free the list. */ 170025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (fnames != NULL) 170125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 170225b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = fnames; 170325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fnames = fnames->next; 170425b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (runp); 170525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 170625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 170725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return res; 170825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 170925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 171025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 171125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle opening of the given file with ELF descriptor. */ 171225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 171325b3c049e70834cf33790a28643ab058b507b35cBen Chengopen_elf (struct usedfiles *fileinfo, Elf *elf) 171425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 171525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int res = 0; 171625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 171725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf == NULL) 171825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 171925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get descriptor for ELF file (%s:%d): %s\n"), 172025b3c049e70834cf33790a28643ab058b507b35cBen Cheng __FILE__, __LINE__, elf_errmsg (-1)); 172125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 172225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_kind (elf) == ELF_K_NONE)) 172325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 172425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct filename_list *fnames; 172525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 172625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't have to look at this file again. */ 172725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->status = closed; 172825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 172925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Let's see whether this is a linker script. */ 173025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->fd != -1) 173125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create a stream from the file handle we know. */ 173225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ldin = fdopen (fileinfo->fd, "r"); 173325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 173425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 173525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the memory for the archive member. */ 173625b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *content; 173725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t contentsize; 173825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 173925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the content of the file. */ 174025b3c049e70834cf33790a28643ab058b507b35cBen Cheng content = elf_rawfile (elf, &contentsize); 174125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (content == NULL) 174225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 174325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("%s: invalid ELF file (%s:%d)\n"), 174425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, __FILE__, __LINE__); 174525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 174625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 174725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 174825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The content of the file is available in memory. Read the 174925b3c049e70834cf33790a28643ab058b507b35cBen Cheng memory region as a stream. */ 175025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ldin = fmemopen (content, contentsize, "r"); 175125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 175225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 175325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No need for locking. */ 175425b3c049e70834cf33790a28643ab058b507b35cBen Cheng __fsetlocking (ldin, FSETLOCKING_BYCALLER); 175525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 175625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ldin == NULL) 175725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("cannot open '%s'"), 175825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname); 175925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 176025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Parse the file. If it is a linker script no problems will be 176125b3c049e70834cf33790a28643ab058b507b35cBen Cheng reported. */ 176225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.srcfiles = NULL; 176325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ldlineno = 1; 176425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_scan_version_script = 0; 176525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ldin_fname = fileinfo->rfname; 176625b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = ldparse (); 176725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 176825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fclose (ldin); 176925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->fd != -1 && !fileinfo->fd_passed) 177025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 177125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We won't need the file descriptor again. */ 177225b3c049e70834cf33790a28643ab058b507b35cBen Cheng close (fileinfo->fd); 177325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fd = -1; 177425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 177525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 177625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_end (elf); 177725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 177825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (res != 0)) 177925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Something went wrong during parsing. */ 178025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 178125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 178225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is no ELF file. */ 178325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->elf = NULL; 178425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 178525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now we have to handle eventual INPUT and GROUP statements in 178625b3c049e70834cf33790a28643ab058b507b35cBen Cheng the script. Read the files mentioned. */ 178725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fnames = ld_state.srcfiles; 178825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fnames != NULL) 178925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 179025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct filename_list *oldp; 179125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 179225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Convert the list into a normal single-linked list. */ 179325b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp = fnames; 179425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fnames = fnames->next; 179525b3c049e70834cf33790a28643ab058b507b35cBen Cheng oldp->next = NULL; 179625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 179725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remove the list from the state structure. */ 179825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.srcfiles = NULL; 179925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 180025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_handle_filename_list (fnames) != 0)) 180125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 180225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 180325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 180425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 180525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 180625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 180725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the file info. */ 180825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->elf = elf; 180925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 181025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The file is ready for action. */ 181125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->status = opened; 181225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 181325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 181425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 181525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 181625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 181725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 181825b3c049e70834cf33790a28643ab058b507b35cBen Chengadd_whole_archive (struct usedfiles *fileinfo) 181925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 182025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *arelf; 182125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Cmd cmd = ELF_C_READ_MMAP_PRIVATE; 182225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int res = 0; 182325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 182425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((arelf = elf_begin (fileinfo->fd, cmd, fileinfo->elf)) != NULL) 182525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 182625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Arhdr *arhdr = elf_getarhdr (arelf); 182725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *newp; 182825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 182925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (arhdr == NULL) 183025b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 183125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 183225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Just to be sure; since these are no files in the archive 183325b3c049e70834cf33790a28643ab058b507b35cBen Cheng these names should never be returned. */ 183425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (strcmp (arhdr->ar_name, "/") != 0); 183525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (strcmp (arhdr->ar_name, "//") != 0); 183625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 183725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = ld_new_inputfile (arhdr->ar_name, relocatable_file_type); 183825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->archive_file = fileinfo; 183925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 184025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_state.trace_files)) 184125b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_name (stdout, newp, 1, 1); 184225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 184325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This shows that this file is contained in an archive. */ 184425b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->fd = -1; 184525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the ELF descriptor. */ 184625b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->elf = arelf; 184725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Show that we are open for business. */ 184825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->status = opened; 184925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 185025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Proces the file, add all the symbols etc. */ 185125b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = file_process2 (newp); 185225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (res != 0)) 185325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 185425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 185525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Advance to the next archive element. */ 185625b3c049e70834cf33790a28643ab058b507b35cBen Cheng cmd = elf_next (arelf); 185725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 185825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 185925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return res; 186025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 186125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 186225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 186325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 186425b3c049e70834cf33790a28643ab058b507b35cBen Chengextract_from_archive (struct usedfiles *fileinfo) 186525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 186625b3c049e70834cf33790a28643ab058b507b35cBen Cheng static int archive_seq; 186725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int res = 0; 186825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 186925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->archive_seq == 0) 187025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is an archive we are not using completely. Give it a 187125b3c049e70834cf33790a28643ab058b507b35cBen Cheng unique number. */ 187225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->archive_seq = ++archive_seq; 187325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 187425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If there are no unresolved symbols don't do anything. */ 187525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.extract_rule == defaultextract 187625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ld_state.extract_rule == weakextract); 187725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((likely (ld_state.extract_rule == defaultextract) 187825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ld_state.nunresolved_nonweak : ld_state.nunresolved) == 0) 187925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 188025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 188125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Arsym *syms; 188225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsyms; 188325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 188425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get all the symbols. */ 188525b3c049e70834cf33790a28643ab058b507b35cBen Cheng syms = elf_getarsym (fileinfo->elf, &nsyms); 188625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (syms == NULL) 188725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 188825b3c049e70834cf33790a28643ab058b507b35cBen Cheng cannot_read_archive: 188925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot read archive `%s': %s"), 189025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, elf_errmsg (-1)); 189125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 189225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We cannot use this archive anymore. */ 189325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->status = closed; 189425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 189525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 189625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 189725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 189825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now add all the symbols to the hash table. Note that there 189925b3c049e70834cf33790a28643ab058b507b35cBen Cheng can potentially be duplicate definitions. We'll always use 190025b3c049e70834cf33790a28643ab058b507b35cBen Cheng the first definition. */ 190125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Is this a compatible behavior? 190225b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool any_used; 190325b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 190425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 190525b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_used = false; 190625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 190725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 190825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < nsyms; ++cnt) 190925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 191025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol search = { .name = syms[cnt].as_name }; 191125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *sym = ld_symbol_tab_find (&ld_state.symbol_tab, 191225b3c049e70834cf33790a28643ab058b507b35cBen Cheng syms[cnt].as_hash, &search); 191325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym != NULL && ! sym->defined) 191425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 191525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The symbol is referenced and not defined. */ 191625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *arelf; 191725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Arhdr *arhdr; 191825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *newp; 191925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 192025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the archive member for this symbol. */ 192125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_rand (fileinfo->elf, syms[cnt].as_off) 192225b3c049e70834cf33790a28643ab058b507b35cBen Cheng != syms[cnt].as_off)) 192325b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto cannot_read_archive; 192425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 192525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note: no test of a failing 'elf_begin' call. That's fine 192625b3c049e70834cf33790a28643ab058b507b35cBen Cheng since 'elf'getarhdr' will report the problem. */ 192725b3c049e70834cf33790a28643ab058b507b35cBen Cheng arelf = elf_begin (fileinfo->fd, ELF_C_READ_MMAP_PRIVATE, 192825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->elf); 192925b3c049e70834cf33790a28643ab058b507b35cBen Cheng arhdr = elf_getarhdr (arelf); 193025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (arhdr == NULL) 193125b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto cannot_read_archive; 193225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 193325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have all the information and an ELF handle for the 193425b3c049e70834cf33790a28643ab058b507b35cBen Cheng archive member. Create the normal data structure for 193525b3c049e70834cf33790a28643ab058b507b35cBen Cheng a file now. */ 193625b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = ld_new_inputfile (obstack_strdup (&ld_state.smem, 193725b3c049e70834cf33790a28643ab058b507b35cBen Cheng arhdr->ar_name), 193825b3c049e70834cf33790a28643ab058b507b35cBen Cheng relocatable_file_type); 193925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->archive_file = fileinfo; 194025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 194125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_state.trace_files)) 194225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_name (stdout, newp, 1, 1); 194325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 194425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This shows that this file is contained in an archive. */ 194525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->fd = -1; 194625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the ELF descriptor. */ 194725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->elf = arelf; 194825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Show that we are open for business. */ 194925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->status = in_archive; 195025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 195125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now read the file and add all the symbols. */ 195225b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = file_process2 (newp); 195325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (res != 0)) 195425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return res; 195525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 195625b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_used = true; 195725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 195825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 195925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 196025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (any_used) 196125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 196225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is an archive therefore it must have a number. */ 196325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fileinfo->archive_seq != 0); 196425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.last_archive_used = fileinfo->archive_seq; 196525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 196625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 196725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (any_used); 196825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 196925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return res; 197025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 197125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 197225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 197325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 197425b3c049e70834cf33790a28643ab058b507b35cBen Chengfile_process2 (struct usedfiles *fileinfo) 197525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 197625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int res; 197725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 197825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (elf_kind (fileinfo->elf) == ELF_K_ELF)) 197925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 198025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The first time we get here we read the ELF header. */ 198125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF != 0 198225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fileinfo->ehdr == NULL)) 198325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 198425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (FILEINFO_EHDR (fileinfo->ehdr).e_type == ET_NONE)) 198525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 198625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 198725b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Ehdr *ehdr; 198825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF != 0 198925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr = xelf_getehdr (fileinfo->elf, fileinfo->ehdr); 199025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 199125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getehdr_copy (fileinfo->elf, ehdr, fileinfo->ehdr); 199225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 199325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr == NULL) 199425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 199525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("%s: invalid ELF file (%s:%d)\n"), 199625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, __FILE__, __LINE__); 199725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->status = closed; 199825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 199925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 200025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 200125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (FILEINFO_EHDR (fileinfo->ehdr).e_type != ET_REL 200225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && unlikely (FILEINFO_EHDR (fileinfo->ehdr).e_type != ET_DYN)) 200325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Add ebl* function to query types which are allowed 200425b3c049e70834cf33790a28643ab058b507b35cBen Cheng to link in. */ 200525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 200625b3c049e70834cf33790a28643ab058b507b35cBen Cheng char buf[64]; 200725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 200825b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_name (stderr, fileinfo, 1, 0); 200925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, 201025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("file of type %s cannot be linked in\n"), 201125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_object_type_name (ld_state.ebl, 201225b3c049e70834cf33790a28643ab058b507b35cBen Cheng FILEINFO_EHDR (fileinfo->ehdr).e_type, 201325b3c049e70834cf33790a28643ab058b507b35cBen Cheng buf, sizeof (buf))); 201425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->status = closed; 201525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 201625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 201725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 201825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make sure the file type matches the backend. */ 201925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (FILEINFO_EHDR (fileinfo->ehdr).e_machine 202025b3c049e70834cf33790a28643ab058b507b35cBen Cheng != ebl_get_elfmachine (ld_state.ebl)) 202125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 202225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("\ 202325b3c049e70834cf33790a28643ab058b507b35cBen Cheng%s: input file incompatible with ELF machine type %s\n"), 202425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, 202525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_backend_name (ld_state.ebl)); 202625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->status = closed; 202725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 202825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 202925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 203025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the section header string table section index. */ 203125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elf_getshdrstrndx (fileinfo->elf, &fileinfo->shstrndx) 203225b3c049e70834cf33790a28643ab058b507b35cBen Cheng < 0)) 203325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 203425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stderr, gettext ("\ 203525b3c049e70834cf33790a28643ab058b507b35cBen Cheng%s: cannot get section header string table index: %s\n"), 203625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->rfname, elf_errmsg (-1)); 203725b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->status = closed; 203825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 203925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 204025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 204125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 204225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now handle the different types of files. */ 204325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (FILEINFO_EHDR (fileinfo->ehdr).e_type == ET_REL) 204425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 204525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add all the symbol. Relocatable files have symbol 204625b3c049e70834cf33790a28643ab058b507b35cBen Cheng tables. */ 204725b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = add_relocatable_file (fileinfo, SHT_SYMTAB); 204825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 204925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 205025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 205125b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool has_l_name = fileinfo->file_type == archive_file_type; 205225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 205325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (FILEINFO_EHDR (fileinfo->ehdr).e_type == ET_DYN); 205425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 205525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the file is a DT_NEEDED dependency then the type is 205625b3c049e70834cf33790a28643ab058b507b35cBen Cheng already correctly specified. */ 205725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->file_type != dso_needed_file_type) 205825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->file_type = dso_file_type; 205925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 206025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We cannot use DSOs when generating relocatable objects. */ 206125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type == relocatable_file_type) 206225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 206325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("\ 206425b3c049e70834cf33790a28643ab058b507b35cBen Chengcannot use DSO '%s' when generating relocatable object file"), 206525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fname); 206625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 206725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 206825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 206925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add all the symbols. For DSOs we are looking at the 207025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynamic symbol table. */ 207125b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = add_relocatable_file (fileinfo, SHT_DYNSYM); 207225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 207325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We always have to have a dynamic section. */ 207425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fileinfo->dynscn != NULL); 207525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 207625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to remember the dependencies for this object. It 207725b3c049e70834cf33790a28643ab058b507b35cBen Cheng is necessary to look them up. */ 207825b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr_vardef (dynshdr); 207925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (fileinfo->dynscn, dynshdr); 208025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 208125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *dyndata = elf_getdata (fileinfo->dynscn, NULL); 208225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Should we flag the failure to get the dynamic section? */ 208325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dynshdr != NULL) 208425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 208525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int cnt = dynshdr->sh_size / dynshdr->sh_entsize; 208625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Dyn_vardef (dyn); 208725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 208825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (--cnt >= 0) 208925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 209025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getdyn (dyndata, cnt, dyn); 209125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dyn != NULL) 209225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 209325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if(dyn->d_tag == DT_NEEDED) 209425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 209525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *newp; 209625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 209725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = ld_new_inputfile (elf_strptr (fileinfo->elf, 209825b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynshdr->sh_link, 209925b3c049e70834cf33790a28643ab058b507b35cBen Cheng dyn->d_un.d_val), 210025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dso_needed_file_type); 210125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 210225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Enqueue the newly found dependencies. */ 210325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Check that there not already a file with the 210425b3c049e70834cf33790a28643ab058b507b35cBen Cheng // same name. 210525b3c049e70834cf33790a28643ab058b507b35cBen Cheng CSNGL_LIST_ADD_REAR (ld_state.needed, newp); 210625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 210725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (dyn->d_tag == DT_SONAME) 210825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 210925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We use the DT_SONAME (this is what's there 211025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for). */ 211125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->soname = elf_strptr (fileinfo->elf, 211225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynshdr->sh_link, 211325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dyn->d_un.d_val); 211425b3c049e70834cf33790a28643ab058b507b35cBen Cheng has_l_name = false; 211525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 211625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 211725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 211825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 211925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 212025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Construct the file name if the DSO has no SONAME and the 212125b3c049e70834cf33790a28643ab058b507b35cBen Cheng file name comes from a -lXX parameter on the comment 212225b3c049e70834cf33790a28643ab058b507b35cBen Cheng line. */ 212325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (has_l_name)) 212425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 212525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The FNAME is the parameter the user specified on the 212625b3c049e70834cf33790a28643ab058b507b35cBen Cheng command line. We prepend "lib" and append ".so". */ 212725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len = strlen (fileinfo->fname) + 7; 212825b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *newp; 212925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 213025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = (char *) obstack_alloc (&ld_state.smem, len); 213125b3c049e70834cf33790a28643ab058b507b35cBen Cheng strcpy (stpcpy (stpcpy (newp, "lib"), fileinfo->fname), ".so"); 213225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 213325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->soname = newp; 213425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 213525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 213625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 213725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (likely (elf_kind (fileinfo->elf) == ELF_K_AR)) 213825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 213925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_state.extract_rule == allextract)) 214025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Which this option enabled we have to add all the object 214125b3c049e70834cf33790a28643ab058b507b35cBen Cheng files in the archive. */ 214225b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = add_whole_archive (fileinfo); 214325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (ld_state.file_type == relocatable_file_type) 214425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 214525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When generating a relocatable object we don't find files 214625b3c049e70834cf33790a28643ab058b507b35cBen Cheng in archives. */ 214725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (verbose) 214825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("input file '%s' ignored"), fileinfo->fname); 214925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 215025b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = 0; 215125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 215225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 215325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 215425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.group_start_requested 215525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && ld_state.group_start_archive == NULL) 215625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.group_start_archive = fileinfo; 215725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 215825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.archives == NULL) 215925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.archives = fileinfo; 216025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 216125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.tailarchives != NULL) 216225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.tailarchives->next = fileinfo; 216325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.tailarchives = fileinfo; 216425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 216525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Extract only the members from the archive which are 216625b3c049e70834cf33790a28643ab058b507b35cBen Cheng currently referenced by unresolved symbols. */ 216725b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = extract_from_archive (fileinfo); 216825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 216925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 217025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 217125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This should never happen, we know about no other types. */ 217225b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 217325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 217425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return res; 217525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 217625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 217725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 217825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Process a given file. The first parameter is a file descriptor for 217925b3c049e70834cf33790a28643ab058b507b35cBen Cheng the file which can be -1 to indicate the file has not yet been 218025b3c049e70834cf33790a28643ab058b507b35cBen Cheng found. The second parameter describes the file to be opened, the 218125b3c049e70834cf33790a28643ab058b507b35cBen Cheng last one is the state of the linker which among other information 218225b3c049e70834cf33790a28643ab058b507b35cBen Cheng contain the paths we look at. */ 218325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 218425b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_file_process (int fd, struct usedfiles *fileinfo, 218525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct ld_state *statep, struct usedfiles **nextp) 218625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 218725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int res = 0; 218825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 218925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* By default we go to the next file in the list. */ 219025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *nextp = fileinfo->next; 219125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 219225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set the flag to signal we are looking for a group start. */ 219325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (fileinfo->group_start)) 219425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 219525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.group_start_requested = true; 219625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->group_start = false; 219725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 219825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 219925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the file isn't open yet, open it now. */ 220025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fileinfo->status == not_opened)) 220125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 220225b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool fd_passed = true; 220325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 220425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fd == -1)) 220525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 220625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Find the file ourselves. */ 220725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int err = open_along_path (fileinfo); 220825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (err != 0)) 220925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We allow libraries and DSOs to be named more than once. 221025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Don't report an error to the caller. */ 221125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return err == EAGAIN ? 0 : err; 221225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 221325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fd_passed = false; 221425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 221525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 221625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fd = fd; 221725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 221825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember where we got the descriptor from. */ 221925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->fd_passed = fd_passed; 222025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 222125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We found the file. Now test whether it is a file type we can 222225b3c049e70834cf33790a28643ab058b507b35cBen Cheng handle. 222325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 222425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XXX Do we need to have the ability to start from a given 222525b3c049e70834cf33790a28643ab058b507b35cBen Cheng position in the search path again to look for another file if 222625b3c049e70834cf33790a28643ab058b507b35cBen Cheng the one found has not the right type? */ 222725b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = open_elf (fileinfo, elf_begin (fileinfo->fd, 222825b3c049e70834cf33790a28643ab058b507b35cBen Cheng is_dso_p (fileinfo->fd) 222925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ELF_C_READ_MMAP 223025b3c049e70834cf33790a28643ab058b507b35cBen Cheng : ELF_C_READ_MMAP_PRIVATE, NULL)); 223125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (res != 0)) 223225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return res; 223325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 223425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 223525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now that we have opened the file start processing it. */ 223625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fileinfo->status != closed)) 223725b3c049e70834cf33790a28643ab058b507b35cBen Cheng res = file_process2 (fileinfo); 223825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 223925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine which file to look at next. */ 224025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (fileinfo->group_backref != NULL)) 224125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 224225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We only go back if an archive other than the one we would go 224325b3c049e70834cf33790a28643ab058b507b35cBen Cheng back to has been used in the last round. */ 224425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.last_archive_used > fileinfo->group_backref->archive_seq) 224525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 224625b3c049e70834cf33790a28643ab058b507b35cBen Cheng *nextp = fileinfo->group_backref; 224725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.last_archive_used = 0; 224825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 224925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 225025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 225125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we come here this means that the archives we read so 225225b3c049e70834cf33790a28643ab058b507b35cBen Cheng far are not needed anymore. We can free some of the data 225325b3c049e70834cf33790a28643ab058b507b35cBen Cheng now. */ 225425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *runp = ld_state.archives; 225525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 225625b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 225725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 225825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't need the ELF descriptor anymore. Unless there 225925b3c049e70834cf33790a28643ab058b507b35cBen Cheng are no files from the archive used this will not free 226025b3c049e70834cf33790a28643ab058b507b35cBen Cheng the whole file but only some data structures. */ 226125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_end (runp->elf); 226225b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->elf = NULL; 226325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 226425b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = runp->next; 226525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 226625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (runp != fileinfo->next); 226725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 226825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Do not do this again. */ 226925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.archives = NULL; 227025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 227125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Do not move on to the next archive. */ 227225b3c049e70834cf33790a28643ab058b507b35cBen Cheng *nextp = fileinfo->next = NULL; 227325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 227425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 227525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (fileinfo->group_end)) 227625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 227725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is the end of a group. We possibly have to go back. 227825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Determine which file we would go back to and see whether it 227925b3c049e70834cf33790a28643ab058b507b35cBen Cheng makes sense. If there has not been an archive we don't have 228025b3c049e70834cf33790a28643ab058b507b35cBen Cheng to do anything. */ 228125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.group_start_requested) 228225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 228325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.group_start_archive != ld_state.tailarchives) 228425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The loop includes more than one archive, add the pointer. */ 228525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 228625b3c049e70834cf33790a28643ab058b507b35cBen Cheng *nextp = ld_state.tailarchives->group_backref = 228725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.group_start_archive; 228825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.last_archive_used = 0; 228925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 229025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 229125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We might still have to go back to the beginning of the 229225b3c049e70834cf33790a28643ab058b507b35cBen Cheng group if since the last archive other files have been 229325b3c049e70834cf33790a28643ab058b507b35cBen Cheng added. But we go back exactly once. */ 229425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.tailarchives != fileinfo) 229525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 229625b3c049e70834cf33790a28643ab058b507b35cBen Cheng *nextp = ld_state.group_start_archive; 229725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.last_archive_used = 0; 229825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 229925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 230025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 230125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Clear the flags. */ 230225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.group_start_requested = false; 230325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.group_start_archive = NULL; 230425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fileinfo->group_end = false; 230525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 230625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 230725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return res; 230825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 230925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 231025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 231125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Library names passed to the linker as -lXX represent files named 231225b3c049e70834cf33790a28643ab058b507b35cBen Cheng libXX.YY. The YY part can have different forms, depending on the 231325b3c049e70834cf33790a28643ab058b507b35cBen Cheng platform. The generic set is .so and .a (in this order). */ 231425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char ** 231525b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_lib_extensions (struct ld_state *statep __attribute__ ((__unused__))) 231625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 231725b3c049e70834cf33790a28643ab058b507b35cBen Cheng static const char *exts[] = 231825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 231925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ".so", ".a", NULL 232025b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 232125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 232225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return exts; 232325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 232425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 232525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 232625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Flag unresolved symbols. */ 232725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 232825b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_flag_unresolved (struct ld_state *statep) 232925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 233025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int retval = 0; 233125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 233225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.nunresolved_nonweak > 0) 233325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 233425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Go through the list and determine the unresolved symbols. */ 233525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *first; 233625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *s; 233725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 233825b3c049e70834cf33790a28643ab058b507b35cBen Cheng s = first = ld_state.unresolved->next; 233925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 234025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 234125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! s->defined && ! s->weak) 234225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 234325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Two special symbol we recognize: the symbol for the 234425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GOT and the dynamic section. */ 234525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (s->name, "_GLOBAL_OFFSET_TABLE_") == 0 234625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || strcmp (s->name, "_DYNAMIC") == 0) 234725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 234825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We will have to fill in more information later. */ 234925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.need_got = true; 235025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 235125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember that we found it. */ 235225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (s->name[1] == 'G') 235325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.got_symbol = s; 235425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 235525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.dyn_symbol = s; 235625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 235725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (ld_state.file_type != dso_file_type || !ld_state.nodefs) 235825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 235925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX The error message should get better. It should use 236025b3c049e70834cf33790a28643ab058b507b35cBen Cheng the debugging information if present to tell where in the 236125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sources the undefined reference is. */ 236225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("undefined symbol `%s' in %s"), 236325b3c049e70834cf33790a28643ab058b507b35cBen Cheng s->name, s->file->fname); 236425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 236525b3c049e70834cf33790a28643ab058b507b35cBen Cheng retval = 1; 236625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 236725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 236825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 236925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We cannot decide here what to do with undefined 237025b3c049e70834cf33790a28643ab058b507b35cBen Cheng references which will come from DSO since we do not know 237125b3c049e70834cf33790a28643ab058b507b35cBen Cheng what kind of symbol we expect. Only when looking at the 237225b3c049e70834cf33790a28643ab058b507b35cBen Cheng relocations we can see whether we need a PLT entry or 237325b3c049e70834cf33790a28643ab058b507b35cBen Cheng only a GOT entry. */ 237425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 237525b3c049e70834cf33790a28643ab058b507b35cBen Cheng s = s->next; 237625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 237725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (s != first); 237825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 237925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 238025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return retval; 238125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 238225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 238325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 238425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Close the given file. */ 238525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 238625b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_file_close (struct usedfiles *fileinfo, struct ld_state *statep) 238725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 238825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Close the ELF descriptor. */ 238925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_end (fileinfo->elf); 239025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 239125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we have opened the file descriptor close it. But we might 239225b3c049e70834cf33790a28643ab058b507b35cBen Cheng have done this already in which case FD is -1. */ 239325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!fileinfo->fd_passed && fileinfo->fd != -1) 239425b3c049e70834cf33790a28643ab058b507b35cBen Cheng close (fileinfo->fd); 239525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 239625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We allocated the resolved file name. */ 239725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fileinfo->fname != fileinfo->rfname) 239825b3c049e70834cf33790a28643ab058b507b35cBen Cheng free ((char *) fileinfo->rfname); 239925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 240025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 240125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 240225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 240325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 240425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 240525b3c049e70834cf33790a28643ab058b507b35cBen Chengnew_generated_scn (enum scn_kind kind, const char *name, int type, int flags, 240625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int entsize, int align) 240725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 240825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead *newp; 240925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 241025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = (struct scnhead *) obstack_calloc (&ld_state.smem, 241125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (struct scnhead)); 241225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->kind = kind; 241325b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->name = name; 241425b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->nameent = ebl_strtabadd (ld_state.shstrtab, name, 0); 241525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->type = type; 241625b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->flags = flags; 241725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->entsize = entsize; 241825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->align = align; 241925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->grp_signature = NULL; 242025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->used = true; 242125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 242225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* All is well. Create now the data for the section and insert it 242325b3c049e70834cf33790a28643ab058b507b35cBen Cheng into the section table. */ 242425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_section_tab_insert (&ld_state.section_tab, elf_hash (name), newp); 242525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 242625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 242725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 242825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Create the sections which are generated by the linker and are not 242925b3c049e70834cf33790a28643ab058b507b35cBen Cheng present in the input file. */ 243025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 243125b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_generate_sections (struct ld_state *statep) 243225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 243325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The relocation section type. */ 243425b3c049e70834cf33790a28643ab058b507b35cBen Cheng int rel_type = REL_TYPE (&ld_state) == DT_REL ? SHT_REL : SHT_RELA; 243525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 243625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When requested, every output file will have a build ID section. */ 243725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (statep->build_id != NULL) 243825b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_note_gnu_build_id, ".note.gnu.build-id", 243925b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHT_NOTE, SHF_ALLOC, 0, 4); 244025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 244125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When building dynamically linked object we have to include a 244225b3c049e70834cf33790a28643ab058b507b35cBen Cheng section containing a string describing the interpreter. This 244325b3c049e70834cf33790a28643ab058b507b35cBen Cheng should be at the very beginning of the file together with the 244425b3c049e70834cf33790a28643ab058b507b35cBen Cheng other information the ELF loader (kernel or wherever) has to look 244525b3c049e70834cf33790a28643ab058b507b35cBen Cheng at. We put it as the first section in the file. 244625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 244725b3c049e70834cf33790a28643ab058b507b35cBen Cheng We also have to create the dynamic segment which is a special 244825b3c049e70834cf33790a28643ab058b507b35cBen Cheng section the dynamic linker locates through an entry in the 244925b3c049e70834cf33790a28643ab058b507b35cBen Cheng program header. */ 245025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dynamically_linked_p ()) 245125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 245225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use any versioning (defined or required)? */ 245325b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool use_versioning = false; 245425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use version requirements? */ 245525b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool need_version = false; 245625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 245725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First the .interp section. */ 245825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.interp != NULL || ld_state.file_type != dso_file_type) 245925b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_interp, ".interp", SHT_PROGBITS, SHF_ALLOC, 246025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 0, 1); 246125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 246225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now the .dynamic section. */ 246325b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_dynamic, ".dynamic", SHT_DYNAMIC, 246425b3c049e70834cf33790a28643ab058b507b35cBen Cheng DYNAMIC_SECTION_FLAGS (&ld_state), 246525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_DYN, 1), 246625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1)); 246725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 246825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We will need in any case the dynamic symbol table (even in 246925b3c049e70834cf33790a28643ab058b507b35cBen Cheng the unlikely case that no symbol is exported or referenced 247025b3c049e70834cf33790a28643ab058b507b35cBen Cheng from a DSO). */ 247125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.need_dynsym = true; 247225b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_dynsym, ".dynsym", SHT_DYNSYM, SHF_ALLOC, 247325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_SYM, 1), 247425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1)); 247525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* It comes with a string table. */ 247625b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_dynstr, ".dynstr", SHT_STRTAB, SHF_ALLOC, 247725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 0, 1); 247825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And a hashing table. */ 247925b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX For Linux/Alpha we need other sizes unless they change... 248025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (GENERATE_SYSV_HASH) 248125b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_hash, ".hash", SHT_HASH, SHF_ALLOC, 248225b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (Elf32_Word), sizeof (Elf32_Word)); 248325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (GENERATE_GNU_HASH) 248425b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_gnu_hash, ".gnu.hash", SHT_GNU_HASH, 248525b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHF_ALLOC, sizeof (Elf32_Word), 248625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (Elf32_Word)); 248725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 248825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the section associated with the PLT if necessary. */ 248925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.nplt > 0) 249025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 249125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the .plt section. */ 249225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX We might need a function which returns the section flags. */ 249325b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_plt, ".plt", SHT_PROGBITS, 249425b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHF_ALLOC | SHF_EXECINSTR, 249525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Is the size correct? */ 249625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1), 249725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1)); 249825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 249925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the relocation section for the .plt. This is always 250025b3c049e70834cf33790a28643ab058b507b35cBen Cheng separate even if the other relocation sections are combined. */ 250125b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_pltrel, ".rel.plt", rel_type, SHF_ALLOC, 250225b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel_type == SHT_REL 250325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? xelf_fsize (ld_state.outelf, ELF_T_REL, 1) 250425b3c049e70834cf33790a28643ab058b507b35cBen Cheng : xelf_fsize (ld_state.outelf, ELF_T_RELA, 1), 250525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1)); 250625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 250725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX We might need a function which returns the section flags. */ 250825b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_gotplt, ".got.plt", SHT_PROGBITS, 250925b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHF_ALLOC | SHF_WRITE, 251025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1), 251125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1)); 251225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 251325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Mark all used DSOs as used. Determine whether any referenced 251425b3c049e70834cf33790a28643ab058b507b35cBen Cheng object uses symbol versioning. */ 251525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.from_dso != NULL) 251625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 251725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *srunp = ld_state.from_dso; 251825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 251925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 252025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 252125b3c049e70834cf33790a28643ab058b507b35cBen Cheng srunp->file->used = true; 252225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 252325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (srunp->file->verdefdata != NULL) 252425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 252525b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Versym versym; 252625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 252725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The input DSO uses versioning. */ 252825b3c049e70834cf33790a28643ab058b507b35cBen Cheng use_versioning = true; 252925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We reference versions. */ 253025b3c049e70834cf33790a28643ab058b507b35cBen Cheng need_version = true; 253125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 253225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (xelf_getversym_copy (srunp->file->versymdata, 253325b3c049e70834cf33790a28643ab058b507b35cBen Cheng srunp->symidx, versym) == NULL) 253425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (! "xelf_getversym failed"); 253525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 253625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We cannot link explicitly with an older 253725b3c049e70834cf33790a28643ab058b507b35cBen Cheng version of a symbol. */ 253825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((versym & 0x8000) == 0); 253925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We cannot reference local (index 0) or plain 254025b3c049e70834cf33790a28643ab058b507b35cBen Cheng global (index 1) versions. */ 254125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (versym > 1); 254225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 254325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether we have already seen the 254425b3c049e70834cf33790a28643ab058b507b35cBen Cheng version and if not add it to the referenced 254525b3c049e70834cf33790a28643ab058b507b35cBen Cheng versions in the output file. */ 254625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! srunp->file->verdefused[versym]) 254725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 254825b3c049e70834cf33790a28643ab058b507b35cBen Cheng srunp->file->verdefused[versym] = 1; 254925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 255025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (++srunp->file->nverdefused == 1) 255125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Count the file if it is using versioning. */ 255225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nverdeffile; 255325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nverdefused; 255425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 255525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 255625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 255725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((srunp = srunp->next) != ld_state.from_dso); 255825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 255925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 256025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the sections used to record version dependencies. */ 256125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (need_version) 256225b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_version_r, ".gnu.version_r", 256325b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHT_GNU_verneed, SHF_ALLOC, 0, 256425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_WORD, 1)); 256525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 256625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 256725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now count the used DSOs since this is what the user 256825b3c049e70834cf33790a28643ab058b507b35cBen Cheng wants. */ 256925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int ndt_needed = 0; 257025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.ndsofiles > 0) 257125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 257225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *frunp = ld_state.dsofiles; 257325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 257425b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 257525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! frunp->as_needed || frunp->used) 257625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 257725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ndt_needed; 257825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (frunp->lazyload) 257925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to create another dynamic section 258025b3c049e70834cf33790a28643ab058b507b35cBen Cheng entry for the DT_POSFLAG_1 entry. 258125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 258225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XXX Once more functionality than the lazyloading 258325b3c049e70834cf33790a28643ab058b507b35cBen Cheng flag are suppported the test must be 258425b3c049e70834cf33790a28643ab058b507b35cBen Cheng extended. */ 258525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ndt_needed; 258625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 258725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((frunp = frunp->next) != ld_state.dsofiles); 258825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 258925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 259025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (use_versioning) 259125b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_version, ".gnu.version", SHT_GNU_versym, 259225b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHF_ALLOC, 259325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_HALF, 1), 259425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_HALF, 1)); 259525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 259625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We need some entries all the time. */ 259725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.ndynamic = (7 + (ld_state.runpath != NULL 259825b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ld_state.rpath != NULL) 259925b3c049e70834cf33790a28643ab058b507b35cBen Cheng + ndt_needed 260025b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (ld_state.init_symbol != NULL ? 1 : 0) 260125b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (ld_state.fini_symbol != NULL ? 1 : 0) 260225b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (use_versioning ? 1 : 0) 260325b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (need_version ? 2 : 0) 260425b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (ld_state.nplt > 0 ? 4 : 0) 260525b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (ld_state.relsize_total > 0 ? 3 : 0)); 260625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 260725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 260825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When creating a relocatable file or when we are not stripping the 260925b3c049e70834cf33790a28643ab058b507b35cBen Cheng output file we create a symbol table. */ 261025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.need_symtab = (ld_state.file_type == relocatable_file_type 261125b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ld_state.strip == strip_none); 261225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 261325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the .got section if needed. */ 261425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_got) 261525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX We might need a function which returns the section flags. */ 261625b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_got, ".got", SHT_PROGBITS, 261725b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHF_ALLOC | SHF_WRITE, 261825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1), 261925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1)); 262025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 262125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the .rel.dyn section. */ 262225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.relsize_total > 0) 262325b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_generated_scn (scn_dot_dynrel, ".rel.dyn", rel_type, SHF_ALLOC, 262425b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel_type == SHT_REL 262525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? xelf_fsize (ld_state.outelf, ELF_T_REL, 1) 262625b3c049e70834cf33790a28643ab058b507b35cBen Cheng : xelf_fsize (ld_state.outelf, ELF_T_RELA, 1), 262725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1)); 262825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 262925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 263025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 263125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Callback function registered with on_exit to make sure the temporary 263225b3c049e70834cf33790a28643ab058b507b35cBen Cheng files gets removed if something goes wrong. */ 263325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 263425b3c049e70834cf33790a28643ab058b507b35cBen Chengremove_tempfile (int status, void *arg) 263525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 263625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (status != 0 && ld_state.tempfname != NULL) 263725b3c049e70834cf33790a28643ab058b507b35cBen Cheng unlink (ld_state.tempfname); 263825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 263925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 264025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 264125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Create the output file. The file name is given or "a.out". We 264225b3c049e70834cf33790a28643ab058b507b35cBen Cheng create as much of the ELF structure as possible. */ 264325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 264425b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_open_outfile (struct ld_state *statep, int machine, int klass, 264525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int data) 264625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 264725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We do not create the new file right away with the final name. 264825b3c049e70834cf33790a28643ab058b507b35cBen Cheng This would destroy an existing file with this name before a 264925b3c049e70834cf33790a28643ab058b507b35cBen Cheng replacement is finalized. We create instead a temporary file in 265025b3c049e70834cf33790a28643ab058b507b35cBen Cheng the same directory. */ 265125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.outfname == NULL) 265225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.outfname = "a.out"; 265325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 265425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t outfname_len = strlen (ld_state.outfname); 265525b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *tempfname = (char *) obstack_alloc (&ld_state.smem, 265625b3c049e70834cf33790a28643ab058b507b35cBen Cheng outfname_len + sizeof (".XXXXXX")); 265725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.tempfname = tempfname; 265825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 265925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int fd; 266025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int try = 0; 266125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (1) 266225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 266325b3c049e70834cf33790a28643ab058b507b35cBen Cheng strcpy (mempcpy (tempfname, ld_state.outfname, outfname_len), ".XXXXXX"); 266425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 266525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The use of mktemp() here is fine. We do not want to use 266625b3c049e70834cf33790a28643ab058b507b35cBen Cheng mkstemp() since then the umask isn't used. And the output 266725b3c049e70834cf33790a28643ab058b507b35cBen Cheng file will have these permissions anyhow. Any intruder could 266825b3c049e70834cf33790a28643ab058b507b35cBen Cheng change the file later if it would be possible now. */ 266925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (mktemp (tempfname) != NULL 267025b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (fd = open (tempfname, O_RDWR | O_EXCL | O_CREAT | O_NOFOLLOW, 267125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.file_type == relocatable_file_type 267225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? DEFFILEMODE : ACCESSPERMS)) != -1) 267325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 267425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 267525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Failed this round. We keep trying a number of times. */ 267625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (++try >= 10) 267725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("cannot create output file")); 267825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 267925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.outfd = fd; 268025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 268125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make sure we remove the temporary file in case something goes 268225b3c049e70834cf33790a28643ab058b507b35cBen Cheng wrong. */ 268325b3c049e70834cf33790a28643ab058b507b35cBen Cheng on_exit (remove_tempfile, NULL); 268425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 268525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the ELF file data for the output file. */ 268625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *elf = ld_state.outelf = elf_begin (fd, 268725b3c049e70834cf33790a28643ab058b507b35cBen Cheng conserve_memory 268825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ELF_C_WRITE : ELF_C_WRITE_MMAP, 268925b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL); 269025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf == NULL) 269125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 269225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create ELF descriptor for output file: %s"), 269325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 269425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 269525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the basic data structures. */ 269625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! xelf_newehdr (elf, klass)) 269725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Couldn't create the ELF header. Very bad. */ 269825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 269925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("could not create ELF header for output file: %s"), 270025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 270125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 270225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And get the current header so that we can modify it. */ 270325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Ehdr_vardef (ehdr); 270425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getehdr (elf, ehdr); 270525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ehdr != NULL); 270625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 270725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set the machine type. */ 270825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_machine = machine; 270925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 271025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Modify it according to the info we have here and now. */ 271125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type == executable_file_type) 271225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_type = ET_EXEC; 271325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (ld_state.file_type == dso_file_type) 271425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_type = ET_DYN; 271525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 271625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 271725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.file_type == relocatable_file_type); 271825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_type = ET_REL; 271925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 272025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 272125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set the ELF version. */ 272225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_version = EV_CURRENT; 272325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 272425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set the endianness. */ 272525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_ident[EI_DATA] = data; 272625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 272725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Write the ELF header information back. */ 272825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_ehdr (elf, ehdr); 272925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 273025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 273125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 273225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 273325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 273425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* We compute the offsets of the various copied objects and the total 273525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size of the memory needed. */ 273625b3c049e70834cf33790a28643ab058b507b35cBen Cheng// XXX The method used here is simple: go from front to back and pack 273725b3c049e70834cf33790a28643ab058b507b35cBen Cheng// the objects in this order. A more space efficient way would 273825b3c049e70834cf33790a28643ab058b507b35cBen Cheng// actually trying to pack the objects as dense as possible. But this 273925b3c049e70834cf33790a28643ab058b507b35cBen Cheng// is more expensive. 274025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 274125b3c049e70834cf33790a28643ab058b507b35cBen Chengcompute_copy_reloc_offset (XElf_Shdr *shdr) 274225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 274325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *runp = ld_state.from_dso; 274425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (runp != NULL); 274525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 274625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off maxalign = 1; 274725b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off offset = 0; 274825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 274925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 275025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->need_copy) 275125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 275225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine alignment for the symbol. */ 275325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX The question is how? The symbol record itself does not 275425b3c049e70834cf33790a28643ab058b507b35cBen Cheng // have the information. So we have to be conservative and 275525b3c049e70834cf33790a28643ab058b507b35cBen Cheng // assume the alignment of the section the symbol is in. 275625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 275725b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX We can be more precise. Use the offset from the beginning 275825b3c049e70834cf33790a28643ab058b507b35cBen Cheng // of the section and determine the largest power of two with 275925b3c049e70834cf33790a28643ab058b507b35cBen Cheng // module zero. 276025b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off symalign = MAX (SCNINFO_SHDR (runp->file->scninfo[runp->scndx].shdr).sh_addralign, 1); 276125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Keep track of the maximum alignment requirement. */ 276225b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxalign = MAX (maxalign, symalign); 276325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 276425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Align current position. */ 276525b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = (offset + symalign - 1) & ~(symalign - 1); 276625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 276725b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->merge.value = offset; 276825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 276925b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += runp->size; 277025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 277125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != ld_state.from_dso); 277225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 277325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_type = SHT_NOBITS; 277425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size = offset; 277525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addralign = maxalign; 277625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 277725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 277825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 277925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 278025b3c049e70834cf33790a28643ab058b507b35cBen Chengcompute_common_symbol_offset (XElf_Shdr *shdr) 278125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 278225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *runp = ld_state.common_syms; 278325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (runp != NULL); 278425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 278525b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off maxalign = 1; 278625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off offset = 0; 278725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 278825b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 278925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 279025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine alignment for the symbol. */ 279125b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off symalign = runp->merge.value; 279225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 279325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Keep track of the maximum alignment requirement. */ 279425b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxalign = MAX (maxalign, symalign); 279525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 279625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Align current position. */ 279725b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = (offset + symalign - 1) & ~(symalign - 1); 279825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 279925b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->merge.value = offset; 280025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 280125b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += runp->size; 280225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 280325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != ld_state.common_syms); 280425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 280525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_type = SHT_NOBITS; 280625b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size = offset; 280725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addralign = maxalign; 280825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 280925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 281025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 281125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 281225b3c049e70834cf33790a28643ab058b507b35cBen Chengsort_sections_generic (void) 281325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 281425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX TBI */ 281525b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 281625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 281725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 281825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 281925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 282025b3c049e70834cf33790a28643ab058b507b35cBen Chengmatch_section (const char *osectname, struct filemask_section_name *sectmask, 282125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead **scnhead, bool new_section, size_t segment_nr) 282225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 282325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *prevp; 282425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *runp; 282525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *notused; 282625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 282725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fnmatch (sectmask->section_name->name, (*scnhead)->name, 0) != 0) 282825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The section name does not match. */ 282925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return new_section; 283025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 283125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If this is a section generated by the linker it doesn't contain 283225b3c049e70834cf33790a28643ab058b507b35cBen Cheng the regular information (i.e., input section data etc) and must 283325b3c049e70834cf33790a28643ab058b507b35cBen Cheng be handle special. */ 283425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((*scnhead)->kind != scn_normal) 283525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 283625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (*scnhead)->name = osectname; 283725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (*scnhead)->segment_nr = segment_nr; 283825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 283925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to count note section since they get their own 284025b3c049e70834cf33790a28643ab058b507b35cBen Cheng program header entry. */ 284125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((*scnhead)->type == SHT_NOTE) 284225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nnotesections; 284325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 284425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[ld_state.nallsections++] = (*scnhead); 284525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return true; 284625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 284725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 284825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now we have to match the file names of the input files. Some of 284925b3c049e70834cf33790a28643ab058b507b35cBen Cheng the sections here might not match. */ 285025b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = (*scnhead)->last->next; 285125b3c049e70834cf33790a28643ab058b507b35cBen Cheng prevp = (*scnhead)->last; 285225b3c049e70834cf33790a28643ab058b507b35cBen Cheng notused = NULL; 285325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 285425b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 285525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 285625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Base of the file name the section comes from. */ 285725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *brfname = basename (runp->fileinfo->rfname); 285825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 285925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the section isn't used, the name doesn't match the positive 286025b3c049e70834cf33790a28643ab058b507b35cBen Cheng inclusion list, or the name does match the negative inclusion 286125b3c049e70834cf33790a28643ab058b507b35cBen Cheng list, ignore the section. */ 286225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!runp->used 286325b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (sectmask->filemask != NULL 286425b3c049e70834cf33790a28643ab058b507b35cBen Cheng && fnmatch (sectmask->filemask, brfname, 0) != 0) 286525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (sectmask->excludemask != NULL 286625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && fnmatch (sectmask->excludemask, brfname, 0) == 0)) 286725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 286825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This file does not match the file name masks. */ 286925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (notused == NULL) 287025b3c049e70834cf33790a28643ab058b507b35cBen Cheng notused = runp; 287125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 287225b3c049e70834cf33790a28643ab058b507b35cBen Cheng prevp = runp; 287325b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = runp->next; 287425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp == notused) 287525b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = NULL; 287625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 287725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The section fulfills all requirements, add it to the output 287825b3c049e70834cf33790a28643ab058b507b35cBen Cheng file with the correct section name etc. */ 287925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 288025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 288125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *found = runp; 288225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 288325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remove this input section data buffer from the list. */ 288425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (prevp != runp) 288525b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = prevp->next = runp->next; 288625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 288725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 288825b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (*scnhead); 288925b3c049e70834cf33790a28643ab058b507b35cBen Cheng *scnhead = NULL; 289025b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = NULL; 289125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 289225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 289325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create a new section for the output file if the 'new_section' 289425b3c049e70834cf33790a28643ab058b507b35cBen Cheng flag says so. Otherwise append the buffer to the last 289525b3c049e70834cf33790a28643ab058b507b35cBen Cheng section which we created in one of the last calls. */ 289625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (new_section) 289725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 289825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead *newp; 289925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 290025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = (struct scnhead *) obstack_calloc (&ld_state.smem, 290125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (*newp)); 290225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->kind = scn_normal; 290325b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->name = osectname; 290425b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->type = SCNINFO_SHDR (found->shdr).sh_type; 290525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Executable or DSO do not have section groups. Drop that 290625b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 290725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->flags = SCNINFO_SHDR (found->shdr).sh_flags & ~SHF_GROUP; 290825b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->segment_nr = segment_nr; 290925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->last = found->next = found; 291025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->used = true; 291125b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->relsize = found->relsize; 291225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->entsize = SCNINFO_SHDR (found->shdr).sh_entsize; 291325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 291425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to count note section since they get their own 291525b3c049e70834cf33790a28643ab058b507b35cBen Cheng program header entry. */ 291625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (newp->type == SHT_NOTE) 291725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.nnotesections; 291825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 291925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[ld_state.nallsections++] = newp; 292025b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_section = false; 292125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 292225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 292325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 292425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead *queued; 292525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 292625b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued = ld_state.allsections[ld_state.nallsections - 1]; 292725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 292825b3c049e70834cf33790a28643ab058b507b35cBen Cheng found->next = queued->last->next; 292925b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->last = queued->last->next = found; 293025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 293125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the linker script forces us to add incompatible 293225b3c049e70834cf33790a28643ab058b507b35cBen Cheng sections together do so. But reflect this in the 293325b3c049e70834cf33790a28643ab058b507b35cBen Cheng type and flags of the resulting file. */ 293425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (queued->type != SCNINFO_SHDR (found->shdr).sh_type) 293525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Any better choice? */ 293625b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->type = SHT_PROGBITS; 293725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (queued->flags != SCNINFO_SHDR (found->shdr).sh_flags) 293825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Executable or DSO do not have section groups. Drop that 293925b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 294025b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->flags = ebl_sh_flags_combine (ld_state.ebl, 294125b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->flags, 294225b3c049e70834cf33790a28643ab058b507b35cBen Cheng SCNINFO_SHDR (found->shdr).sh_flags 294325b3c049e70834cf33790a28643ab058b507b35cBen Cheng & ~SHF_GROUP); 294425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 294525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Accumulate the relocation section size. */ 294625b3c049e70834cf33790a28643ab058b507b35cBen Cheng queued->relsize += found->relsize; 294725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 294825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 294925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 295025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (runp != NULL); 295125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 295225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return new_section; 295325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 295425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 295525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 295625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 295725b3c049e70834cf33790a28643ab058b507b35cBen Chengsort_sections_lscript (void) 295825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 295925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead *temp[ld_state.nallsections]; 296025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 296125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make a copy of the section head pointer array. */ 296225b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (temp, ld_state.allsections, 296325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.nallsections * sizeof (temp[0])); 296425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nallsections = ld_state.nallsections; 296525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 296625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Convert the output segment list in a single-linked list. */ 296725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct output_segment *segment = ld_state.output_segments->next; 296825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.output_segments->next = NULL; 296925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.output_segments = segment; 297025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 297125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Put the sections in the correct order in the array in the state 297225b3c049e70834cf33790a28643ab058b507b35cBen Cheng structure. This might involve merging of sections and also 297325b3c049e70834cf33790a28643ab058b507b35cBen Cheng renaming the containing section in the output file. */ 297425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.nallsections = 0; 297525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t segment_nr; 297625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t last_writable = ~0ul; 297725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (segment_nr = 0; segment != NULL; segment = segment->next, ++segment_nr) 297825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 297925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct output_rule *orule; 298025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 298125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (orule = segment->output_rules; orule != NULL; orule = orule->next) 298225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (orule->tag == output_section) 298325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 298425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct input_rule *irule; 298525b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool new_section = true; 298625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 298725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (irule = orule->val.section.input; irule != NULL; 298825b3c049e70834cf33790a28643ab058b507b35cBen Cheng irule = irule->next) 298925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (irule->tag == input_section) 299025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 299125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 299225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 299325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < nallsections; ++cnt) 299425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (temp[cnt] != NULL) 299525b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_section = 299625b3c049e70834cf33790a28643ab058b507b35cBen Cheng match_section (orule->val.section.name, 299725b3c049e70834cf33790a28643ab058b507b35cBen Cheng irule->val.section, &temp[cnt], 299825b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_section, segment_nr); 299925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 300025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 300125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 300225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((segment->mode & PF_W) != 0) 300325b3c049e70834cf33790a28643ab058b507b35cBen Cheng last_writable = ld_state.nallsections - 1; 300425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 300525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 300625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* In case we have to create copy relocations or we have common 300725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbols, find the last writable segment and add one more data 300825b3c049e70834cf33790a28643ab058b507b35cBen Cheng block. It will be a NOBITS block and take up no disk space. 300925b3c049e70834cf33790a28643ab058b507b35cBen Cheng This is why it is important to get the last block. */ 301025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.ncopy > 0 || ld_state.common_syms != NULL) 301125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 301225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (last_writable == ~0ul) 301325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, "no writable segment"); 301425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 301525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.allsections[last_writable]->type != SHT_NOBITS) 301625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 301725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make room in the ALLSECTIONS array for a new section. 301825b3c049e70834cf33790a28643ab058b507b35cBen Cheng There is guaranteed room in the array. We add the new 301925b3c049e70834cf33790a28643ab058b507b35cBen Cheng entry after the last writable section. */ 302025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++last_writable; 302125b3c049e70834cf33790a28643ab058b507b35cBen Cheng memmove (&ld_state.allsections[last_writable + 1], 302225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &ld_state.allsections[last_writable], 302325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (ld_state.nallsections - last_writable) 302425b3c049e70834cf33790a28643ab058b507b35cBen Cheng * sizeof (ld_state.allsections[0])); 302525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 302625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable] = (struct scnhead *) 302725b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, sizeof (struct scnhead)); 302825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 302925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Name for the new section. */ 303025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->name = ".bss"; 303125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Type: NOBITS. */ 303225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->type = SHT_NOBITS; 303325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Same segment as the last writable section. */ 303425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->segment_nr 303525b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ld_state.allsections[last_writable - 1]->segment_nr; 303625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 303725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 303825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 303925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create common symbol data block. */ 304025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.ncopy > 0) 304125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 304225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF 304325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *si = (struct scninfo *) 304425b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, sizeof (*si) + sizeof (XElf_Shdr)); 304525b3c049e70834cf33790a28643ab058b507b35cBen Cheng si->shdr = (XElf_Shdr *) (si + 1); 304625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 304725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *si = (struct scninfo *) obstack_calloc (&ld_state.smem, 304825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (*si)); 304925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 305025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 305125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the information regarding the symbols with copy relocations. */ 305225b3c049e70834cf33790a28643ab058b507b35cBen Cheng compute_copy_reloc_offset (&SCNINFO_SHDR (si->shdr)); 305325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 305425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This section is needed. */ 305525b3c049e70834cf33790a28643ab058b507b35cBen Cheng si->used = true; 305625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember for later the section data structure. */ 305725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.copy_section = si; 305825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 305925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (ld_state.allsections[last_writable]->last != NULL)) 306025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 306125b3c049e70834cf33790a28643ab058b507b35cBen Cheng si->next = ld_state.allsections[last_writable]->last->next; 306225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->last->next = si; 306325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->last = si; 306425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 306525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 306625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->last = si->next = si; 306725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 306825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 306925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create common symbol data block. */ 307025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.common_syms != NULL) 307125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 307225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF 307325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *si = (struct scninfo *) 307425b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_calloc (&ld_state.smem, sizeof (*si) + sizeof (XElf_Shdr)); 307525b3c049e70834cf33790a28643ab058b507b35cBen Cheng si->shdr = (XElf_Shdr *) (si + 1); 307625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 307725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *si = (struct scninfo *) obstack_calloc (&ld_state.smem, 307825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (*si)); 307925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 308025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 308125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the information regarding the symbols with copy relocations. */ 308225b3c049e70834cf33790a28643ab058b507b35cBen Cheng compute_common_symbol_offset (&SCNINFO_SHDR (si->shdr)); 308325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 308425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This section is needed. */ 308525b3c049e70834cf33790a28643ab058b507b35cBen Cheng si->used = true; 308625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember for later the section data structure. */ 308725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.common_section = si; 308825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 308925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (ld_state.allsections[last_writable]->last != NULL)) 309025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 309125b3c049e70834cf33790a28643ab058b507b35cBen Cheng si->next = ld_state.allsections[last_writable]->last->next; 309225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->last->next = si; 309325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->last = si; 309425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 309525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 309625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[last_writable]->last = si->next = si; 309725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 309825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 309925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 310025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 310125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Create the output sections now. This requires knowledge about all 310225b3c049e70834cf33790a28643ab058b507b35cBen Cheng the sections we will need. It may be necessary to sort sections in 310325b3c049e70834cf33790a28643ab058b507b35cBen Cheng the order they are supposed to appear in the executable. The 310425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sorting use many different kinds of information to optimize the 310525b3c049e70834cf33790a28643ab058b507b35cBen Cheng resulting binary. Important is to respect segment boundaries and 310625b3c049e70834cf33790a28643ab058b507b35cBen Cheng the needed alignment. The mode of the segments will be determined 310725b3c049e70834cf33790a28643ab058b507b35cBen Cheng afterwards automatically by the output routines. 310825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 310925b3c049e70834cf33790a28643ab058b507b35cBen Cheng The generic sorting routines work in one of two possible ways: 311025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 311125b3c049e70834cf33790a28643ab058b507b35cBen Cheng - if a linker script specifies the sections to be used in the 311225b3c049e70834cf33790a28643ab058b507b35cBen Cheng output and assigns them to a segment this information is used; 311325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 311425b3c049e70834cf33790a28643ab058b507b35cBen Cheng - otherwise the linker will order the sections based on permissions 311525b3c049e70834cf33790a28643ab058b507b35cBen Cheng and some special knowledge about section names.*/ 311625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 311725b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_create_sections (struct ld_state *statep) 311825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 311925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scngroup *groups; 312025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 312125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 312225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* For relocatable object we don't have to bother sorting the 312325b3c049e70834cf33790a28643ab058b507b35cBen Cheng sections and we do want to preserve the relocation sections as 312425b3c049e70834cf33790a28643ab058b507b35cBen Cheng they appear in the input files. */ 312525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type != relocatable_file_type) 312625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 312725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Collect all the relocation sections. They are handled 312825b3c049e70834cf33790a28643ab058b507b35cBen Cheng separately. */ 312925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *list = NULL; 313025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < ld_state.nallsections; ++cnt) 313125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((ld_state.allsections[cnt]->type == SHT_REL 313225b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ld_state.allsections[cnt]->type == SHT_RELA) 313325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The generated relocation sections are not of any 313425b3c049e70834cf33790a28643ab058b507b35cBen Cheng interest here. */ 313525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && ld_state.allsections[cnt]->last != NULL) 313625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 313725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (list == NULL) 313825b3c049e70834cf33790a28643ab058b507b35cBen Cheng list = ld_state.allsections[cnt]->last; 313925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 314025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 314125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Merge the sections list. */ 314225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *first = list->next; 314325b3c049e70834cf33790a28643ab058b507b35cBen Cheng list->next = ld_state.allsections[cnt]->last->next; 314425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[cnt]->last->next = first; 314525b3c049e70834cf33790a28643ab058b507b35cBen Cheng list = ld_state.allsections[cnt]->last; 314625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 314725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 314825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remove the entry from the section list. */ 314925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[cnt] = NULL; 315025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 315125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.rellist = list; 315225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 315325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.output_segments == NULL) 315425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Sort using builtin rules. */ 315525b3c049e70834cf33790a28643ab058b507b35cBen Cheng sort_sections_generic (); 315625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 315725b3c049e70834cf33790a28643ab058b507b35cBen Cheng sort_sections_lscript (); 315825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 315925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 316025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now iterate over the input sections and create the sections in the 316125b3c049e70834cf33790a28643ab058b507b35cBen Cheng order they are required in the output file. */ 316225b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < ld_state.nallsections; ++cnt) 316325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 316425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead *head = ld_state.allsections[cnt]; 316525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn; 316625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr_vardef (shdr); 316725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 316825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Don't handle unused sections. */ 316925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!head->used) 317025b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 317125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 317225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We first have to create the section group if necessary. 317325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Section group sections must come (in section index order) 317425b3c049e70834cf33790a28643ab058b507b35cBen Cheng before any of the section contained. This all is necessary 317525b3c049e70834cf33790a28643ab058b507b35cBen Cheng only for relocatable object as other object types are not 317625b3c049e70834cf33790a28643ab058b507b35cBen Cheng allowed to contain section groups. */ 317725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type == relocatable_file_type 317825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && unlikely (head->flags & SHF_GROUP)) 317925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 318025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There is at least one section which is contained in a 318125b3c049e70834cf33790a28643ab058b507b35cBen Cheng section group in the input file. This means we must 318225b3c049e70834cf33790a28643ab058b507b35cBen Cheng create a section group here as well. The only problem is 318325b3c049e70834cf33790a28643ab058b507b35cBen Cheng that not all input files have to have to same kind of 318425b3c049e70834cf33790a28643ab058b507b35cBen Cheng partitioning of the sections. I.e., sections A and B in 318525b3c049e70834cf33790a28643ab058b507b35cBen Cheng one input file and sections B and C in another input file 318625b3c049e70834cf33790a28643ab058b507b35cBen Cheng can be in one group. That will result in a group 318725b3c049e70834cf33790a28643ab058b507b35cBen Cheng containing the sections A, B, and C in the output 318825b3c049e70834cf33790a28643ab058b507b35cBen Cheng file. */ 318925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *runp; 319025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word here_groupidx = 0; 319125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scngroup *here_group; 319225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct member *newp; 319325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 319425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First check whether any section is already in a group. 319525b3c049e70834cf33790a28643ab058b507b35cBen Cheng In this case we have to add this output section, too. */ 319625b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = head->last; 319725b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 319825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 319925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (runp->grpid != 0); 320025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 320125b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_groupidx = runp->fileinfo->scninfo[runp->grpid].outscnndx; 320225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (here_groupidx != 0) 320325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 320425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 320525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != head->last); 320625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 320725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (here_groupidx == 0) 320825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 320925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We need a new section group section. */ 321025b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = elf_newscn (ld_state.outelf); 321125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 321225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL) 321325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 321425b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 321525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 321625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 321725b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group = (struct scngroup *) xmalloc (sizeof (*here_group)); 321825b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group->outscnidx = here_groupidx = elf_ndxscn (scn); 321925b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group->nscns = 0; 322025b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group->member = NULL; 322125b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group->next = ld_state.groups; 322225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Pick a name for the section. To keep it meaningful 322325b3c049e70834cf33790a28643ab058b507b35cBen Cheng we use a name used in the input files. If the 322425b3c049e70834cf33790a28643ab058b507b35cBen Cheng section group in the output file should contain 322525b3c049e70834cf33790a28643ab058b507b35cBen Cheng section which were in section groups of different 322625b3c049e70834cf33790a28643ab058b507b35cBen Cheng names in the input files this is the users 322725b3c049e70834cf33790a28643ab058b507b35cBen Cheng problem. */ 322825b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group->nameent 322925b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_strtabadd (ld_state.shstrtab, 323025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (runp->fileinfo->elf, 323125b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->fileinfo->shstrndx, 323225b3c049e70834cf33790a28643ab058b507b35cBen Cheng SCNINFO_SHDR (runp->shdr).sh_name), 323325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 0); 323425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Signature symbol. */ 323525b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group->symbol 323625b3c049e70834cf33790a28643ab058b507b35cBen Cheng = runp->fileinfo->scninfo[runp->grpid].symbols; 323725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 323825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.groups = here_group; 323925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 324025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 324125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 324225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Search for the group with this index. */ 324325b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group = ld_state.groups; 324425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (here_group->outscnidx != here_groupidx) 324525b3c049e70834cf33790a28643ab058b507b35cBen Cheng here_group = here_group->next; 324625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 324725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 324825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the new output section. */ 324925b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = (struct member *) alloca (sizeof (*newp)); 325025b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->scn = head; 325125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDT_NEEDED 325225b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->next = NULL; 325325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 325425b3c049e70834cf33790a28643ab058b507b35cBen Cheng CSNGL_LIST_ADD_REAR (here_group->member, newp); 325525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++here_group->nscns; 325625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 325725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the section group index in all input files. */ 325825b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = head->last; 325925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 326025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 326125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (runp->grpid != 0); 326225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 326325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->fileinfo->scninfo[runp->grpid].outscnndx == 0) 326425b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->fileinfo->scninfo[runp->grpid].outscnndx = here_groupidx; 326525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 326625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (runp->fileinfo->scninfo[runp->grpid].outscnndx 326725b3c049e70834cf33790a28643ab058b507b35cBen Cheng == here_groupidx); 326825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 326925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != head->last); 327025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 327125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 327225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We'll use this section so get it's name in the section header 327325b3c049e70834cf33790a28643ab058b507b35cBen Cheng string table. */ 327425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (head->kind == scn_normal) 327525b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->nameent = ebl_strtabadd (ld_state.shstrtab, head->name, 0); 327625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 327725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create a new section in the output file and add all data 327825b3c049e70834cf33790a28643ab058b507b35cBen Cheng from all the sections we read. */ 327925b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = elf_newscn (ld_state.outelf); 328025b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->scnidx = elf_ndxscn (scn); 328125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 328225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL) 328325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 328425b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 328525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 328625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 328725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (head->type != SHT_NULL); 328825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (head->type != SHT_SYMTAB); 328925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (head->type != SHT_DYNSYM || head->kind != scn_normal); 329025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (head->type != SHT_STRTAB || head->kind != scn_normal); 329125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (head->type != SHT_GROUP); 329225b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_type = head->type; 329325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_flags = head->flags; 329425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addralign = head->align; 329525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_entsize = head->entsize; 329625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr->sh_entsize != 0 || (shdr->sh_flags & SHF_MERGE) == 0); 329725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (scn, shdr); 329825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 329925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to know the section index of the dynamic symbol table 330025b3c049e70834cf33790a28643ab058b507b35cBen Cheng right away. */ 330125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (head->kind == scn_dot_dynsym) 330225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.dynsymscnidx = elf_ndxscn (scn); 330325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 330425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 330525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Actually create the section group sections. */ 330625b3c049e70834cf33790a28643ab058b507b35cBen Cheng groups = ld_state.groups; 330725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (groups != NULL) 330825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 330925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn; 331025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data; 331125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *grpdata; 331225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct member *runp; 331325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 331425b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = elf_getscn (ld_state.outelf, groups->outscnidx); 331525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (scn != NULL); 331625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 331725b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = elf_newdata (scn); 331825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 331925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 332025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 332125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 332225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 332325b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_size = (groups->nscns + 1) * sizeof (Elf32_Word); 332425b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_buf = grpdata = (Elf32_Word *) xmalloc (data->d_size); 332525b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_type = ELF_T_WORD; 332625b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_version = EV_CURRENT; 332725b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_off = 0; 332825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX What better to use? */ 332925b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_align = sizeof (Elf32_Word); 333025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 333125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The first word in the section is the flag word. */ 333225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Set COMDATA flag is necessary. */ 333325b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpdata[0] = 0; 333425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 333525b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = groups->member->next; 333625b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt = 1; 333725b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 333825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fill in the index of the section. */ 333925b3c049e70834cf33790a28643ab058b507b35cBen Cheng grpdata[cnt++] = runp->scn->scnidx; 334025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != groups->member->next); 334125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 334225b3c049e70834cf33790a28643ab058b507b35cBen Cheng groups = groups->next; 334325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 334425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 334525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 334625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 334725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool 334825b3c049e70834cf33790a28643ab058b507b35cBen Chengreduce_symbol_p (XElf_Sym *sym, struct Ebl_Strent *strent) 334925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 335025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *str; 335125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *version; 335225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct id_list search; 335325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct id_list *verp; 335425b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool result = ld_state.default_bind_local; 335525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 335625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (XELF_ST_BIND (sym->st_info) == STB_LOCAL || sym->st_shndx == SHN_UNDEF) 335725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't have to do anything to local symbols here. */ 335825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Any section value in [SHN_LORESERVER,SHN_XINDEX) need 335925b3c049e70834cf33790a28643ab058b507b35cBen Cheng special treatment? */ 336025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 336125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 336225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Handle other symbol bindings. */ 336325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (XELF_ST_BIND (sym->st_info) == STB_GLOBAL 336425b3c049e70834cf33790a28643ab058b507b35cBen Cheng || XELF_ST_BIND (sym->st_info) == STB_WEAK); 336525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 336625b3c049e70834cf33790a28643ab058b507b35cBen Cheng str = ebl_string (strent); 336725b3c049e70834cf33790a28643ab058b507b35cBen Cheng version = strchr (str, VER_CHR); 336825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (version != NULL) 336925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 337025b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.id = strndupa (str, version - str); 337125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (*++version == VER_CHR) 337225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Skip the second '@' signaling a default definition. */ 337325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++version; 337425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 337525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 337625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 337725b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.id = str; 337825b3c049e70834cf33790a28643ab058b507b35cBen Cheng version = ""; 337925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 338025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 338125b3c049e70834cf33790a28643ab058b507b35cBen Cheng verp = ld_version_str_tab_find (&ld_state.version_str_tab, 338225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_hash (search.id), &search); 338325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (verp != NULL) 338425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 338525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have this symbol in the version hash table. Now match the 338625b3c049e70834cf33790a28643ab058b507b35cBen Cheng version name. */ 338725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (verp->u.s.versionname, version) == 0) 338825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Match! */ 338925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return verp->u.s.local; 339025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 339125b3c049e70834cf33790a28643ab058b507b35cBen Cheng verp = verp->next; 339225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 339325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 339425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Add test for wildcard version symbols. */ 339525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 339625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 339725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 339825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 339925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 340025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic XElf_Addr 340125b3c049e70834cf33790a28643ab058b507b35cBen Chengeval_expression (struct expression *expr, XElf_Addr addr) 340225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 340325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Addr val = ~((XElf_Addr) 0); 340425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 340525b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (expr->tag) 340625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 340725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_num: 340825b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = expr->val.num; 340925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 341025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 341125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_sizeof_headers: 341225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 341325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The 'elf_update' call determine the offset of the first 341425b3c049e70834cf33790a28643ab058b507b35cBen Cheng section. The the size of the header. */ 341525b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr_vardef (shdr); 341625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 341725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, 1), shdr); 341825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 341925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 342025b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = shdr->sh_offset; 342125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 342225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 342325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 342425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_pagesize: 342525b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = ld_state.pagesize; 342625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 342725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 342825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_id: 342925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We are here computing only address expressions. It seems not 343025b3c049e70834cf33790a28643ab058b507b35cBen Cheng to be necessary to handle any variable but ".". Let's avoid 343125b3c049e70834cf33790a28643ab058b507b35cBen Cheng the complication. If it turns up to be needed we can add 343225b3c049e70834cf33790a28643ab058b507b35cBen Cheng it. */ 343325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (expr->val.str, ".") != 0) 343425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 343525b3c049e70834cf33790a28643ab058b507b35cBen Chengaddress computation expression contains variable '%s'"), 343625b3c049e70834cf33790a28643ab058b507b35cBen Cheng expr->val.str); 343725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 343825b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = addr; 343925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 344025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 344125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_mult: 344225b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = (eval_expression (expr->val.binary.left, addr) 344325b3c049e70834cf33790a28643ab058b507b35cBen Cheng * eval_expression (expr->val.binary.right, addr)); 344425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 344525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 344625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_div: 344725b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = (eval_expression (expr->val.binary.left, addr) 344825b3c049e70834cf33790a28643ab058b507b35cBen Cheng / eval_expression (expr->val.binary.right, addr)); 344925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 345025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 345125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_mod: 345225b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = (eval_expression (expr->val.binary.left, addr) 345325b3c049e70834cf33790a28643ab058b507b35cBen Cheng % eval_expression (expr->val.binary.right, addr)); 345425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 345525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 345625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_plus: 345725b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = (eval_expression (expr->val.binary.left, addr) 345825b3c049e70834cf33790a28643ab058b507b35cBen Cheng + eval_expression (expr->val.binary.right, addr)); 345925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 346025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 346125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_minus: 346225b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = (eval_expression (expr->val.binary.left, addr) 346325b3c049e70834cf33790a28643ab058b507b35cBen Cheng - eval_expression (expr->val.binary.right, addr)); 346425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 346525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 346625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_and: 346725b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = (eval_expression (expr->val.binary.left, addr) 346825b3c049e70834cf33790a28643ab058b507b35cBen Cheng & eval_expression (expr->val.binary.right, addr)); 346925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 347025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 347125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_or: 347225b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = (eval_expression (expr->val.binary.left, addr) 347325b3c049e70834cf33790a28643ab058b507b35cBen Cheng | eval_expression (expr->val.binary.right, addr)); 347425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 347525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 347625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case exp_align: 347725b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = eval_expression (expr->val.child, addr); 347825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((val & (val - 1)) != 0) 347925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("argument '%" PRIuMAX "' of ALIGN in address computation expression is no power of two"), 348025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uintmax_t) val); 348125b3c049e70834cf33790a28643ab058b507b35cBen Cheng val = (addr + val - 1) & ~(val - 1); 348225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 348325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 348425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 348525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return val; 348625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 348725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 348825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 348925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Find a good as possible size for the hash table so that all the 349025b3c049e70834cf33790a28643ab058b507b35cBen Cheng non-zero entries in HASHCODES don't collide too much and the table 349125b3c049e70834cf33790a28643ab058b507b35cBen Cheng isn't too large. There is no exact formular for this so we use a 349225b3c049e70834cf33790a28643ab058b507b35cBen Cheng heuristic. Depending on the optimization level the search is 349325b3c049e70834cf33790a28643ab058b507b35cBen Cheng longer or shorter. */ 349425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t 349525b3c049e70834cf33790a28643ab058b507b35cBen Chengoptimal_bucket_size (Elf32_Word *hashcodes, size_t maxcnt, int optlevel) 349625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 349725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t minsize; 349825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t maxsize; 349925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t bestsize; 350025b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t bestcost; 350125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t size; 350225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t *counts; 350325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t *lengths; 350425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 350525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (maxcnt == 0) 350625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 350725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 350825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When we are not optimizing we run only very few tests. */ 350925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (optlevel <= 0) 351025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 351125b3c049e70834cf33790a28643ab058b507b35cBen Cheng minsize = maxcnt; 351225b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxsize = maxcnt + 10000 / maxcnt; 351325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 351425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 351525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 351625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Does not make much sense to start with a smaller table than 351725b3c049e70834cf33790a28643ab058b507b35cBen Cheng one which has at least four collisions. */ 351825b3c049e70834cf33790a28643ab058b507b35cBen Cheng minsize = MAX (1, maxcnt / 4); 351925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We look for a best fit in the range of up to eigth times the 352025b3c049e70834cf33790a28643ab058b507b35cBen Cheng number of elements. */ 352125b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxsize = 2 * maxcnt + (6 * MIN (optlevel, 100) * maxcnt) / 100; 352225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 352325b3c049e70834cf33790a28643ab058b507b35cBen Cheng bestsize = maxcnt; 352425b3c049e70834cf33790a28643ab058b507b35cBen Cheng bestcost = UINT_MAX; 352525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 352625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Array for counting the collisions and chain lengths. */ 352725b3c049e70834cf33790a28643ab058b507b35cBen Cheng counts = (uint32_t *) xmalloc ((maxcnt + 1 + maxsize) * sizeof (uint32_t)); 352825b3c049e70834cf33790a28643ab058b507b35cBen Cheng lengths = &counts[maxcnt + 1]; 352925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 353025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size = minsize; size <= maxsize; ++size) 353125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 353225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t inner; 353325b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t cost; 353425b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t maxlength; 353525b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint64_t success; 353625b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t acc; 353725b3c049e70834cf33790a28643ab058b507b35cBen Cheng double factor; 353825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 353925b3c049e70834cf33790a28643ab058b507b35cBen Cheng memset (lengths, '\0', size * sizeof (uint32_t)); 354025b3c049e70834cf33790a28643ab058b507b35cBen Cheng memset (counts, '\0', (maxcnt + 1) * sizeof (uint32_t)); 354125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 354225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine how often each hash bucket is used. */ 354325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (hashcodes[0] == 0); 354425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (inner = 1; inner < maxcnt; ++inner) 354525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++lengths[hashcodes[inner] % size]; 354625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 354725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the lengths. */ 354825b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxlength = 0; 354925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (inner = 0; inner < size; ++inner) 355025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 355125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++counts[lengths[inner]]; 355225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 355325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (lengths[inner] > maxlength) 355425b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxlength = lengths[inner]; 355525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 355625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 355725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine successful lookup length. */ 355825b3c049e70834cf33790a28643ab058b507b35cBen Cheng acc = 0; 355925b3c049e70834cf33790a28643ab058b507b35cBen Cheng success = 0; 356025b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (inner = 0; inner <= maxlength; ++inner) 356125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 356225b3c049e70834cf33790a28643ab058b507b35cBen Cheng acc += inner; 356325b3c049e70834cf33790a28643ab058b507b35cBen Cheng success += counts[inner] * acc; 356425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 356525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 356625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We can compute two factors now: the average length of a 356725b3c049e70834cf33790a28643ab058b507b35cBen Cheng positive search and the average length of a negative search. 356825b3c049e70834cf33790a28643ab058b507b35cBen Cheng We count the number of comparisons which have to look at the 356925b3c049e70834cf33790a28643ab058b507b35cBen Cheng names themselves. Recognizing that the chain ended is not 357025b3c049e70834cf33790a28643ab058b507b35cBen Cheng accounted for since it's almost for free. 357125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 357225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Which lookup is more important depends on the kind of DSO. 357325b3c049e70834cf33790a28643ab058b507b35cBen Cheng If it is a system DSO like libc it is expected that most 357425b3c049e70834cf33790a28643ab058b507b35cBen Cheng lookups succeed. Otherwise most lookups fail. */ 357525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.is_system_library) 357625b3c049e70834cf33790a28643ab058b507b35cBen Cheng factor = (1.0 * (double) success / (double) maxcnt 357725b3c049e70834cf33790a28643ab058b507b35cBen Cheng + 0.3 * (double) maxcnt / (double) size); 357825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 357925b3c049e70834cf33790a28643ab058b507b35cBen Cheng factor = (0.3 * (double) success / (double) maxcnt 358025b3c049e70834cf33790a28643ab058b507b35cBen Cheng + 1.0 * (double) maxcnt / (double) size); 358125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 358225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Combine the lookup cost factor. The 1/16th addend adds 358325b3c049e70834cf33790a28643ab058b507b35cBen Cheng penalties for too large table sizes. */ 358425b3c049e70834cf33790a28643ab058b507b35cBen Cheng cost = (2 + maxcnt + size) * (factor + 1.0 / 16.0); 358525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 358625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if 0 358725b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("maxcnt = %d, size = %d, cost = %Ld, success = %g, fail = %g, factor = %g\n", 358825b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxcnt, size, cost, (double) success / (double) maxcnt, (double) maxcnt / (double) size, factor); 358925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 359025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 359125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compare with current best results. */ 359225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cost < bestcost) 359325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 359425b3c049e70834cf33790a28643ab058b507b35cBen Cheng bestcost = cost; 359525b3c049e70834cf33790a28643ab058b507b35cBen Cheng bestsize = size; 359625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 359725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 359825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 359925b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (counts); 360025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 360125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return bestsize; 360225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 360325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 360425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 360525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 360625b3c049e70834cf33790a28643ab058b507b35cBen Chengoptimal_gnu_hash_size (Elf32_Word *hashcodes, size_t maxcnt, int optlevel, 360725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t *bitmask_nwords, size_t *shift, size_t *nbuckets) 360825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 360925b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Implement something real 361025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *bitmask_nwords = 256; 361125b3c049e70834cf33790a28643ab058b507b35cBen Cheng *shift = 6; 361225b3c049e70834cf33790a28643ab058b507b35cBen Cheng *nbuckets = 3 * maxcnt / 2; 361325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 361425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 361525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 361625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic XElf_Addr 361725b3c049e70834cf33790a28643ab058b507b35cBen Chengfind_entry_point (void) 361825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 361925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Addr result; 362025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 362125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.entry != NULL) 362225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 362325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol search = { .name = ld_state.entry }; 362425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *syment; 362525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 362625b3c049e70834cf33790a28643ab058b507b35cBen Cheng syment = ld_symbol_tab_find (&ld_state.symbol_tab, 362725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_hash (ld_state.entry), &search); 362825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (syment != NULL && syment->defined) 362925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 363025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We found the symbol. */ 363125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (elf_getscn (ld_state.outelf, 363225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.symscnidx), NULL); 363325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 363425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 363525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 363625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym = NULL; 363725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data != NULL) 363825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (data, ld_state.dblindirect[syment->outsymidx], sym); 363925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 364025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym == NULL && ld_state.need_dynsym && syment->outdynsymidx != 0) 364125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 364225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use the dynamic symbol table if available. */ 364325b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = elf_getdata (elf_getscn (ld_state.outelf, 364425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.dynsymscnidx), NULL); 364525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 364625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym = NULL; 364725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data != NULL) 364825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (data, syment->outdynsymidx, sym); 364925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 365025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 365125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym != NULL) 365225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return sym->st_value; 365325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 365425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX What to do if the output has no non-dynamic symbol 365525b3c049e70834cf33790a28643ab058b507b35cBen Cheng table and the dynamic symbol table does not contain the 365625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol? */ 365725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.need_symtab); 365825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.symscnidx != 0); 365925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 366025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 366125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 366225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We couldn't find the symbol or none was given. Use the first 366325b3c049e70834cf33790a28643ab058b507b35cBen Cheng address of the ".text" section then. */ 366425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 366525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 366625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = 0; 366725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 366825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* In DSOs this is no fatal error. They usually have no entry 366925b3c049e70834cf33790a28643ab058b507b35cBen Cheng points. In this case we set the entry point to zero, which makes 367025b3c049e70834cf33790a28643ab058b507b35cBen Cheng sure it will always fail. */ 367125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type == executable_file_type) 367225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 367325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.entry != NULL) 367425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("\ 367525b3c049e70834cf33790a28643ab058b507b35cBen Chengcannot find entry symbol '%s': defaulting to %#0*" PRIx64), 367625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.entry, 367725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getclass (ld_state.outelf) == ELFCLASS32 ? 10 : 18, 367825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) result); 367925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 368025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("\ 368125b3c049e70834cf33790a28643ab058b507b35cBen Chengno entry symbol specified: defaulting to %#0*" PRIx64), 368225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getclass (ld_state.outelf) == ELFCLASS32 ? 10 : 18, 368325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (uint64_t) result); 368425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 368525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 368625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 368725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 368825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 368925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 369025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 369125b3c049e70834cf33790a28643ab058b507b35cBen Chengfillin_special_symbol (struct symbol *symst, size_t scnidx, size_t nsym, 369225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *symdata, struct Ebl_Strtab *strtab) 369325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 369425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.file_type != relocatable_file_type); 369525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 369625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 369725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym_ptr (symdata, nsym, sym); 369825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 369925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The name offset will be filled in later. */ 370025b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_name = 0; 370125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Traditionally: globally visible. */ 370225b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_info = XELF_ST_INFO (symst->local ? STB_LOCAL : STB_GLOBAL, 370325b3c049e70834cf33790a28643ab058b507b35cBen Cheng symst->type); 370425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_other = symst->hidden ? STV_HIDDEN : STV_DEFAULT; 370525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Reference to the GOT or dynamic section. Since the GOT and 370625b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynamic section are only created for executables and DSOs it 370725b3c049e70834cf33790a28643ab058b507b35cBen Cheng cannot be that the section index is too large. */ 370825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (scnidx != 0); 370925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (scnidx < SHN_LORESERVE || scnidx == SHN_ABS); 371025b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx = scnidx; 371125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We want the beginning of the section. */ 371225b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value = 0; 371325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX What size? 371425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_size = 0; 371525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 371625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the size of the section. */ 371725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (scnidx != SHN_ABS) 371825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 371925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (elf_getscn (ld_state.outelf, scnidx), 372025b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL); 372125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (data != NULL); 372225b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_size = data->d_size; 372325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make sure there is no second data block. */ 372425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (elf_getdata (elf_getscn (ld_state.outelf, scnidx), data) 372525b3c049e70834cf33790a28643ab058b507b35cBen Cheng == NULL); 372625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 372725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 372825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Insert symbol into the symbol table. Note that we do not have to 372925b3c049e70834cf33790a28643ab058b507b35cBen Cheng use xelf_update_symshdx. */ 373025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (symdata, nsym, sym); 373125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 373225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Cross-references. */ 373325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym[nsym] = symst; 373425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symst->outsymidx = nsym; 373525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 373625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the name to the string table. */ 373725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[nsym] = ebl_strtabadd (strtab, symst->name, 0); 373825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 373925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 374025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 374125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 374225b3c049e70834cf33790a28643ab058b507b35cBen Chengnew_dynamic_entry (Elf_Data *data, int idx, XElf_Sxword tag, XElf_Addr val) 374325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 374425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Dyn_vardef (dyn); 374525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getdyn_ptr (data, idx, dyn); 374625b3c049e70834cf33790a28643ab058b507b35cBen Cheng dyn->d_tag = tag; 374725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dyn->d_un.d_ptr = val; 374825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_dyn (data, idx, dyn); 374925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 375025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 375125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 375225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 375325b3c049e70834cf33790a28643ab058b507b35cBen Chengallocate_version_names (struct usedfiles *runp, struct Ebl_Strtab *dynstrtab) 375425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 375525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If this DSO has no versions skip it. */ 375625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->status != opened || runp->verdefdata == NULL) 375725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 375825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 375925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the object name. */ 376025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int offset = 0; 376125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (1) 376225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 376325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Verdef_vardef (def); 376425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Verdaux_vardef (aux); 376525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 376625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get data at the next offset. */ 376725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getverdef (runp->verdefdata, offset, def); 376825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (def != NULL); 376925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getverdaux (runp->verdefdata, offset + def->vd_aux, aux); 377025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (aux != NULL); 377125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 377225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (def->vd_ndx <= runp->nverdef); 377325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (def->vd_ndx == 1 || runp->verdefused[def->vd_ndx] != 0) 377425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 377525b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->verdefent[def->vd_ndx] 377625b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_strtabadd (dynstrtab, elf_strptr (runp->elf, 377725b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->dynsymstridx, 377825b3c049e70834cf33790a28643ab058b507b35cBen Cheng aux->vda_name), 0); 377925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 378025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (def->vd_ndx > 1) 378125b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->verdefused[def->vd_ndx] = ld_state.nextveridx++; 378225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 378325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 378425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (def->vd_next == 0) 378525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* That were all versions. */ 378625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 378725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 378825b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += def->vd_next; 378925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 379025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 379125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 379225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 379325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic XElf_Off 379425b3c049e70834cf33790a28643ab058b507b35cBen Chengcreate_verneed_data (XElf_Off offset, Elf_Data *verneeddata, 379525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *runp, int *ntotal) 379625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 379725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t verneed_size = xelf_fsize (ld_state.outelf, ELF_T_VNEED, 1); 379825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t vernaux_size = xelf_fsize (ld_state.outelf, ELF_T_VNAUX, 1); 379925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int need_offset; 380025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool filled = false; 380125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Verneed verneed; 380225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Vernaux vernaux; 380325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int ndef = 0; 380425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 380525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 380625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If this DSO has no versions skip it. */ 380725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->nverdefused == 0) 380825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return offset; 380925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 381025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We fill in the Verneed record last. Remember the offset. */ 381125b3c049e70834cf33790a28643ab058b507b35cBen Cheng need_offset = offset; 381225b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += verneed_size; 381325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 381425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 2; cnt <= runp->nverdef; ++cnt) 381525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->verdefused[cnt] != 0) 381625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 381725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (runp->verdefent[cnt] != NULL); 381825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 381925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (filled) 382025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 382125b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux.vna_next = vernaux_size; 382225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) gelf_update_vernaux (verneeddata, offset, &vernaux); 382325b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += vernaux_size; 382425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 382525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 382625b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux.vna_hash = elf_hash (ebl_string (runp->verdefent[cnt])); 382725b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux.vna_flags = 0; 382825b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux.vna_other = runp->verdefused[cnt]; 382925b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux.vna_name = ebl_strtaboffset (runp->verdefent[cnt]); 383025b3c049e70834cf33790a28643ab058b507b35cBen Cheng filled = true; 383125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ndef; 383225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 383325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 383425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (filled); 383525b3c049e70834cf33790a28643ab058b507b35cBen Cheng vernaux.vna_next = 0; 383625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) gelf_update_vernaux (verneeddata, offset, &vernaux); 383725b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += vernaux_size; 383825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 383925b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneed.vn_version = VER_NEED_CURRENT; 384025b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneed.vn_cnt = ndef; 384125b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneed.vn_file = ebl_strtaboffset (runp->verdefent[1]); 384225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The first auxiliary entry is always found directly 384325b3c049e70834cf33790a28643ab058b507b35cBen Cheng after the verneed entry. */ 384425b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneed.vn_aux = verneed_size; 384525b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneed.vn_next = --*ntotal > 0 ? offset - need_offset : 0; 384625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) gelf_update_verneed (verneeddata, need_offset, &verneed); 384725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 384825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return offset; 384925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 385025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 385125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 385225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Callback for qsort to sort dynamic string table. */ 385325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic Elf32_Word *global_hashcodes; 385425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t global_nbuckets; 385525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 385625b3c049e70834cf33790a28643ab058b507b35cBen Chengsortfct_hashval (const void *p1, const void *p2) 385725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 385825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t idx1 = *(size_t *) p1; 385925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t idx2 = *(size_t *) p2; 386025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 386125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int def1 = ndxtosym[idx1]->defined && !ndxtosym[idx1]->in_dso; 386225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int def2 = ndxtosym[idx2]->defined && !ndxtosym[idx2]->in_dso; 386325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 386425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! def1 && def2) 386525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return -1; 386625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (def1 && !def2) 386725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 386825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! def1) 386925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 387025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 387125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word hval1 = (global_hashcodes[ndxtosym[idx1]->outdynsymidx] 387225b3c049e70834cf33790a28643ab058b507b35cBen Cheng % global_nbuckets); 387325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word hval2 = (global_hashcodes[ndxtosym[idx2]->outdynsymidx] 387425b3c049e70834cf33790a28643ab058b507b35cBen Cheng % global_nbuckets); 387525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 387625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (hval1 < hval2) 387725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return -1; 387825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (hval1 > hval2) 387925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 388025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 388125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 388225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 388325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 388425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Sort the dynamic symbol table. The GNU hash table lookup assumes 388525b3c049e70834cf33790a28643ab058b507b35cBen Cheng that all symbols with the same hash value module the bucket table 388625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size follow one another. This avoids the extra hash chain table. 388725b3c049e70834cf33790a28643ab058b507b35cBen Cheng There is no need (and no way) to perform this operation if we do 388825b3c049e70834cf33790a28643ab058b507b35cBen Cheng not use the new hash table format. */ 388925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 389025b3c049e70834cf33790a28643ab058b507b35cBen Chengcreate_gnu_hash (size_t nsym_local, size_t nsym, size_t nsym_dyn, 389125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *gnuhashcodes) 389225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 389325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t gnu_bitmask_nwords = 0; 389425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t gnu_shift = 0; 389525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t gnu_nbuckets = 0; 389625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *gnu_bitmask = NULL; 389725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *gnu_buckets = NULL; 389825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *gnu_chain = NULL; 389925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr_vardef (shdr); 390025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 390125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the "optimal" bucket size. */ 390225b3c049e70834cf33790a28643ab058b507b35cBen Cheng optimal_gnu_hash_size (gnuhashcodes, nsym_dyn, ld_state.optlevel, 390325b3c049e70834cf33790a28643ab058b507b35cBen Cheng &gnu_bitmask_nwords, &gnu_shift, &gnu_nbuckets); 390425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 390525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the .gnu.hash section data structures. */ 390625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *hashscn = elf_getscn (ld_state.outelf, ld_state.gnuhashscnidx); 390725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (hashscn, shdr); 390825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *hashdata = elf_newdata (hashscn); 390925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL || hashdata == NULL) 391025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 391125b3c049e70834cf33790a28643ab058b507b35cBen Chengcannot create GNU hash table section for output file: %s"), 391225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 391325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 391425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.dynsymscnidx; 391525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (hashscn, shdr); 391625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 391725b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_size = (xelf_fsize (ld_state.outelf, ELF_T_ADDR, 391825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_bitmask_nwords) 391925b3c049e70834cf33790a28643ab058b507b35cBen Cheng + (4 + gnu_nbuckets + nsym_dyn) * sizeof (Elf32_Word)); 392025b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_buf = xcalloc (1, hashdata->d_size); 392125b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_align = sizeof (Elf32_Word); 392225b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_type = ELF_T_WORD; 392325b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_off = 0; 392425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 392525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((Elf32_Word *) hashdata->d_buf)[0] = gnu_nbuckets; 392625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((Elf32_Word *) hashdata->d_buf)[2] = gnu_bitmask_nwords; 392725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((Elf32_Word *) hashdata->d_buf)[3] = gnu_shift; 392825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_bitmask = &((Elf32_Word *) hashdata->d_buf)[4]; 392925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_buckets = &gnu_bitmask[xelf_fsize (ld_state.outelf, ELF_T_ADDR, 393025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_bitmask_nwords) 393125b3c049e70834cf33790a28643ab058b507b35cBen Cheng / sizeof (*gnu_buckets)]; 393225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_chain = &gnu_buckets[gnu_nbuckets]; 393325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 393425b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *endp = &gnu_chain[nsym_dyn]; 393525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 393625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (endp == (void *) ((char *) hashdata->d_buf + hashdata->d_size)); 393725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 393825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 393925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t *remap = xmalloc (nsym_dyn * sizeof (size_t)); 394025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 394125b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsym_dyn_cnt = 1; 394225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 394325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = nsym_local; cnt < nsym; ++cnt) 394425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symstrent[cnt] != NULL) 394525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 394625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ndxtosym[cnt]->outdynsymidx > 0); 394725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ndxtosym[cnt]->outdynsymidx < nsym_dyn); 394825b3c049e70834cf33790a28643ab058b507b35cBen Cheng remap[ndxtosym[cnt]->outdynsymidx] = cnt; 394925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 395025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nsym_dyn_cnt; 395125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 395225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 395325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym_dyn_cnt == nsym_dyn); 395425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 395525b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Until we can rely on qsort_r use global variables. 395625b3c049e70834cf33790a28643ab058b507b35cBen Cheng global_hashcodes = gnuhashcodes; 395725b3c049e70834cf33790a28643ab058b507b35cBen Cheng global_nbuckets = gnu_nbuckets; 395825b3c049e70834cf33790a28643ab058b507b35cBen Cheng qsort (remap + 1, nsym_dyn - 1, sizeof (size_t), sortfct_hashval); 395925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 396025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool bm32 = (xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1) 396125b3c049e70834cf33790a28643ab058b507b35cBen Cheng == sizeof (Elf32_Word)); 396225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 396325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t first_defined = 0; 396425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf64_Word bitmask_idxbits = gnu_bitmask_nwords - 1; 396525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word last_bucket = 0; 396625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = 1; cnt < nsym_dyn; ++cnt) 396725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 396825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first_defined == 0) 396925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 397025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! ndxtosym[remap[cnt]]->defined 397125b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ndxtosym[remap[cnt]]->in_dso) 397225b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto next; 397325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 397425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((Elf32_Word *) hashdata->d_buf)[1] = first_defined = cnt; 397525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 397625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 397725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word hval = gnuhashcodes[ndxtosym[remap[cnt]]->outdynsymidx]; 397825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 397925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (bm32) 398025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 398125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *bsw = &gnu_bitmask[(hval / 32) & bitmask_idxbits]; 398225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((void *) gnu_bitmask <= (void *) bsw); 398325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((void *) bsw < (void *) gnu_buckets); 398425b3c049e70834cf33790a28643ab058b507b35cBen Cheng *bsw |= 1 << (hval & 31); 398525b3c049e70834cf33790a28643ab058b507b35cBen Cheng *bsw |= 1 << ((hval >> gnu_shift) & 31); 398625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 398725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 398825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 398925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf64_Word *bsw = &((Elf64_Word *) gnu_bitmask)[(hval / 64) 399025b3c049e70834cf33790a28643ab058b507b35cBen Cheng & bitmask_idxbits]; 399125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((void *) gnu_bitmask <= (void *) bsw); 399225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((void *) bsw < (void *) gnu_buckets); 399325b3c049e70834cf33790a28643ab058b507b35cBen Cheng *bsw |= 1 << (hval & 63); 399425b3c049e70834cf33790a28643ab058b507b35cBen Cheng *bsw |= 1 << ((hval >> gnu_shift) & 63); 399525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 399625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 399725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t this_bucket = hval % gnu_nbuckets; 399825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cnt == first_defined || this_bucket != last_bucket) 399925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 400025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cnt != first_defined) 400125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 400225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Terminate the previous chain. */ 400325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((void *) &gnu_chain[cnt - first_defined - 1] < endp); 400425b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_chain[cnt - first_defined - 1] |= 1; 400525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 400625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 400725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (this_bucket < gnu_nbuckets); 400825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_buckets[this_bucket] = cnt; 400925b3c049e70834cf33790a28643ab058b507b35cBen Cheng last_bucket = this_bucket; 401025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 401125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 401225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (cnt >= first_defined); 401325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (cnt - first_defined < nsym_dyn); 401425b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_chain[cnt - first_defined] = hval & ~1u; 401525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 401625b3c049e70834cf33790a28643ab058b507b35cBen Cheng next: 401725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym[remap[cnt]]->outdynsymidx = cnt; 401825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 401925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 402025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Terminate the last chain. */ 402125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first_defined != 0) 402225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 402325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym_dyn > first_defined); 402425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym_dyn - first_defined - 1 < nsym_dyn); 402525b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnu_chain[nsym_dyn - first_defined - 1] |= 1; 402625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 402725b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_size -= first_defined * sizeof (Elf32_Word); 402825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 402925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 403025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We do not need any hash table. */ 403125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX 403225b3c049e70834cf33790a28643ab058b507b35cBen Cheng do { } while (0); 403325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 403425b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (remap); 403525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 403625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 403725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 403825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Create the SysV-style hash table. */ 403925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 404025b3c049e70834cf33790a28643ab058b507b35cBen Chengcreate_hash (size_t nsym_local, size_t nsym, size_t nsym_dyn, 404125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *hashcodes) 404225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 404325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nbucket = 0; 404425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *bucket = NULL; 404525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *chain = NULL; 404625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr_vardef (shdr); 404725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 404825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the "optimal" bucket size. If we also generate the 404925b3c049e70834cf33790a28643ab058b507b35cBen Cheng new-style hash function there is no need to waste effort and 405025b3c049e70834cf33790a28643ab058b507b35cBen Cheng space on the old one which should not be used. Make it as small 405125b3c049e70834cf33790a28643ab058b507b35cBen Cheng as possible. */ 405225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (GENERATE_GNU_HASH) 405325b3c049e70834cf33790a28643ab058b507b35cBen Cheng nbucket = 1; 405425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 405525b3c049e70834cf33790a28643ab058b507b35cBen Cheng nbucket = optimal_bucket_size (hashcodes, nsym_dyn, ld_state.optlevel); 405625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the .hash section data structures. */ 405725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *hashscn = elf_getscn (ld_state.outelf, ld_state.hashscnidx); 405825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (hashscn, shdr); 405925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *hashdata = elf_newdata (hashscn); 406025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL || hashdata == NULL) 406125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 406225b3c049e70834cf33790a28643ab058b507b35cBen Chengcannot create hash table section for output file: %s"), 406325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 406425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 406525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.dynsymscnidx; 406625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (hashscn, shdr); 406725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 406825b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_size = (2 + nsym_dyn + nbucket) * sizeof (Elf32_Word); 406925b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_buf = xcalloc (1, hashdata->d_size); 407025b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_align = sizeof (Elf32_Word); 407125b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_type = ELF_T_WORD; 407225b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashdata->d_off = 0; 407325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 407425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((Elf32_Word *) hashdata->d_buf)[0] = nbucket; 407525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((Elf32_Word *) hashdata->d_buf)[1] = nsym_dyn; 407625b3c049e70834cf33790a28643ab058b507b35cBen Cheng bucket = &((Elf32_Word *) hashdata->d_buf)[2]; 407725b3c049e70834cf33790a28643ab058b507b35cBen Cheng chain = &((Elf32_Word *) hashdata->d_buf)[2 + nbucket]; 407825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 407925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (size_t cnt = nsym_local; cnt < nsym; ++cnt) 408025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symstrent[cnt] != NULL) 408125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 408225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t dynidx = ndxtosym[cnt]->outdynsymidx; 408325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t hashidx = hashcodes[dynidx] % nbucket; 408425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (bucket[hashidx] == 0) 408525b3c049e70834cf33790a28643ab058b507b35cBen Cheng bucket[hashidx] = dynidx; 408625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 408725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 408825b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashidx = bucket[hashidx]; 408925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (chain[hashidx] != 0) 409025b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashidx = chain[hashidx]; 409125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 409225b3c049e70834cf33790a28643ab058b507b35cBen Cheng chain[hashidx] = dynidx; 409325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 409425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 409525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 409625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 409725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 409825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 409925b3c049e70834cf33790a28643ab058b507b35cBen Chengcreate_build_id_section (Elf_Scn *scn) 410025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 410125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We know how large the section will be so we can create it now. */ 410225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *d = elf_newdata (scn); 410325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (d == NULL) 410425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot create build ID section: %s"), 410525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 410625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 410725b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_type = ELF_T_BYTE; 410825b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_version = EV_CURRENT; 410925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 411025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The note section header. */ 411125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); 411225b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_size = sizeof (GElf_Nhdr); 411325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The string is four bytes long. */ 411425b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_size += sizeof (ELF_NOTE_GNU); 411525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (d->d_size % 4 == 0); 411625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 411725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (ld_state.build_id, "md5") == 0 411825b3c049e70834cf33790a28643ab058b507b35cBen Cheng || strcmp (ld_state.build_id, "uuid") == 0) 411925b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_size += 16; 412025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (ld_state.build_id, "sha1") == 0) 412125b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_size += 20; 412225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 412325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 412425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.build_id[0] == '0' && ld_state.build_id[1] == 'x'); 412525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use an upper limit of the possible number of bytes generated 412625b3c049e70834cf33790a28643ab058b507b35cBen Cheng from the string. */ 412725b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_size += strlen (ld_state.build_id) / 2; 412825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 412925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 413025b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_buf = xcalloc (d->d_size, 1); 413125b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_off = 0; 413225b3c049e70834cf33790a28643ab058b507b35cBen Cheng d->d_align = 0; 413325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 413425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 413525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 413625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 413725b3c049e70834cf33790a28643ab058b507b35cBen Chengcompute_hash_sum (void (*hashfct) (const void *, size_t, void *), void *ctx) 413825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 413925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The call cannot fail. */ 414025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrndx; 414125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) elf_getshdrstrndx (ld_state.outelf, &shstrndx); 414225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 414325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *ident = elf_getident (ld_state.outelf, NULL); 414425b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool same_byte_order = ((ident[EI_DATA] == ELFDATA2LSB 414525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && __BYTE_ORDER == __LITTLE_ENDIAN) 414625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (ident[EI_DATA] == ELFDATA2MSB 414725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && __BYTE_ORDER == __BIG_ENDIAN)); 414825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 414925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Iterate over all sections to find those which are not strippable. */ 415025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 415125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (ld_state.outelf, scn)) != NULL) 415225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 415325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header. */ 415425b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 415525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 415625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 415725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 415825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (SECTION_STRIP_P (shdr, elf_strptr (ld_state.outelf, shstrndx, 415925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name), true)) 416025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The section can be stripped. Don't use it. */ 416125b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 416225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 416325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Do not look at NOBITS sections. */ 416425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type == SHT_NOBITS) 416525b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 416625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 416725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Iterate through the list of data blocks. */ 416825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = NULL; 416925b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((data = INTUSE(elf_getdata) (scn, data)) != NULL) 417025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the file byte order is the same as the host byte order 417125b3c049e70834cf33790a28643ab058b507b35cBen Cheng process the buffer directly. If the data is just a stream 417225b3c049e70834cf33790a28643ab058b507b35cBen Cheng of bytes which the library will not convert we can use it 417325b3c049e70834cf33790a28643ab058b507b35cBen Cheng as well. */ 417425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (same_byte_order) || data->d_type == ELF_T_BYTE) 417525b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashfct (data->d_buf, data->d_size, ctx); 417625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 417725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 417825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Convert the data to file byte order. */ 417925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (gelf_xlatetof (ld_state.outelf, data, data, ident[EI_DATA]) 418025b3c049e70834cf33790a28643ab058b507b35cBen Cheng == NULL) 418125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 418225b3c049e70834cf33790a28643ab058b507b35cBen Chengcannot convert section data to file format: %s"), 418325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 418425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 418525b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashfct (data->d_buf, data->d_size, ctx); 418625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 418725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And convert it back. */ 418825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (gelf_xlatetom (ld_state.outelf, data, data, ident[EI_DATA]) 418925b3c049e70834cf33790a28643ab058b507b35cBen Cheng == NULL) 419025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 419125b3c049e70834cf33790a28643ab058b507b35cBen Chengcannot convert section data to memory format: %s"), 419225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 419325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 419425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 419525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 419625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 419725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 419825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Iterate over the sections */ 419925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 420025b3c049e70834cf33790a28643ab058b507b35cBen Chengcompute_build_id (void) 420125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 420225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *d = elf_getdata (elf_getscn (ld_state.outelf, 420325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.buildidscnidx), NULL); 420425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (d != NULL); 420525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 420625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Nhdr *hdr = d->d_buf; 420725b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr->n_namesz = sizeof (ELF_NOTE_GNU); 420825b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr->n_type = NT_GNU_BUILD_ID; 420925b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *dp = mempcpy (hdr + 1, ELF_NOTE_GNU, sizeof (ELF_NOTE_GNU)); 421025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 421125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (ld_state.build_id, "sha1") == 0) 421225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 421325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute the SHA1 sum of various parts of the generated file. 421425b3c049e70834cf33790a28643ab058b507b35cBen Cheng We compute the hash sum over the external representation. */ 421525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct sha1_ctx ctx; 421625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sha1_init_ctx (&ctx); 421725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 421825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute the hash sum by running over all sections. */ 421925b3c049e70834cf33790a28643ab058b507b35cBen Cheng compute_hash_sum ((void (*) (const void *, size_t, void *)) sha1_process_bytes, 422025b3c049e70834cf33790a28643ab058b507b35cBen Cheng &ctx); 422125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 422225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We are done computing the checksum. */ 422325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) sha1_finish_ctx (&ctx, dp); 422425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 422525b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr->n_descsz = SHA1_DIGEST_SIZE; 422625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 422725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (ld_state.build_id, "md5") == 0) 422825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 422925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute the MD5 sum of various parts of the generated file. 423025b3c049e70834cf33790a28643ab058b507b35cBen Cheng We compute the hash sum over the external representation. */ 423125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct md5_ctx ctx; 423225b3c049e70834cf33790a28643ab058b507b35cBen Cheng md5_init_ctx (&ctx); 423325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 423425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute the hash sum by running over all sections. */ 423525b3c049e70834cf33790a28643ab058b507b35cBen Cheng compute_hash_sum ((void (*) (const void *, size_t, void *)) md5_process_bytes, 423625b3c049e70834cf33790a28643ab058b507b35cBen Cheng &ctx); 423725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 423825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We are done computing the checksum. */ 423925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) md5_finish_ctx (&ctx, dp); 424025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 424125b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr->n_descsz = MD5_DIGEST_SIZE; 424225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 424325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (strcmp (ld_state.build_id, "uuid") == 0) 424425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 424525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int fd = open ("/dev/urandom", O_RDONLY); 424625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fd == -1) 424725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("cannot open '%s'"), 424825b3c049e70834cf33790a28643ab058b507b35cBen Cheng "/dev/urandom"); 424925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 425025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (TEMP_FAILURE_RETRY (read (fd, dp, 16)) != 16) 425125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot read enough data for UUID")); 425225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 425325b3c049e70834cf33790a28643ab058b507b35cBen Cheng close (fd); 425425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 425525b3c049e70834cf33790a28643ab058b507b35cBen Cheng hdr->n_descsz = 16; 425625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 425725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 425825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 425925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *cp = ld_state.build_id + 2; 426025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 426125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The form of the string has been verified before so here we can 426225b3c049e70834cf33790a28643ab058b507b35cBen Cheng simplify the scanning. */ 426325b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 426425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 426525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (isxdigit (cp[0])) 426625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 426725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char ch1 = tolower (cp[0]); 426825b3c049e70834cf33790a28643ab058b507b35cBen Cheng char ch2 = tolower (cp[1]); 426925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 427025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *dp++ = (((isdigit (ch1) ? ch1 - '0' : ch1 - 'a' + 10) << 4) 427125b3c049e70834cf33790a28643ab058b507b35cBen Cheng | (isdigit (ch2) ? ch2 - '0' : ch2 - 'a' + 10)); 427225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 427325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 427425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++cp; 427525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 427625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (*cp != '\0'); 427725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 427825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 427925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 428025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 428125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Create the output file. 428225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 428325b3c049e70834cf33790a28643ab058b507b35cBen Cheng For relocatable files what basically has to happen is that all 428425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sections from all input files are written into the output file. 428525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Sections with the same name are combined (offsets adjusted 428625b3c049e70834cf33790a28643ab058b507b35cBen Cheng accordingly). The symbol tables are combined in one single table. 428725b3c049e70834cf33790a28643ab058b507b35cBen Cheng When stripping certain symbol table entries are omitted. 428825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 428925b3c049e70834cf33790a28643ab058b507b35cBen Cheng For executables (shared or not) we have to create the program header, 429025b3c049e70834cf33790a28643ab058b507b35cBen Cheng additional sections like the .interp, eventually (in addition) create 429125b3c049e70834cf33790a28643ab058b507b35cBen Cheng a dynamic symbol table and a dynamic section. Also the relocations 429225b3c049e70834cf33790a28643ab058b507b35cBen Cheng have to be processed differently. */ 429325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 429425b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_create_outfile (struct ld_state *statep) 429525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 429625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnlist 429725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 429825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t scnidx; 429925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *scninfo; 430025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnlist *next; 430125b3c049e70834cf33790a28643ab058b507b35cBen Cheng }; 430225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnlist *rellist = NULL; 430325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t cnt; 430425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *symscn = NULL; 430525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *xndxscn = NULL; 430625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *strscn = NULL; 430725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strtab *strtab = NULL; 430825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strtab *dynstrtab = NULL; 430925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Shdr_vardef (shdr); 431025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data; 431125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *symdata = NULL; 431225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *xndxdata = NULL; 431325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *file; 431425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsym; 431525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsym_local; 431625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsym_allocated; 431725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsym_dyn = 0; 431825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *dblindirect = NULL; 431925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 432025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool need_xndx; 432125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 432225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *shstrtab_scn; 432325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t shstrtab_ndx; 432425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Ehdr_vardef (ehdr); 432525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strent *symtab_ent = NULL; 432625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strent *xndx_ent = NULL; 432725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strent *strtab_ent = NULL; 432825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strent *shstrtab_ent; 432925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scngroup *groups; 433025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *dynsymscn = NULL; 433125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *dynsymdata = NULL; 433225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *dynstrdata = NULL; 433325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *hashcodes = NULL; 433425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word *gnuhashcodes = NULL; 433525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nsym_dyn_allocated = 0; 433625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *versymscn = NULL; 433725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *versymdata = NULL; 433825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 433925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_symtab) 434025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 434125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First create the symbol table. We need the symbol section itself 434225b3c049e70834cf33790a28643ab058b507b35cBen Cheng and the string table for it. */ 434325b3c049e70834cf33790a28643ab058b507b35cBen Cheng symscn = elf_newscn (ld_state.outelf); 434425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.symscnidx = elf_ndxscn (symscn); 434525b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata = elf_newdata (symscn); 434625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symdata == NULL) 434725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 434825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create symbol table for output file: %s"), 434925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 435025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 435125b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_type = ELF_T_SYM; 435225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is an estimated size, but it will definitely cap the real value. 435325b3c049e70834cf33790a28643ab058b507b35cBen Cheng We might have to adjust the number later. */ 435425b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_allocated = (1 + ld_state.nsymtab + ld_state.nplt + ld_state.ngot 435525b3c049e70834cf33790a28643ab058b507b35cBen Cheng + ld_state.nusedsections + ld_state.nlscript_syms); 435625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_SYM, 435725b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_allocated); 435825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 435925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Optionally the extended section table. */ 436025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Is SHN_LORESERVE correct? Do we need some other sections? */ 436125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (ld_state.nusedsections >= SHN_LORESERVE)) 436225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 436325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxscn = elf_newscn (ld_state.outelf); 436425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.xndxscnidx = elf_ndxscn (xndxscn); 436525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 436625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata = elf_newdata (xndxscn); 436725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (xndxdata == NULL) 436825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 436925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create symbol table for output file: %s"), 437025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 437125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 437225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The following relies on the fact that Elf32_Word and Elf64_Word 437325b3c049e70834cf33790a28643ab058b507b35cBen Cheng have the same size. */ 437425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata->d_type = ELF_T_WORD; 437525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is an estimated size, but it will definitely cap the 437625b3c049e70834cf33790a28643ab058b507b35cBen Cheng real value. we might have to adjust the number later. */ 437725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_WORD, 437825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_allocated); 437925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The first entry is left empty, clear it here and now. */ 438025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata->d_buf = memset (xmalloc (xndxdata->d_size), '\0', 438125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_WORD, 438225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1)); 438325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata->d_off = 0; 438425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Should use an ebl function. */ 438525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata->d_align = sizeof (Elf32_Word); 438625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 438725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 438825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 438925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 439025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.need_dynsym); 439125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 439225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First create the symbol table. We need the symbol section itself 439325b3c049e70834cf33790a28643ab058b507b35cBen Cheng and the string table for it. */ 439425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symscn = elf_getscn (ld_state.outelf, ld_state.dynsymscnidx); 439525b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata = elf_newdata (symscn); 439625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symdata == NULL) 439725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 439825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create symbol table for output file: %s"), 439925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 440025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 440125b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_version = EV_CURRENT; 440225b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_type = ELF_T_SYM; 440325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is an estimated size, but it will definitely cap the real value. 440425b3c049e70834cf33790a28643ab058b507b35cBen Cheng We might have to adjust the number later. */ 440525b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_allocated = (1 + ld_state.nsymtab + ld_state.nplt + ld_state.ngot 440625b3c049e70834cf33790a28643ab058b507b35cBen Cheng - ld_state.nlocalsymbols + ld_state.nlscript_syms); 440725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_SYM, 440825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_allocated); 440925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 441025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 441125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The first entry is left empty, clear it here and now. */ 441225b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_buf = memset (xmalloc (symdata->d_size), '\0', 441325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_SYM, 1)); 441425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_off = 0; 441525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX This is ugly but how else can it be done. */ 441625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_align = xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1); 441725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 441825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Allocate another array to keep track of the handles for the symbol 441925b3c049e70834cf33790a28643ab058b507b35cBen Cheng names. */ 442025b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent = (struct Ebl_Strent **) xcalloc (nsym_allocated, 442125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (struct Ebl_Strent *)); 442225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 442325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* By starting at 1 we effectively add a null entry. */ 442425b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym = 1; 442525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 442625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Iteration over all sections. */ 442725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < ld_state.nallsections; ++cnt) 442825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 442925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnhead *head = ld_state.allsections[cnt]; 443025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn; 443125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *runp; 443225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off offset; 443325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word xndx; 443425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 443525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Don't handle unused sections at all. */ 443625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!head->used) 443725b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 443825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 443925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section handle. */ 444025b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = elf_getscn (ld_state.outelf, head->scnidx); 444125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 444225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_interp)) 444325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 444425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *outdata = elf_newdata (scn); 444525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (outdata == NULL) 444625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 444725b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 444825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 444925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 445025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is the string we'll put in the section. */ 445125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *interp = ld_state.interp ?: "/lib/ld.so.1"; 445225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 445325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the section data. */ 445425b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_buf = (void *) interp; 445525b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_size = strlen (interp) + 1; 445625b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_type = ELF_T_BYTE; 445725b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_off = 0; 445825b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_align = 1; 445925b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_version = EV_CURRENT; 446025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 446125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 446225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.interpscnidx = head->scnidx; 446325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 446425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 446525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 446625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 446725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_got)) 446825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 446925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 447025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.gotscnidx = elf_ndxscn (scn); 447125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 447225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Give the backend the change to initialize the section. */ 447325b3c049e70834cf33790a28643ab058b507b35cBen Cheng INITIALIZE_GOT (&ld_state, scn); 447425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 447525b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 447625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 447725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 447825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_gotplt)) 447925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 448025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 448125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.gotpltscnidx = elf_ndxscn (scn); 448225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 448325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Give the backend the change to initialize the section. */ 448425b3c049e70834cf33790a28643ab058b507b35cBen Cheng INITIALIZE_GOTPLT (&ld_state, scn); 448525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 448625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 448725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 448825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 448925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_dynrel)) 449025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 449125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *outdata; 449225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 449325b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata = elf_newdata (scn); 449425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (outdata == NULL) 449525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 449625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 449725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 449825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 449925b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_size = ld_state.relsize_total; 450025b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_buf = xmalloc (outdata->d_size); 450125b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_type = (REL_TYPE (&ld_state) == DT_REL 450225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? ELF_T_REL : ELF_T_RELA); 450325b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_off = 0; 450425b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_align = xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1); 450525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 450625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 450725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.reldynscnidx = elf_ndxscn (scn); 450825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 450925b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 451025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 451125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 451225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_dynamic)) 451325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 451425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Only create the data for now. */ 451525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *outdata; 451625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 451725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Account for a few more entries we have to add. */ 451825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.dt_flags != 0) 451925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.ndynamic; 452025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.dt_flags_1 != 0) 452125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.ndynamic; 452225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.dt_feature_1 != 0) 452325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++ld_state.ndynamic; 452425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 452525b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata = elf_newdata (scn); 452625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (outdata == NULL) 452725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 452825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 452925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 453025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 453125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the section data. */ 453225b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_DYN, 453325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.ndynamic); 453425b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_buf = xcalloc (1, outdata->d_size); 453525b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_type = ELF_T_DYN; 453625b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_off = 0; 453725b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_align = xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1); 453825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 453925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 454025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.dynamicscnidx = elf_ndxscn (scn); 454125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 454225b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 454325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 454425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 454525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_dynsym)) 454625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 454725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We already know the section index. */ 454825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.dynsymscnidx == elf_ndxscn (scn)); 454925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 455025b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 455125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 455225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 455325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_dynstr)) 455425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 455525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 455625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.dynstrscnidx = elf_ndxscn (scn); 455725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 455825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the string table. */ 455925b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynstrtab = ebl_strtabinit (true); 456025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 456125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX TBI 456225b3c049e70834cf33790a28643ab058b507b35cBen Cheng We have to add all the strings which are needed in the 456325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynamic section here. This means DT_FILTER, 456425b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_AUXILIARY, ... entries. */ 456525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.ndsofiles > 0) 456625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 456725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *frunp = ld_state.dsofiles; 456825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 456925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 457025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! frunp->as_needed || frunp->used) 457125b3c049e70834cf33790a28643ab058b507b35cBen Cheng frunp->sonameent = ebl_strtabadd (dynstrtab, frunp->soname, 457225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 0); 457325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((frunp = frunp->next) != ld_state.dsofiles); 457425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 457525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 457625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 457725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the runtime path information. The strings are stored 457825b3c049e70834cf33790a28643ab058b507b35cBen Cheng in the .dynstr section. If both rpath and runpath are defined 457925b3c049e70834cf33790a28643ab058b507b35cBen Cheng the runpath information is used. */ 458025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.runpath != NULL || ld_state.rpath != NULL) 458125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 458225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct pathelement *startp; 458325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct pathelement *prunp; 458425b3c049e70834cf33790a28643ab058b507b35cBen Cheng int tag; 458525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len; 458625b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *str; 458725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *cp; 458825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 458925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.runpath != NULL) 459025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 459125b3c049e70834cf33790a28643ab058b507b35cBen Cheng startp = ld_state.runpath; 459225b3c049e70834cf33790a28643ab058b507b35cBen Cheng tag = DT_RUNPATH; 459325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 459425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 459525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 459625b3c049e70834cf33790a28643ab058b507b35cBen Cheng startp = ld_state.rpath; 459725b3c049e70834cf33790a28643ab058b507b35cBen Cheng tag = DT_RPATH; 459825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 459925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 460025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine how long the string will be. */ 460125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (len = 0, prunp = startp; prunp != NULL; prunp = prunp->next) 460225b3c049e70834cf33790a28643ab058b507b35cBen Cheng len += strlen (prunp->pname) + 1; 460325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 460425b3c049e70834cf33790a28643ab058b507b35cBen Cheng cp = str = (char *) obstack_alloc (&ld_state.smem, len); 460525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Copy the string. */ 460625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (prunp = startp; prunp != NULL; prunp = prunp->next) 460725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 460825b3c049e70834cf33790a28643ab058b507b35cBen Cheng cp = stpcpy (cp, prunp->pname); 460925b3c049e70834cf33790a28643ab058b507b35cBen Cheng *cp++ = ':'; 461025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 461125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remove the last colon. */ 461225b3c049e70834cf33790a28643ab058b507b35cBen Cheng cp[-1] = '\0'; 461325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 461425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the values until we can generate the dynamic 461525b3c049e70834cf33790a28643ab058b507b35cBen Cheng section. */ 461625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.rxxpath_strent = ebl_strtabadd (dynstrtab, str, len); 461725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.rxxpath_tag = tag; 461825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 461925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 462025b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 462125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 462225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 462325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_hash)) 462425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 462525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 462625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.hashscnidx = elf_ndxscn (scn); 462725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 462825b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 462925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 463025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 463125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_gnu_hash)) 463225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 463325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 463425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.gnuhashscnidx = elf_ndxscn (scn); 463525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 463625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 463725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 463825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 463925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_plt)) 464025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 464125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 464225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.pltscnidx = elf_ndxscn (scn); 464325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 464425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Give the backend the change to initialize the section. */ 464525b3c049e70834cf33790a28643ab058b507b35cBen Cheng INITIALIZE_PLT (&ld_state, scn); 464625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 464725b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 464825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 464925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 465025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_pltrel)) 465125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 465225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 465325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.pltrelscnidx = elf_ndxscn (scn); 465425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 465525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Give the backend the change to initialize the section. */ 465625b3c049e70834cf33790a28643ab058b507b35cBen Cheng INITIALIZE_PLTREL (&ld_state, scn); 465725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 465825b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 465925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 466025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 466125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_version)) 466225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 466325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 466425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.versymscnidx = elf_ndxscn (scn); 466525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 466625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 466725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 466825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 466925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_version_r)) 467025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 467125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 467225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.verneedscnidx = elf_ndxscn (scn); 467325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 467425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 467525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 467625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 467725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (head->kind == scn_dot_note_gnu_build_id)) 467825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 467925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the index of this section. */ 468025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.buildidscnidx = elf_ndxscn (scn); 468125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 468225b3c049e70834cf33790a28643ab058b507b35cBen Cheng create_build_id_section (scn); 468325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 468425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 468525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 468625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 468725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we come here we must be handling a normal section. */ 468825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (head->kind == scn_normal); 468925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 469025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create an STT_SECTION entry in the symbol table. But not for 469125b3c049e70834cf33790a28643ab058b507b35cBen Cheng the symbolic symbol table. */ 469225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_symtab) 469325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 469425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Can we be cleverer and do this only if needed? */ 469525b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 469625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 469725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Optimization ahead: in the native linker we get a pointer 469825b3c049e70834cf33790a28643ab058b507b35cBen Cheng to the final location so that the following code writes 469925b3c049e70834cf33790a28643ab058b507b35cBen Cheng directly in the correct place. Otherwise we write into 470025b3c049e70834cf33790a28643ab058b507b35cBen Cheng the local variable first. */ 470125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym_ptr (symdata, nsym, sym); 470225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 470325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Usual section symbol: local, no specific information, 470425b3c049e70834cf33790a28643ab058b507b35cBen Cheng except the section index. The offset here is zero, the 470525b3c049e70834cf33790a28643ab058b507b35cBen Cheng start address will later be added. */ 470625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_name = 0; 470725b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_info = XELF_ST_INFO (STB_LOCAL, STT_SECTION); 470825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_other = 0; 470925b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value = 0; 471025b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_size = 0; 471125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* In relocatable files the section index can be too big for 471225b3c049e70834cf33790a28643ab058b507b35cBen Cheng the ElfXX_Sym struct. we have to deal with the extended 471325b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol table. */ 471425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (head->scnidx < SHN_LORESERVE)) 471525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 471625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx = head->scnidx; 471725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx = 0; 471825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 471925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 472025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 472125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx = SHN_XINDEX; 472225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx = head->scnidx; 472325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 472425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Commit the change. See the optimization above, this does 472525b3c049e70834cf33790a28643ab058b507b35cBen Cheng not change the symbol table entry. But the extended 472625b3c049e70834cf33790a28643ab058b507b35cBen Cheng section index table entry is always written, if there is 472725b3c049e70834cf33790a28643ab058b507b35cBen Cheng such a table. */ 472825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym < nsym_allocated); 472925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_update_symshndx (symdata, xndxdata, nsym, sym, xndx, 0); 473025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 473125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the symbol's index in the symbol table. */ 473225b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->scnsymidx = nsym++; 473325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 473425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 473525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (head->type == SHT_REL || head->type == SHT_RELA) 473625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 473725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember that we have to fill in the symbol table section 473825b3c049e70834cf33790a28643ab058b507b35cBen Cheng index. */ 473925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type == relocatable_file_type) 474025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 474125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scnlist *newp; 474225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 474325b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp = (struct scnlist *) alloca (sizeof (*newp)); 474425b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->scnidx = head->scnidx; 474525b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->scninfo = head->last->next; 474625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 474725b3c049e70834cf33790a28643ab058b507b35cBen Cheng newp->next = NULL; 474825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 474925b3c049e70834cf33790a28643ab058b507b35cBen Cheng SNGL_LIST_PUSH (rellist, newp); 475025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 475125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 475225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 475325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* When we create an executable or a DSO we don't simply 475425b3c049e70834cf33790a28643ab058b507b35cBen Cheng copy the existing relocations. Instead many will be 475525b3c049e70834cf33790a28643ab058b507b35cBen Cheng resolved, others will be converted. Create a data buffer 475625b3c049e70834cf33790a28643ab058b507b35cBen Cheng large enough to contain the contents which we will fill 475725b3c049e70834cf33790a28643ab058b507b35cBen Cheng in later. */ 475825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int type = head->type == SHT_REL ? ELF_T_REL : ELF_T_RELA; 475925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 476025b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = elf_newdata (scn); 476125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 476225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 476325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 476425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 476525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 476625b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_size = xelf_fsize (ld_state.outelf, type, head->relsize); 476725b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_buf = xcalloc (data->d_size, 1); 476825b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_type = type; 476925b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_align = xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1); 477025b3c049e70834cf33790a28643ab058b507b35cBen Cheng data->d_off = 0; 477125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 477225b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 477325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 477425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 477525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 477625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Recognize string and merge flag and handle them. */ 477725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (head->flags & SHF_MERGE) 477825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 477925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We merge the contents of the sections. For this we do 478025b3c049e70834cf33790a28643ab058b507b35cBen Cheng not look at the contents of section directly. Instead we 478125b3c049e70834cf33790a28643ab058b507b35cBen Cheng look at the symbols of the section. */ 478225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *outdata; 478325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 478425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Concatenate the lists of symbols for all sections. 478525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 478625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XXX In case any input section has no symbols associated 478725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (this happens for debug sections) we cannot use this 478825b3c049e70834cf33790a28643ab058b507b35cBen Cheng method. Implement parsing the other debug sections and 478925b3c049e70834cf33790a28643ab058b507b35cBen Cheng find the string pointers. For now we don't merge. */ 479025b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = head->last->next; 479125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->symbols == NULL) 479225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 479325b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->flags &= ~SHF_MERGE; 479425b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto no_merge; 479525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 479625b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->symbols = runp->symbols; 479725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 479825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != head->last->next) 479925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 480025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->symbols == NULL) 480125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 480225b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->flags &= ~SHF_MERGE; 480325b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->symbols = NULL; 480425b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto no_merge; 480525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 480625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 480725b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *oldhead = head->symbols->next_in_scn; 480825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 480925b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->symbols->next_in_scn = runp->symbols->next_in_scn; 481025b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->symbols->next_in_scn = oldhead; 481125b3c049e70834cf33790a28643ab058b507b35cBen Cheng head->symbols = runp->symbols; 481225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 481325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 481425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the output section. */ 481525b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata = elf_newdata (scn); 481625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (outdata == NULL) 481725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 481825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 481925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 482025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 482125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We use different merging algorithms for performance 482225b3c049e70834cf33790a28643ab058b507b35cBen Cheng reasons. We can easily handle single-byte and 482325b3c049e70834cf33790a28643ab058b507b35cBen Cheng wchar_t-wide character strings. All other cases (which 482425b3c049e70834cf33790a28643ab058b507b35cBen Cheng really should happen in real life) are handled by the 482525b3c049e70834cf33790a28643ab058b507b35cBen Cheng generic code. */ 482625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (SCNINFO_SHDR (head->last->shdr).sh_entsize == 1 482725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (head->flags & SHF_STRINGS)) 482825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 482925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Simple, single-byte string matching. */ 483025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strtab *mergestrtab; 483125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *symrunp; 483225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *locsymdata = NULL; 483325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *locdata = NULL; 483425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 483525b3c049e70834cf33790a28643ab058b507b35cBen Cheng mergestrtab = ebl_strtabinit (false); 483625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 483725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp = head->symbols->next_in_scn; 483825b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = NULL; 483925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 484025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 484125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Accelarate the loop. We cache the file 484225b3c049e70834cf33790a28643ab058b507b35cBen Cheng information since it might very well be the case 484325b3c049e70834cf33790a28643ab058b507b35cBen Cheng that the previous entry was from the same 484425b3c049e70834cf33790a28643ab058b507b35cBen Cheng file. */ 484525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symrunp->file != file) 484625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 484725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the file. */ 484825b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = symrunp->file; 484925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Symbol table data from that file. */ 485025b3c049e70834cf33790a28643ab058b507b35cBen Cheng locsymdata = file->symtabdata; 485125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* String section data. */ 485225b3c049e70834cf33790a28643ab058b507b35cBen Cheng locdata = elf_rawdata (file->scninfo[symrunp->scndx].scn, 485325b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL); 485425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (locdata != NULL); 485525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* While we are at it, remember the output 485625b3c049e70834cf33790a28643ab058b507b35cBen Cheng section. If we don't access the string data 485725b3c049e70834cf33790a28643ab058b507b35cBen Cheng section the section won't be in the output 485825b3c049e70834cf33790a28643ab058b507b35cBen Cheng file. So it is sufficient to do the work 485925b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 486025b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->scninfo[symrunp->scndx].outscnndx = head->scnidx; 486125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 486225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 486325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the symbol information. This provides us the 486425b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset into the string data section. */ 486525b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 486625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (locsymdata, symrunp->symidx, sym); 486725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 486825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 486925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data from the file. Note that we access 487025b3c049e70834cf33790a28643ab058b507b35cBen Cheng the raw section data; no endian-ness issues with 487125b3c049e70834cf33790a28643ab058b507b35cBen Cheng single-byte strings. */ 487225b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merge.handle 487325b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_strtabadd (mergestrtab, 487425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (char *) locdata->d_buf + sym->st_value, 487525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 0); 487625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 487725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((symrunp = symrunp->next_in_scn) 487825b3c049e70834cf33790a28643ab058b507b35cBen Cheng != head->symbols->next_in_scn); 487925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 488025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* All strings have been added. Create the final table. */ 488125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_strtabfinalize (mergestrtab, outdata); 488225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 488325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute the final offsets in the section. */ 488425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp = runp->symbols; 488525b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 488625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 488725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merge.value 488825b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_strtaboffset (symrunp->merge.handle); 488925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merged = 1; 489025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 489125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((symrunp = symrunp->next_in_scn) != runp->symbols); 489225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 489325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't need the string table anymore. */ 489425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_strtabfree (mergestrtab); 489525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 489625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (likely (SCNINFO_SHDR (head->last->shdr).sh_entsize 489725b3c049e70834cf33790a28643ab058b507b35cBen Cheng == sizeof (wchar_t)) 489825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && likely (head->flags & SHF_STRINGS)) 489925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 490025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Simple, wchar_t string merging. */ 490125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_WStrtab *mergestrtab; 490225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *symrunp; 490325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *locsymdata = NULL; 490425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *locdata = NULL; 490525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 490625b3c049e70834cf33790a28643ab058b507b35cBen Cheng mergestrtab = ebl_wstrtabinit (false); 490725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 490825b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp = runp->symbols; 490925b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = NULL; 491025b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 491125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 491225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Accelarate the loop. We cache the file 491325b3c049e70834cf33790a28643ab058b507b35cBen Cheng information since it might very well be the case 491425b3c049e70834cf33790a28643ab058b507b35cBen Cheng that the previous entry was from the same 491525b3c049e70834cf33790a28643ab058b507b35cBen Cheng file. */ 491625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symrunp->file != file) 491725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 491825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the file. */ 491925b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = symrunp->file; 492025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Symbol table data from that file. */ 492125b3c049e70834cf33790a28643ab058b507b35cBen Cheng locsymdata = file->symtabdata; 492225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* String section data. */ 492325b3c049e70834cf33790a28643ab058b507b35cBen Cheng locdata = elf_rawdata (file->scninfo[symrunp->scndx].scn, 492425b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL); 492525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (locdata != NULL); 492625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 492725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* While we are at it, remember the output 492825b3c049e70834cf33790a28643ab058b507b35cBen Cheng section. If we don't access the string data 492925b3c049e70834cf33790a28643ab058b507b35cBen Cheng section the section won't be in the output 493025b3c049e70834cf33790a28643ab058b507b35cBen Cheng file. So it is sufficient to do the work 493125b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 493225b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->scninfo[symrunp->scndx].outscnndx = head->scnidx; 493325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 493425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 493525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the symbol information. This provides us the 493625b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset into the string data section. */ 493725b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 493825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (locsymdata, symrunp->symidx, sym); 493925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 494025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 494125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data from the file. Using the raw 494225b3c049e70834cf33790a28643ab058b507b35cBen Cheng section data here is possible since we don't 494325b3c049e70834cf33790a28643ab058b507b35cBen Cheng interpret the string themselves except for 494425b3c049e70834cf33790a28643ab058b507b35cBen Cheng looking for the wide NUL character. The NUL 494525b3c049e70834cf33790a28643ab058b507b35cBen Cheng character has fortunately the same representation 494625b3c049e70834cf33790a28643ab058b507b35cBen Cheng regardless of the byte order. */ 494725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merge.handle 494825b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_wstrtabadd (mergestrtab, 494925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (wchar_t *) ((char *) locdata->d_buf 495025b3c049e70834cf33790a28643ab058b507b35cBen Cheng + sym->st_value), 0); 495125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 495225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((symrunp = symrunp->next_in_scn) != runp->symbols); 495325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 495425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* All strings have been added. Create the final table. */ 495525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_wstrtabfinalize (mergestrtab, outdata); 495625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 495725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute the final offsets in the section. */ 495825b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp = runp->symbols; 495925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 496025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 496125b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merge.value 496225b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_wstrtaboffset (symrunp->merge.handle); 496325b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merged = 1; 496425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 496525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((symrunp = symrunp->next_in_scn) != runp->symbols); 496625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 496725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't need the string table anymore. */ 496825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_wstrtabfree (mergestrtab); 496925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 497025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 497125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 497225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Non-standard merging. */ 497325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_GStrtab *mergestrtab; 497425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *symrunp; 497525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *locsymdata = NULL; 497625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *locdata = NULL; 497725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If this is no string section the length of each "string" 497825b3c049e70834cf33790a28643ab058b507b35cBen Cheng is always one. */ 497925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int len = (head->flags & SHF_STRINGS) ? 0 : 1; 498025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 498125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is the generic string table functionality. Much 498225b3c049e70834cf33790a28643ab058b507b35cBen Cheng slower than the specialized code. */ 498325b3c049e70834cf33790a28643ab058b507b35cBen Cheng mergestrtab 498425b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_gstrtabinit (SCNINFO_SHDR (head->last->shdr).sh_entsize, 498525b3c049e70834cf33790a28643ab058b507b35cBen Cheng false); 498625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 498725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp = runp->symbols; 498825b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = NULL; 498925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 499025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 499125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Accelarate the loop. We cache the file 499225b3c049e70834cf33790a28643ab058b507b35cBen Cheng information since it might very well be the case 499325b3c049e70834cf33790a28643ab058b507b35cBen Cheng that the previous entry was from the same 499425b3c049e70834cf33790a28643ab058b507b35cBen Cheng file. */ 499525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symrunp->file != file) 499625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 499725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the file. */ 499825b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = symrunp->file; 499925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Symbol table data from that file. */ 500025b3c049e70834cf33790a28643ab058b507b35cBen Cheng locsymdata = file->symtabdata; 500125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* String section data. */ 500225b3c049e70834cf33790a28643ab058b507b35cBen Cheng locdata = elf_rawdata (file->scninfo[symrunp->scndx].scn, 500325b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL); 500425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (locdata != NULL); 500525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 500625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* While we are at it, remember the output 500725b3c049e70834cf33790a28643ab058b507b35cBen Cheng section. If we don't access the string data 500825b3c049e70834cf33790a28643ab058b507b35cBen Cheng section the section won't be in the output 500925b3c049e70834cf33790a28643ab058b507b35cBen Cheng file. So it is sufficient to do the work 501025b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 501125b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->scninfo[symrunp->scndx].outscnndx = head->scnidx; 501225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 501325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 501425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the symbol information. This provides us the 501525b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset into the string data section. */ 501625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 501725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (locsymdata, symrunp->symidx, sym); 501825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 501925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 502025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the data from the file. Using the raw 502125b3c049e70834cf33790a28643ab058b507b35cBen Cheng section data here is possible since we don't 502225b3c049e70834cf33790a28643ab058b507b35cBen Cheng interpret the string themselves except for 502325b3c049e70834cf33790a28643ab058b507b35cBen Cheng looking for the wide NUL character. The NUL 502425b3c049e70834cf33790a28643ab058b507b35cBen Cheng character has fortunately the same representation 502525b3c049e70834cf33790a28643ab058b507b35cBen Cheng regardless of the byte order. */ 502625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merge.handle 502725b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_gstrtabadd (mergestrtab, 502825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (char *) locdata->d_buf + sym->st_value, 502925b3c049e70834cf33790a28643ab058b507b35cBen Cheng len); 503025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 503125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((symrunp = symrunp->next_in_scn) != runp->symbols); 503225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 503325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the final table. */ 503425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_gstrtabfinalize (mergestrtab, outdata); 503525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 503625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute the final offsets in the section. */ 503725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp = runp->symbols; 503825b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 503925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 504025b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merge.value 504125b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_gstrtaboffset (symrunp->merge.handle); 504225b3c049e70834cf33790a28643ab058b507b35cBen Cheng symrunp->merged = 1; 504325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 504425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((symrunp = symrunp->next_in_scn) != runp->symbols); 504525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 504625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't need the string table anymore. */ 504725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_gstrtabfree (mergestrtab); 504825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 504925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 505025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 505125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 505225b3c049e70834cf33790a28643ab058b507b35cBen Cheng no_merge: 505325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (head->scnidx == elf_ndxscn (scn)); 505425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 505525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* It is important to start with the first list entry (and 505625b3c049e70834cf33790a28643ab058b507b35cBen Cheng not just any one) to add the sections in the correct 505725b3c049e70834cf33790a28643ab058b507b35cBen Cheng order. */ 505825b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = head->last->next; 505925b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = 0; 506025b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 506125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 506225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *outdata = elf_newdata (scn); 506325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (outdata == NULL) 506425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 506525b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 506625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 506725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 506825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Exceptional case: if we synthesize a data block SCN 506925b3c049e70834cf33790a28643ab058b507b35cBen Cheng is NULL and the sectio header info must be for a 507025b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHT_NOBITS block and the size and alignment are 507125b3c049e70834cf33790a28643ab058b507b35cBen Cheng filled in. */ 507225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (runp->scn != NULL)) 507325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 507425b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = elf_getdata (runp->scn, NULL); 507525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (data != NULL); 507625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 507725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We reuse the data buffer in the input file. */ 507825b3c049e70834cf33790a28643ab058b507b35cBen Cheng *outdata = *data; 507925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 508025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Given that we read the input file from disk we know there 508125b3c049e70834cf33790a28643ab058b507b35cBen Cheng cannot be another data part. */ 508225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (elf_getdata (runp->scn, data) == NULL); 508325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 508425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 508525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 508625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Must be a NOBITS section. */ 508725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (SCNINFO_SHDR (runp->shdr).sh_type == SHT_NOBITS); 508825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 508925b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_buf = NULL; /* Not needed. */ 509025b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_type = ELF_T_BYTE; 509125b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_version = EV_CURRENT; 509225b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_size = SCNINFO_SHDR (runp->shdr).sh_size; 509325b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_align = SCNINFO_SHDR (runp->shdr).sh_addralign; 509425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 509525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 509625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off align = MAX (1, outdata->d_align); 509725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (powerof2 (align)); 509825b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = ((offset + align - 1) & ~(align - 1)); 509925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 510025b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->offset = offset; 510125b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->outscnndx = head->scnidx; 510225b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->allsectionsidx = cnt; 510325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 510425b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_off = offset; 510525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 510625b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset += outdata->d_size; 510725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 510825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != head->last->next); 510925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 511025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If necessary add the additional line to the .comment section. */ 511125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.add_ld_comment 511225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && head->flags == 0 511325b3c049e70834cf33790a28643ab058b507b35cBen Cheng && head->type == SHT_PROGBITS 511425b3c049e70834cf33790a28643ab058b507b35cBen Cheng && strcmp (head->name, ".comment") == 0 511525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && head->entsize == 0) 511625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 511725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *outdata = elf_newdata (scn); 511825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 511925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (outdata == NULL) 512025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 512125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 512225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 512325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 512425b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_buf = (void *) "\0ld (" PACKAGE_NAME ") " PACKAGE_VERSION; 512525b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_size = strlen ((char *) outdata->d_buf + 1) + 2; 512625b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_off = offset; 512725b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_type = ELF_T_BYTE; 512825b3c049e70834cf33790a28643ab058b507b35cBen Cheng outdata->d_align = 1; 512925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 513025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX We should create a .comment section if none exists. 513125b3c049e70834cf33790a28643ab058b507b35cBen Cheng This requires that we early on detect that no such 513225b3c049e70834cf33790a28643ab058b507b35cBen Cheng section exists. This should probably be implemented 513325b3c049e70834cf33790a28643ab058b507b35cBen Cheng together with some merging of the section contents. 513425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Currently identical entries are not merged. */ 513525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 513625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 513725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 513825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The table we collect the strings in. */ 513925b3c049e70834cf33790a28643ab058b507b35cBen Cheng strtab = ebl_strtabinit (true); 514025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strtab == NULL) 514125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("cannot create string table")); 514225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 514325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 514425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 514525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Keep track of the use of the XINDEX. */ 514625b3c049e70834cf33790a28643ab058b507b35cBen Cheng need_xndx = false; 514725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 514825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 514925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We we generate a normal symbol table for an executable and the 515025b3c049e70834cf33790a28643ab058b507b35cBen Cheng --export-dynamic option is not given, we need an extra table 515125b3c049e70834cf33790a28643ab058b507b35cBen Cheng which keeps track of the symbol entry belonging to the symbol 515225b3c049e70834cf33790a28643ab058b507b35cBen Cheng table entry. Note that EXPORT_ALL_DYNAMIC is always set if we 515325b3c049e70834cf33790a28643ab058b507b35cBen Cheng generate a DSO so we do not have to test this separately. */ 515425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym = (struct symbol **) xcalloc (nsym_allocated, 515525b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (struct symbol)); 515625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 515725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the special symbol for the GOT section. */ 515825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.got_symbol != NULL) 515925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 516025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym < nsym_allocated); 516125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Fix so that it works even if no PLT is needed. 516225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fillin_special_symbol (ld_state.got_symbol, ld_state.gotpltscnidx, 516325b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym++, symdata, strtab); 516425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 516525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 516625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Similarly for the dynamic section symbol. */ 516725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.dyn_symbol != NULL) 516825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 516925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym < nsym_allocated); 517025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fillin_special_symbol (ld_state.dyn_symbol, ld_state.dynamicscnidx, 517125b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym++, symdata, strtab); 517225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 517325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 517425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create symbol table entries for the symbols defined in the linker 517525b3c049e70834cf33790a28643ab058b507b35cBen Cheng script. */ 517625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.lscript_syms != NULL) 517725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 517825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *rsym = ld_state.lscript_syms; 517925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 518025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 518125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym < nsym_allocated); 518225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fillin_special_symbol (rsym, SHN_ABS, nsym++, symdata, strtab); 518325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 518425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((rsym = rsym->next) != NULL); 518525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 518625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 518725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Iterate over all input files to collect the symbols. */ 518825b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = ld_state.relfiles->next; 518925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata = elf_getdata (elf_getscn (ld_state.outelf, ld_state.symscnidx), 519025b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL); 519125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 519225b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 519325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 519425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t maxcnt; 519525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *insymdata; 519625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *inxndxdata; 519725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 519825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There must be no dynamic symbol table when creating 519925b3c049e70834cf33790a28643ab058b507b35cBen Cheng relocatable files. */ 520025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.file_type != relocatable_file_type 520125b3c049e70834cf33790a28643ab058b507b35cBen Cheng || file->dynsymtabdata == NULL); 520225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 520325b3c049e70834cf33790a28643ab058b507b35cBen Cheng insymdata = file->symtabdata; 520425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (insymdata != NULL); 520525b3c049e70834cf33790a28643ab058b507b35cBen Cheng inxndxdata = file->xndxdata; 520625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 520725b3c049e70834cf33790a28643ab058b507b35cBen Cheng maxcnt = file->nsymtab; 520825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 520925b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->symindirect = (Elf32_Word *) xcalloc (maxcnt, sizeof (Elf32_Word)); 521025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 521125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The dynamic symbol table does not contain local symbols. So 521225b3c049e70834cf33790a28643ab058b507b35cBen Cheng we skip those entries. */ 521325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = ld_state.need_symtab ? 1 : file->nlocalsymbols; cnt < maxcnt; 521425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++cnt) 521525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 521625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 521725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word xndx; 521825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *defp = NULL; 521925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 522025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsymshndx (insymdata, inxndxdata, cnt, sym, xndx); 522125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 522225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 522325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (XELF_ST_TYPE (sym->st_info) == STT_SECTION)) 522425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 522525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Section symbols should always be local but who knows... */ 522625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_symtab) 522725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 522825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the real section index in the source file. 522925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Use the XINDEX section content if necessary. We don't 523025b3c049e70834cf33790a28643ab058b507b35cBen Cheng add this information to the dynamic symbol table. */ 523125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_shndx != SHN_XINDEX) 523225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx = sym->st_shndx; 523325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 523425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (file->scninfo[xndx].allsectionsidx 523525b3c049e70834cf33790a28643ab058b507b35cBen Cheng < ld_state.nallsections); 523625b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->symindirect[cnt] = ld_state.allsections[file->scninfo[xndx].allsectionsidx]->scnsymidx; 523725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note that the resulting index can be zero here. There is 523825b3c049e70834cf33790a28643ab058b507b35cBen Cheng no guarantee that the output file will contain all the 523925b3c049e70834cf33790a28643ab058b507b35cBen Cheng sections the input file did. */ 524025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 524125b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 524225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 524325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 524425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((ld_state.strip >= strip_all || !ld_state.need_symtab) 524525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Do we need these entries? */ 524625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && XELF_ST_TYPE (sym->st_info) == STT_FILE) 524725b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 524825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 524925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF != 0 525025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Copy old data. We create a temporary copy because the 525125b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol might still be discarded. */ 525225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym sym_mem; 525325b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym_mem = *sym; 525425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym = &sym_mem; 525525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 525625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 525725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_shndx != SHN_UNDEF 525825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (sym->st_shndx < SHN_LORESERVE 525925b3c049e70834cf33790a28643ab058b507b35cBen Cheng || sym->st_shndx == SHN_XINDEX)) 526025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 526125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we are creating an executable with no normal 526225b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol table and we do not export all symbols and 526325b3c049e70834cf33790a28643ab058b507b35cBen Cheng this symbol is not defined in a DSO as well, ignore 526425b3c049e70834cf33790a28643ab058b507b35cBen Cheng it. */ 526525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!ld_state.export_all_dynamic && !ld_state.need_symtab) 526625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 526725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (cnt >= file->nlocalsymbols); 526825b3c049e70834cf33790a28643ab058b507b35cBen Cheng defp = file->symref[cnt]; 526925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (defp != NULL); 527025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 527125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!defp->in_dso) 527225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Ignore it. */ 527325b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 527425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 527525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 527625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the real section index in the source file. Use 527725b3c049e70834cf33790a28643ab058b507b35cBen Cheng the XINDEX section content if necessary. */ 527825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_shndx != SHN_XINDEX) 527925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx = sym->st_shndx; 528025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 528125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value += file->scninfo[xndx].offset; 528225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 528325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (file->scninfo[xndx].outscnndx < SHN_LORESERVE 528425b3c049e70834cf33790a28643ab058b507b35cBen Cheng || file->scninfo[xndx].outscnndx > SHN_HIRESERVE); 528525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (file->scninfo[xndx].outscnndx > SHN_LORESERVE)) 528625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 528725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* It is not possible to have an extended section index 528825b3c049e70834cf33790a28643ab058b507b35cBen Cheng table for the dynamic symbol table. */ 528925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!ld_state.need_symtab) 529025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 529125b3c049e70834cf33790a28643ab058b507b35cBen Chengsection index too large in dynamic symbol table")); 529225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 529325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (xndxdata != NULL); 529425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx = SHN_XINDEX; 529525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx = file->scninfo[xndx].outscnndx; 529625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifndef NDEBUG 529725b3c049e70834cf33790a28643ab058b507b35cBen Cheng need_xndx = true; 529825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 529925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 530025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 530125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 530225b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx = file->scninfo[xndx].outscnndx; 530325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx = 0; 530425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 530525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 530625b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (sym->st_shndx == SHN_COMMON || sym->st_shndx == SHN_UNDEF) 530725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 530825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check whether we have a (real) definition for this 530925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol. If this is the case we skip this symbol 531025b3c049e70834cf33790a28643ab058b507b35cBen Cheng table entry. */ 531125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (cnt >= file->nlocalsymbols); 531225b3c049e70834cf33790a28643ab058b507b35cBen Cheng defp = file->symref[cnt]; 531325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (defp != NULL); 531425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 531525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym->st_shndx != SHN_COMMON || defp->defined); 531625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 531725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((sym->st_shndx == SHN_COMMON && !defp->common) 531825b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (sym->st_shndx == SHN_UNDEF && defp->defined) 531925b3c049e70834cf33790a28643ab058b507b35cBen Cheng || defp->added) 532025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Ignore this symbol table entry, there is a 532125b3c049e70834cf33790a28643ab058b507b35cBen Cheng "better" one or we already added it. */ 532225b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 532325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 532425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember that we already added this symbol. */ 532525b3c049e70834cf33790a28643ab058b507b35cBen Cheng defp->added = 1; 532625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 532725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Adjust the section number for common symbols. */ 532825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_shndx == SHN_COMMON) 532925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 533025b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value = (ld_state.common_section->offset 533125b3c049e70834cf33790a28643ab058b507b35cBen Cheng + file->symref[cnt]->merge.value); 533225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.common_section->outscnndx < SHN_LORESERVE); 533325b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx = ld_state.common_section->outscnndx; 533425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx = 0; 533525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 533625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 533725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (unlikely (sym->st_shndx != SHN_ABS)) 533825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 533925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (SPECIAL_SECTION_NUMBER_P (&ld_state, sym->st_shndx)) 534025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Add code to handle machine specific special 534125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sections. */ 534225b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 534325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 534425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 534525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the symbol name to the string table. If the user 534625b3c049e70834cf33790a28643ab058b507b35cBen Cheng chooses the highest level of stripping avoid adding names 534725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for local symbols in the string table. */ 534825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_name != 0 534925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (ld_state.strip < strip_everything 535025b3c049e70834cf33790a28643ab058b507b35cBen Cheng || XELF_ST_BIND (sym->st_info) != STB_LOCAL)) 535125b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[nsym] = ebl_strtabadd (strtab, 535225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_strptr (file->elf, 535325b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->symstridx, 535425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_name), 0); 535525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 535625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Once we know the name this field will get the correct 535725b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset. For now set it to zero which means no name 535825b3c049e70834cf33790a28643ab058b507b35cBen Cheng associated. */ 535925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Word st_name = sym->st_name; 536025b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_name = 0; 536125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 536225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we had to merge sections we have a completely new 536325b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset for the symbol. */ 536425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (file->has_merge_sections && file->symref[cnt] != NULL 536525b3c049e70834cf33790a28643ab058b507b35cBen Cheng && file->symref[cnt]->merged) 536625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value = file->symref[cnt]->merge.value; 536725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 536825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the record in the output sections. */ 536925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym < nsym_allocated); 537025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_update_symshndx (symdata, xndxdata, nsym, sym, xndx, 1); 537125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 537225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the reference to the symbol record in case we need it. 537325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Find the symbol if this has not happened yet. We do 537425b3c049e70834cf33790a28643ab058b507b35cBen Cheng not need the information for local symbols. */ 537525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (defp == NULL && cnt >= file->nlocalsymbols) 537625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 537725b3c049e70834cf33790a28643ab058b507b35cBen Cheng defp = file->symref[cnt]; 537825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 537925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (defp == NULL) 538025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 538125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is a symbol in a discarded COMDAT section. 538225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Find the definition we actually use. */ 538325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX The question is: do we have to do this here 538425b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX or can we do it earlier when we discard the 538525b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX section. 538625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol search; 538725b3c049e70834cf33790a28643ab058b507b35cBen Cheng search.name = elf_strptr (file->elf, file->symstridx, 538825b3c049e70834cf33790a28643ab058b507b35cBen Cheng st_name); 538925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *realp 539025b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ld_symbol_tab_find (&ld_state.symbol_tab, 539125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_hash (search.name), &search); 539225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (realp == NULL) 539325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX What to do here? 539425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 539525b3c049e70834cf33790a28643ab058b507b35cBen Cheng "couldn't find symbol from COMDAT section"); 539625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 539725b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->symref[cnt] = realp; 539825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 539925b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 540025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 540125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 540225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 540325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the reference to the symbol record. The sorting 540425b3c049e70834cf33790a28643ab058b507b35cBen Cheng code will have to keep this array in the correct order, too. */ 540525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym[nsym] = defp; 540625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 540725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* One more entry finished. */ 540825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (cnt >= file->nlocalsymbols) 540925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 541025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (file->symref[cnt]->outsymidx == 0); 541125b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->symref[cnt]->outsymidx = nsym; 541225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 541325b3c049e70834cf33790a28643ab058b507b35cBen Cheng file->symindirect[cnt] = nsym++; 541425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 541525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 541625b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((file = file->next) != ld_state.relfiles->next); 541725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make sure we didn't create the extended section index table for 541825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nothing. */ 541925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (xndxdata == NULL || need_xndx); 542025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 542125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the version related sections. */ 542225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.verneedscnidx != 0) 542325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 542425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We know the number of input files and total number of 542525b3c049e70834cf33790a28643ab058b507b35cBen Cheng referenced versions. This allows us to allocate the memory 542625b3c049e70834cf33790a28643ab058b507b35cBen Cheng and then we iterate over the DSOs to get the version 542725b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 542825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *runp; 542925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 543025b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = ld_state.dsofiles->next; 543125b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 543225b3c049e70834cf33790a28643ab058b507b35cBen Cheng allocate_version_names (runp, dynstrtab); 543325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != ld_state.dsofiles->next); 543425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 543525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.needed != NULL) 543625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 543725b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = ld_state.needed->next; 543825b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 543925b3c049e70834cf33790a28643ab058b507b35cBen Cheng allocate_version_names (runp, dynstrtab); 544025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != ld_state.needed->next); 544125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 544225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 544325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 544425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* At this point we should hide symbols and so on. */ 544525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.default_bind_local || ld_state.version_str_tab.filled > 0) 544625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Add one more test when handling of wildcard symbol names 544725b3c049e70834cf33790a28643ab058b507b35cBen Cheng is supported. */ 544825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 544925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Check all non-local symbols whether they are on the export list. */ 545025b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool any_reduced = false; 545125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 545225b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 1; cnt < nsym; ++cnt) 545325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 545425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 545525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 545625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note that we don't have to use 'xelf_getsymshndx' since we 545725b3c049e70834cf33790a28643ab058b507b35cBen Cheng only need the binding and the symbol name. */ 545825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, cnt, sym); 545925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 546025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 546125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (reduce_symbol_p (sym, symstrent[cnt])) 546225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 546325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Check whether this is correct... 546425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ndxtosym[cnt]->outdynsymidx != 0); 546525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym[cnt]->outdynsymidx = 0; 546625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 546725b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_info = XELF_ST_INFO (STB_LOCAL, 546825b3c049e70834cf33790a28643ab058b507b35cBen Cheng XELF_ST_TYPE (sym->st_info)); 546925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (symdata, cnt, sym); 547025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 547125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Show that we don't need this string anymore. */ 547225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.strip == strip_everything) 547325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 547425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[cnt] = NULL; 547525b3c049e70834cf33790a28643ab058b507b35cBen Cheng any_reduced = true; 547625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 547725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 547825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 547925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 548025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (any_reduced)) 548125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 548225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Since we will not write names of local symbols in the 548325b3c049e70834cf33790a28643ab058b507b35cBen Cheng output file and we have reduced the binding of some 548425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbols the string table previously constructed contains 548525b3c049e70834cf33790a28643ab058b507b35cBen Cheng too many string. Correct it. */ 548625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strtab *newp = ebl_strtabinit (true); 548725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 548825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 1; cnt < nsym; ++cnt) 548925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symstrent[cnt] != NULL) 549025b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[cnt] = ebl_strtabadd (newp, 549125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_string (symstrent[cnt]), 0); 549225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 549325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_strtabfree (strtab); 549425b3c049e70834cf33790a28643ab058b507b35cBen Cheng strtab = newp; 549525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 549625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 549725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 549825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the references to DSOs. We can add these entries this late 549925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (after sorting out versioning) because references to DSOs are not 550025b3c049e70834cf33790a28643ab058b507b35cBen Cheng effected. */ 550125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.from_dso != NULL) 550225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 550325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *runp; 550425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t plt_base = nsym + ld_state.nfrom_dso - ld_state.nplt; 550525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t plt_idx = 0; 550625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t obj_idx = 0; 550725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 550825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.nfrom_dso >= ld_state.nplt); 550925b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = ld_state.from_dso; 551025b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 551125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 551225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX What about functions which are only referenced via 551325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // pointers and not PLT entries? Can we distinguish such uses? 551425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t idx; 551525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->type == STT_FUNC) 551625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 551725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the PLT entry number. */ 551825b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->merge.value = plt_idx + 1; 551925b3c049e70834cf33790a28643ab058b507b35cBen Cheng idx = plt_base + plt_idx++; 552025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 552125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 552225b3c049e70834cf33790a28643ab058b507b35cBen Cheng idx = nsym + obj_idx++; 552325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 552425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 552525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym_ptr (symdata, idx, sym); 552625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 552725b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value = 0; 552825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_size = runp->size; 552925b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_info = XELF_ST_INFO (runp->weak ? STB_WEAK : STB_GLOBAL, 553025b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->type); 553125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_other = STV_DEFAULT; 553225b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_shndx = SHN_UNDEF; 553325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 553425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the record in the output sections. */ 553525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_update_symshndx (symdata, xndxdata, idx, sym, 0, 0); 553625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 553725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = runp->name; 553825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t namelen = 0; 553925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 554025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->file->verdefdata != NULL) 554125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 554225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Is it useful to add the versym value to struct symbol? 554325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Versym versym; 554425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 554525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_getversym_copy (runp->file->versymdata, runp->symidx, 554625b3c049e70834cf33790a28643ab058b507b35cBen Cheng versym); 554725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 554825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* One can only link with the default version. */ 554925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((versym & 0x8000) == 0); 555025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 555125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *versname 555225b3c049e70834cf33790a28643ab058b507b35cBen Cheng = ebl_string (runp->file->verdefent[versym]); 555325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 555425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t versname_len = strlen (versname) + 1; 555525b3c049e70834cf33790a28643ab058b507b35cBen Cheng namelen = strlen (name) + versname_len + 2; 555625b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *newp = (char *) obstack_alloc (&ld_state.smem, namelen); 555725b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (stpcpy (stpcpy (newp, name), "@@"), 555825b3c049e70834cf33790a28643ab058b507b35cBen Cheng versname, versname_len); 555925b3c049e70834cf33790a28643ab058b507b35cBen Cheng name = newp; 556025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 556125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 556225b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[idx] = ebl_strtabadd (strtab, name, namelen); 556325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 556425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Record the initial index in the symbol table. */ 556525b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp->outsymidx = idx; 556625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 556725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the symbol record this ELF symbol came from. */ 556825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym[idx] = runp; 556925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 557025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != ld_state.from_dso); 557125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 557225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (nsym + obj_idx == plt_base); 557325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (plt_idx == ld_state.nplt); 557425b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym = plt_base + plt_idx; 557525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 557625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 557725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now we know how many symbols will be in the output file. Adjust 557825b3c049e70834cf33790a28643ab058b507b35cBen Cheng the count in the section data. */ 557925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_SYM, nsym); 558025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (xndxdata != NULL)) 558125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndxdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_WORD, nsym); 558225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 558325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the symbol string table section. */ 558425b3c049e70834cf33790a28643ab058b507b35cBen Cheng strscn = elf_newscn (ld_state.outelf); 558525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.strscnidx = elf_ndxscn (strscn); 558625b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = elf_newdata (strscn); 558725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (strscn, shdr); 558825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL || shdr == NULL) 558925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 559025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 559125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 559225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 559325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create a compact string table, allocate the memory for it, and 559425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fill in the section data information. */ 559525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_strtabfinalize (strtab, data); 559625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 559725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_type = SHT_STRTAB; 559825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr->sh_entsize == 0); 559925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 560025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (xelf_update_shdr (strscn, shdr) == 0)) 560125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 560225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section for output file: %s"), 560325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 560425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 560525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fill in the offsets of the symbol names. */ 560625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 1; cnt < nsym; ++cnt) 560725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symstrent[cnt] != NULL) 560825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 560925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 561025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 561125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note that we don't have to use 'xelf_getsymshndx' since we don't 561225b3c049e70834cf33790a28643ab058b507b35cBen Cheng modify the section index. */ 561325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, cnt, sym); 561425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This better worked, we did it before. */ 561525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 561625b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_name = ebl_strtaboffset (symstrent[cnt]); 561725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (symdata, cnt, sym); 561825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 561925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 562025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Since we are going to reorder the symbol table but still have to 562125b3c049e70834cf33790a28643ab058b507b35cBen Cheng be able to find the new position based on the old one (since the 562225b3c049e70834cf33790a28643ab058b507b35cBen Cheng latter is stored in 'symindirect' information of the input file 562325b3c049e70834cf33790a28643ab058b507b35cBen Cheng data structure) we have to create yet another indirection 562425b3c049e70834cf33790a28643ab058b507b35cBen Cheng table. */ 562525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.dblindirect = dblindirect 562625b3c049e70834cf33790a28643ab058b507b35cBen Cheng = (Elf32_Word *) xmalloc (nsym * sizeof (Elf32_Word)); 562725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 562825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Sort the symbol table so that the local symbols come first. */ 562925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX We don't use stable sorting here. It seems not necessary and 563025b3c049e70834cf33790a28643ab058b507b35cBen Cheng would be more expensive. If it turns out to be necessary this can 563125b3c049e70834cf33790a28643ab058b507b35cBen Cheng be fixed easily. */ 563225b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_local = 1; 563325b3c049e70834cf33790a28643ab058b507b35cBen Cheng cnt = nsym - 1; 563425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (nsym_local < cnt) 563525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 563625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (locsym); 563725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word locxndx; 563825b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (globsym); 563925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word globxndx; 564025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 564125b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 564225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 564325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsymshndx (symdata, xndxdata, nsym_local, locsym, locxndx); 564425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This better works. */ 564525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (locsym != NULL); 564625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 564725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (XELF_ST_BIND (locsym->st_info) != STB_LOCAL 564825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (ld_state.need_symtab || ld_state.export_all_dynamic)) 564925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 565025b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 565125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 565225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsymshndx (symdata, xndxdata, cnt, globsym, globxndx); 565325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This better works. */ 565425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (globsym != NULL); 565525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 565625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (XELF_ST_BIND (globsym->st_info) == STB_LOCAL)) 565725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 565825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We swap the two entries. */ 565925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF != 0 566025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Since we directly modify the data in the ELF 566125b3c049e70834cf33790a28643ab058b507b35cBen Cheng data structure we have to make a copy of one 566225b3c049e70834cf33790a28643ab058b507b35cBen Cheng of the entries. */ 566325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym locsym_copy = *locsym; 566425b3c049e70834cf33790a28643ab058b507b35cBen Cheng locsym = &locsym_copy; 566525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 566625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_update_symshndx (symdata, xndxdata, nsym_local, 566725b3c049e70834cf33790a28643ab058b507b35cBen Cheng globsym, globxndx, 1); 566825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_update_symshndx (symdata, xndxdata, cnt, 566925b3c049e70834cf33790a28643ab058b507b35cBen Cheng locsym, locxndx, 1); 567025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 567125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Also swap the cross references. */ 567225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dblindirect[nsym_local] = cnt; 567325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dblindirect[cnt] = nsym_local; 567425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 567525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And the entries for the symbol names. */ 567625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct Ebl_Strent *strtmp = symstrent[nsym_local]; 567725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[nsym_local] = symstrent[cnt]; 567825b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[cnt] = strtmp; 567925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 568025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And the mapping from symbol table entry to 568125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol record. */ 568225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *symtmp = ndxtosym[nsym_local]; 568325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym[nsym_local] = ndxtosym[cnt]; 568425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym[cnt] = symtmp; 568525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 568625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Go to the next entry. */ 568725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nsym_local; 568825b3c049e70834cf33790a28643ab058b507b35cBen Cheng --cnt; 568925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 569025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 569125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 569225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 569325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dblindirect[cnt] = cnt; 569425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 569525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (nsym_local < --cnt); 569625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 569725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 569825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 569925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 570025b3c049e70834cf33790a28643ab058b507b35cBen Cheng dblindirect[nsym_local] = nsym_local; 570125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 570225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (++nsym_local < cnt); 570325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 570425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 570525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The symbol 'nsym_local' is currently pointing to might be local, 570625b3c049e70834cf33790a28643ab058b507b35cBen Cheng too. Check and increment the variable if this is the case. */ 570725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (nsym_local < nsym)) 570825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 570925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (locsym); 571025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 571125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This entry isn't moved. */ 571225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dblindirect[nsym_local] = nsym_local; 571325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 571425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note that it is OK to not use 'xelf_getsymshndx' here. */ 571525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, nsym_local, locsym); 571625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This better works. */ 571725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (locsym != NULL); 571825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 571925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (XELF_ST_BIND (locsym->st_info) == STB_LOCAL) 572025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nsym_local; 572125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 572225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 572325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 572425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We need the versym array right away to keep track of the version 572525b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbols. */ 572625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.versymscnidx != 0) 572725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 572825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We allocate more memory than we need since the array is morroring 572925b3c049e70834cf33790a28643ab058b507b35cBen Cheng the dynamic symbol table and not the normal symbol table. I.e., 573025b3c049e70834cf33790a28643ab058b507b35cBen Cheng no local symbols are present. */ 573125b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymscn = elf_getscn (ld_state.outelf, ld_state.versymscnidx); 573225b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymdata = elf_newdata (versymscn); 573325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (versymdata == NULL) 573425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 573525b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create versioning section: %s"), 573625b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 573725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 573825b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_HALF, 573925b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym - nsym_local + 1); 574025b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymdata->d_buf = xcalloc (1, versymdata->d_size); 574125b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymdata->d_align = xelf_fsize (ld_state.outelf, ELF_T_HALF, 1); 574225b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymdata->d_off = 0; 574325b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymdata->d_type = ELF_T_HALF; 574425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 574525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 574625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 574725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we have to construct the dynamic symbol table we must not include 574825b3c049e70834cf33790a28643ab058b507b35cBen Cheng the local symbols. If the normal symbol has to be emitted as well 574925b3c049e70834cf33790a28643ab058b507b35cBen Cheng we haven't done anything else yet and we can construct it from 575025b3c049e70834cf33790a28643ab058b507b35cBen Cheng scratch now. */ 575125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (!ld_state.need_symtab)) 575225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 575325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note that the following code works even if there is no entry 575425b3c049e70834cf33790a28643ab058b507b35cBen Cheng to remove since the zeroth entry is always local. */ 575525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t reduce = xelf_fsize (ld_state.outelf, ELF_T_SYM, nsym_local - 1); 575625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 575725b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (nullsym); 575825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym_ptr (symdata, nsym_local - 1, nullsym); 575925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 576025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note that we don't have to use 'xelf_update_symshndx' since 576125b3c049e70834cf33790a28643ab058b507b35cBen Cheng this is the dynamic symbol table we write. */ 576225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (symdata, nsym_local - 1, 576325b3c049e70834cf33790a28643ab058b507b35cBen Cheng memset (nullsym, '\0', sizeof (*nullsym))); 576425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 576525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Update the buffer pointer and size in the output data. */ 576625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_buf = (char *) symdata->d_buf + reduce; 576725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symdata->d_size -= reduce; 576825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 576925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the version symbol information. */ 577025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (versymdata != NULL) 577125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 577225b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_dyn = 1; 577325b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = nsym_local; cnt < nsym; ++cnt, ++nsym_dyn) 577425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 577525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *symp = ndxtosym[cnt]; 577625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 577725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symp->file->versymdata != NULL) 577825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 577925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Versym versym; 578025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 578125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getversym (symp->file->versymdata, symp->symidx, 578225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &versym); 578325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 578425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) gelf_update_versym (versymdata, symp->outdynsymidx, 578525b3c049e70834cf33790a28643ab058b507b35cBen Cheng &symp->file->verdefused[versym]); 578625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 578725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 578825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 578925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 579025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Since we only created the dynamic symbol table the number of 579125b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynamic symbols is the total number of symbols. */ 579225b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_dyn = nsym - nsym_local + 1; 579325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 579425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX TBI. Create whatever data structure is missing. */ 579525b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 579625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 579725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (ld_state.need_dynsym) 579825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 579925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the dynamic symbol table section data along with the 580025b3c049e70834cf33790a28643ab058b507b35cBen Cheng string table. We look at all non-local symbols we found for 580125b3c049e70834cf33790a28643ab058b507b35cBen Cheng the normal symbol table and add those. */ 580225b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynsymscn = elf_getscn (ld_state.outelf, ld_state.dynsymscnidx); 580325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynsymdata = elf_newdata (dynsymscn); 580425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 580525b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynstrdata = elf_newdata (elf_getscn (ld_state.outelf, 580625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.dynstrscnidx)); 580725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dynsymdata == NULL || dynstrdata == NULL) 580825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 580925b3c049e70834cf33790a28643ab058b507b35cBen Chengcannot create dynamic symbol table for output file: %s"), 581025b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 581125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 581225b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_dyn_allocated = nsym - nsym_local + 1; 581325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynsymdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_SYM, 581425b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_dyn_allocated); 581525b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynsymdata->d_buf = memset (xmalloc (dynsymdata->d_size), '\0', 581625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_SYM, 1)); 581725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynsymdata->d_type = ELF_T_SYM; 581825b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynsymdata->d_off = 0; 581925b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynsymdata->d_align = xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1); 582025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 582125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We need one more array which contains the hash codes of the 582225b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol names. */ 582325b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashcodes = (Elf32_Word *) xcalloc (__builtin_popcount ((int) ld_state.hash_style) 582425b3c049e70834cf33790a28643ab058b507b35cBen Cheng * nsym_dyn_allocated, 582525b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (Elf32_Word)); 582625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnuhashcodes = hashcodes; 582725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (GENERATE_SYSV_HASH) 582825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnuhashcodes += nsym_dyn_allocated; 582925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 583025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have and empty entry at the beginning. */ 583125b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_dyn = 1; 583225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 583325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Populate the table. */ 583425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = nsym_local; cnt < nsym; ++cnt) 583525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 583625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 583725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 583825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, cnt, sym); 583925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 584025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 584125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_shndx == SHN_XINDEX) 584225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 584325b3c049e70834cf33790a28643ab058b507b35cBen Chengsection index too large in dynamic symbol table")); 584425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 584525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We do not add the symbol to the dynamic symbol table if 584625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 584725b3c049e70834cf33790a28643ab058b507b35cBen Cheng - the symbol is for a file 584825b3c049e70834cf33790a28643ab058b507b35cBen Cheng - it is not externally visible (internal, hidden) 584925b3c049e70834cf33790a28643ab058b507b35cBen Cheng - export_all_dynamic is not set and the symbol is only defined 585025b3c049e70834cf33790a28643ab058b507b35cBen Cheng in the executable (i.e., it is defined, but not (also) in DSO) 585125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 585225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Set symstrent[cnt] to NULL in case an entry is ignored. */ 585325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (XELF_ST_TYPE (sym->st_info) == STT_FILE 585425b3c049e70834cf33790a28643ab058b507b35cBen Cheng || XELF_ST_VISIBILITY (sym->st_other) == STV_INTERNAL 585525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || XELF_ST_VISIBILITY (sym->st_other) == STV_HIDDEN 585625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (!ld_state.export_all_dynamic 585725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && !ndxtosym[cnt]->in_dso && ndxtosym[cnt]->defined)) 585825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 585925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[cnt] = NULL; 586025b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 586125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 586225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 586325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the index of the symbol in the dynamic symbol 586425b3c049e70834cf33790a28643ab058b507b35cBen Cheng table. This is a preliminary value in case we use the 586525b3c049e70834cf33790a28643ab058b507b35cBen Cheng GNU-style hash table. */ 586625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ndxtosym[cnt]->outdynsymidx = nsym_dyn; 586725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 586825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create a new string table entry. */ 586925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *str = ndxtosym[cnt]->name; 587025b3c049e70834cf33790a28643ab058b507b35cBen Cheng symstrent[cnt] = ebl_strtabadd (dynstrtab, str, 0); 587125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (GENERATE_SYSV_HASH) 587225b3c049e70834cf33790a28643ab058b507b35cBen Cheng hashcodes[nsym_dyn] = elf_hash (str); 587325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (GENERATE_GNU_HASH) 587425b3c049e70834cf33790a28643ab058b507b35cBen Cheng gnuhashcodes[nsym_dyn] = elf_gnu_hash (str); 587525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nsym_dyn; 587625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 587725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 587825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type != relocatable_file_type) 587925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 588025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Finalize the dynamic string table. */ 588125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_strtabfinalize (dynstrtab, dynstrdata); 588225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 588325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.hashscnidx != 0 || ld_state.gnuhashscnidx != 0); 588425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 588525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the GNU-style hash table. */ 588625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (GENERATE_GNU_HASH) 588725b3c049e70834cf33790a28643ab058b507b35cBen Cheng create_gnu_hash (nsym_local, nsym, nsym_dyn, gnuhashcodes); 588825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 588925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the SysV-style hash table. This has to happen 589025b3c049e70834cf33790a28643ab058b507b35cBen Cheng after the GNU-style table is created since 589125b3c049e70834cf33790a28643ab058b507b35cBen Cheng CREATE-GNU-HASH might reorder the dynamic symbol table. */ 589225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (GENERATE_SYSV_HASH) 589325b3c049e70834cf33790a28643ab058b507b35cBen Cheng create_hash (nsym_local, nsym, nsym_dyn, hashcodes); 589425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 589525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 589625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the version information. */ 589725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (versymdata != NULL) 589825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = nsym_local; cnt < nsym; ++cnt) 589925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symstrent[cnt] != NULL) 590025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 590125b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *symp = ndxtosym[cnt]; 590225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 590325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Synthetic symbols (i.e., those with no file attached) 590425b3c049e70834cf33790a28643ab058b507b35cBen Cheng have no version information. */ 590525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symp->file != NULL && symp->file->verdefdata != NULL) 590625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 590725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Versym versym; 590825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 590925b3c049e70834cf33790a28643ab058b507b35cBen Cheng gelf_getversym (symp->file->versymdata, symp->symidx, 591025b3c049e70834cf33790a28643ab058b507b35cBen Cheng &versym); 591125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 591225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) gelf_update_versym (versymdata, symp->outdynsymidx, 591325b3c049e70834cf33790a28643ab058b507b35cBen Cheng &symp->file->verdefused[versym]); 591425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 591525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 591625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 591725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Add support for version definitions. */ 591825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Versym global = VER_NDX_GLOBAL; 591925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) gelf_update_versym (versymdata, nsym_dyn, &global); 592025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 592125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 592225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 592325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Update the information about the symbol section. */ 592425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (versymdata != NULL) 592525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 592625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Correct the size now that we know how many entries the 592725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynamic symbol table has. */ 592825b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_HALF, 592925b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_dyn); 593025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 593125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the reference to the symbol table. */ 593225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (versymscn, shdr); 593325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 593425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 593525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.dynsymscnidx; 593625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 593725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (versymscn, shdr); 593825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 593925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 594025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 594125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type != relocatable_file_type) 594225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 594325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now put the names in. */ 594425b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = nsym_local; cnt < nsym; ++cnt) 594525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symstrent[cnt] != NULL) 594625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 594725b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 594825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t dynidx = ndxtosym[cnt]->outdynsymidx; 594925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 595025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#if NATIVE_ELF != 0 595125b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym *osym; 595225b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (xelf_getsym (dynsymdata, dynidx, sym), 595325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, cnt, osym), 595425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sizeof (XElf_Sym)); 595525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#else 595625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, cnt, sym); 595725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 595825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 595925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 596025b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_name = ebl_strtaboffset (symstrent[cnt]); 596125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 596225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (dynsymdata, dynidx, sym); 596325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 596425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 596525b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (hashcodes); 596625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 596725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the required version section. */ 596825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.verneedscnidx != 0) 596925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 597025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *verneedscn; 597125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *verneeddata; 597225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *runp; 597325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t verneed_size = xelf_fsize (ld_state.outelf, ELF_T_VNEED, 1); 597425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t vernaux_size = xelf_fsize (ld_state.outelf, ELF_T_VNAUX, 1); 597525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t offset; 597625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int ntotal; 597725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 597825b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneedscn = elf_getscn (ld_state.outelf, ld_state.verneedscnidx); 597925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (verneedscn, shdr); 598025b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneeddata = elf_newdata (verneedscn); 598125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL || verneeddata == NULL) 598225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 598325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create versioning data: %s"), 598425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 598525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 598625b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneeddata->d_size = (ld_state.nverdeffile * verneed_size 598725b3c049e70834cf33790a28643ab058b507b35cBen Cheng + ld_state.nverdefused * vernaux_size); 598825b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneeddata->d_buf = xmalloc (verneeddata->d_size); 598925b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneeddata->d_type = ELF_T_VNEED; 599025b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneeddata->d_align = xelf_fsize (ld_state.outelf, ELF_T_WORD, 1); 599125b3c049e70834cf33790a28643ab058b507b35cBen Cheng verneeddata->d_off = 0; 599225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 599325b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = 0; 599425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ntotal = ld_state.nverdeffile; 599525b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = ld_state.dsofiles->next; 599625b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 599725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 599825b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = create_verneed_data (offset, verneeddata, runp, 599925b3c049e70834cf33790a28643ab058b507b35cBen Cheng &ntotal); 600025b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = runp->next; 600125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 600225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (ntotal > 0 && runp != ld_state.dsofiles->next); 600325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 600425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ntotal > 0) 600525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 600625b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = ld_state.needed->next; 600725b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 600825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 600925b3c049e70834cf33790a28643ab058b507b35cBen Cheng offset = create_verneed_data (offset, verneeddata, runp, 601025b3c049e70834cf33790a28643ab058b507b35cBen Cheng &ntotal); 601125b3c049e70834cf33790a28643ab058b507b35cBen Cheng runp = runp->next; 601225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 601325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (ntotal > 0 && runp != ld_state.needed->next); 601425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 601525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 601625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (offset == verneeddata->d_size); 601725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 601825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the needed information to the section header. */ 601925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.dynstrscnidx; 602025b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info = ld_state.nverdeffile; 602125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (verneedscn, shdr); 602225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 602325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 602425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Adjust the section size. */ 602525b3c049e70834cf33790a28643ab058b507b35cBen Cheng dynsymdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_SYM, nsym_dyn); 602625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (versymdata != NULL) 602725b3c049e70834cf33790a28643ab058b507b35cBen Cheng versymdata->d_size = xelf_fsize (ld_state.outelf, ELF_T_HALF, 602825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nsym_dyn); 602925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 603025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the remaining information to the section header. */ 603125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (dynsymscn, shdr); 603225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There is always exactly one local symbol. */ 603325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info = 1; 603425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Reference the string table. */ 603525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.dynstrscnidx; 603625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Write the updated info back. */ 603725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (dynsymscn, shdr); 603825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 603925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 604025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't need the string table anymore. */ 604125b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (symstrent); 604225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 604325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the total number of symbols in the dynamic symbol table. */ 604425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.ndynsym = nsym_dyn; 604525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 604625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fill in the section header information. */ 604725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symscn = elf_getscn (ld_state.outelf, ld_state.symscnidx); 604825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (symscn, shdr); 604925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL) 605025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 605125b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create symbol table for output file: %s"), 605225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 605325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 605425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_type = SHT_SYMTAB; 605525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.strscnidx; 605625b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info = nsym_local; 605725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_entsize = xelf_fsize (ld_state.outelf, ELF_T_SYM, 1); 605825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 605925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (symscn, shdr); 606025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 606125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 606225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add names for the generated sections. */ 606325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.symscnidx != 0) 606425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab_ent = ebl_strtabadd (ld_state.shstrtab, ".symtab", 8); 606525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.xndxscnidx != 0) 606625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xndx_ent = ebl_strtabadd (ld_state.shstrtab, ".symtab_shndx", 14); 606725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.strscnidx != 0) 606825b3c049e70834cf33790a28643ab058b507b35cBen Cheng strtab_ent = ebl_strtabadd (ld_state.shstrtab, ".strtab", 8); 606925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* At this point we would have to test for failures in the 607025b3c049e70834cf33790a28643ab058b507b35cBen Cheng allocation. But we skip this. First, the problem will be caught 607125b3c049e70834cf33790a28643ab058b507b35cBen Cheng later when doing more allocations for the section header table. 607225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Even if this would not be the case all that would happen is that 607325b3c049e70834cf33790a28643ab058b507b35cBen Cheng the section names are empty. The binary would still be usable if 607425b3c049e70834cf33790a28643ab058b507b35cBen Cheng it is an executable or a DSO. Not adding the test here saves 607525b3c049e70834cf33790a28643ab058b507b35cBen Cheng quite a bit of code. */ 607625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 607725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 607825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Finally create the section for the section header string table. */ 607925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shstrtab_scn = elf_newscn (ld_state.outelf); 608025b3c049e70834cf33790a28643ab058b507b35cBen Cheng shstrtab_ndx = elf_ndxscn (shstrtab_scn); 608125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shstrtab_ndx == SHN_UNDEF)) 608225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 608325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section header string section: %s"), 608425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 608525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 608625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the name of the section to the string table. */ 608725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shstrtab_ent = ebl_strtabadd (ld_state.shstrtab, ".shstrtab", 10); 608825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shstrtab_ent == NULL)) 608925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, 609025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section header string section")); 609125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 609225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Finalize the section header string table. */ 609325b3c049e70834cf33790a28643ab058b507b35cBen Cheng data = elf_newdata (shstrtab_scn); 609425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 609525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 609625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section header string section: %s"), 609725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 609825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_strtabfinalize (ld_state.shstrtab, data); 609925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 610025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now we know the string offsets for all section names. */ 610125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 0; cnt < ld_state.nallsections; ++cnt) 610225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.allsections[cnt]->scnidx != 0) 610325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 610425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn; 610525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 610625b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = elf_getscn (ld_state.outelf, ld_state.allsections[cnt]->scnidx); 610725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 610825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 610925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 611025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 611125b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name = ebl_strtaboffset (ld_state.allsections[cnt]->nameent); 611225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 611325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (xelf_update_shdr (scn, shdr) == 0) 611425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (0); 611525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 611625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 611725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the names for the generated sections to the respective 611825b3c049e70834cf33790a28643ab058b507b35cBen Cheng section headers. */ 611925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symtab_ent != NULL) 612025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 612125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_getscn (ld_state.outelf, ld_state.symscnidx); 612225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 612325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 612425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot fail, we already accessed the header before. */ 612525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 612625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 612725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name = ebl_strtaboffset (symtab_ent); 612825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 612925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (scn, shdr); 613025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 613125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (xndx_ent != NULL) 613225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 613325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_getscn (ld_state.outelf, ld_state.xndxscnidx); 613425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 613525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 613625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot fail, we already accessed the header before. */ 613725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 613825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 613925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name = ebl_strtaboffset (xndx_ent); 614025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 614125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (scn, shdr); 614225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 614325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strtab_ent != NULL) 614425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 614525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_getscn (ld_state.outelf, ld_state.strscnidx); 614625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 614725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 614825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot fail, we already accessed the header before. */ 614925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 615025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 615125b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name = ebl_strtaboffset (strtab_ent); 615225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 615325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (scn, shdr); 615425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 615525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 615625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And the section header table section itself. */ 615725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (shstrtab_scn, shdr); 615825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL) 615925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 616025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section header string section: %s"), 616125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 616225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 616325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name = ebl_strtaboffset (shstrtab_ent); 616425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_type = SHT_STRTAB; 616525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 616625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (xelf_update_shdr (shstrtab_scn, shdr) == 0)) 616725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 616825b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot create section header string section: %s"), 616925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 617025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 617125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 617225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the correct section header info to the section group sections. */ 617325b3c049e70834cf33790a28643ab058b507b35cBen Cheng groups = ld_state.groups; 617425b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (groups != NULL) 617525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 617625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_getscn (ld_state.outelf, groups->outscnidx); 617725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 617825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 617925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 618025b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_name = ebl_strtaboffset (groups->nameent); 618125b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_type = SHT_GROUP; 618225b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_flags = 0; 618325b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.symscnidx; 618425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_entsize = sizeof (Elf32_Word); 618525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 618625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the index for the signature symbol. */ 618725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word si 618825b3c049e70834cf33790a28643ab058b507b35cBen Cheng = groups->symbol->file->symindirect[groups->symbol->symidx]; 618925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (si == 0) 619025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 619125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (groups->symbol->file->symref[groups->symbol->symidx] 619225b3c049e70834cf33790a28643ab058b507b35cBen Cheng != NULL); 619325b3c049e70834cf33790a28643ab058b507b35cBen Cheng si = groups->symbol->file->symref[groups->symbol->symidx]->outsymidx; 619425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (si != 0); 619525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 619625b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info = ld_state.dblindirect[si]; 619725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 619825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (scn, shdr); 619925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 620025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scngroup *oldp = groups; 620125b3c049e70834cf33790a28643ab058b507b35cBen Cheng groups = groups->next; 620225b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (oldp); 620325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 620425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 620525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 620625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type != relocatable_file_type) 620725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 620825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Every executable needs a program header. The number of entries 620925b3c049e70834cf33790a28643ab058b507b35cBen Cheng varies. One exists for each segment. Each SHT_NOTE section gets 621025b3c049e70834cf33790a28643ab058b507b35cBen Cheng one, too. For dynamically linked executables we have to create 621125b3c049e70834cf33790a28643ab058b507b35cBen Cheng one for the program header, the interpreter, and the dynamic 621225b3c049e70834cf33790a28643ab058b507b35cBen Cheng section. First count the number of segments. 621325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 621425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XXX Determine whether the segment is non-empty. */ 621525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nphdr = 0; 621625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 621725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We always add a PT_GNU_stack entry. */ 621825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nphdr; 621925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 622025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct output_segment *segment = ld_state.output_segments; 622125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (segment != NULL) 622225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 622325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nphdr; 622425b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment = segment->next; 622525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 622625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 622725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the number of SHT_NOTE sections. We counted them earlier. */ 622825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nphdr += ld_state.nnotesections; 622925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 623025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we create a DSO or the file is linked against DSOs we have 623125b3c049e70834cf33790a28643ab058b507b35cBen Cheng at least one more entry: DYNAMIC. If an interpreter is 623225b3c049e70834cf33790a28643ab058b507b35cBen Cheng specified we add PHDR and INTERP, too. */ 623325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dynamically_linked_p ()) 623425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 623525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nphdr; 623625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 623725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.interp != NULL || ld_state.file_type != dso_file_type) 623825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nphdr += 2; 623925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 624025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 624125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If we need a TLS segment we need an entry for that. */ 624225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_tls) 624325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nphdr; 624425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 624525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the program header structure. */ 624625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Phdr_vardef (phdr); 624725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (xelf_newphdr (ld_state.outelf, nphdr) == 0) 624825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot create program header: %s"), 624925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 625025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 625125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 625225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the section sizes and offsets. We have to do this 625325b3c049e70834cf33790a28643ab058b507b35cBen Cheng to be able to determine the memory layout (which normally 625425b3c049e70834cf33790a28643ab058b507b35cBen Cheng differs from the file layout). */ 625525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_update (ld_state.outelf, ELF_C_NULL) == -1) 625625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("while determining file layout: %s"), 625725b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 625825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 625925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 626025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now determine the memory addresses of all the sections and 626125b3c049e70834cf33790a28643ab058b507b35cBen Cheng segments. */ 626225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word nsec = 0; 626325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_getscn (ld_state.outelf, 626425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[nsec]->scnidx); 626525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 626625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 626725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 626825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The address we start with is the offset of the first (not 626925b3c049e70834cf33790a28643ab058b507b35cBen Cheng zeroth) section. */ 627025b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Addr addr = shdr->sh_offset; 627125b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Addr tls_offset = 0; 627225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Addr tls_start = ~((XElf_Addr) 0); 627325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Addr tls_end = 0; 627425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off tls_filesize = 0; 627525b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Addr tls_align = 0; 627625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 627725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The index of the first loadable segment. */ 627825b3c049e70834cf33790a28643ab058b507b35cBen Cheng nphdr = 0; 627925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dynamically_linked_p ()) 628025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 628125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nphdr; 628225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.interp != NULL 628325b3c049e70834cf33790a28643ab058b507b35cBen Cheng || ld_state.file_type != dso_file_type) 628425b3c049e70834cf33790a28643ab058b507b35cBen Cheng nphdr += 2; 628525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 628625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 628725b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment = ld_state.output_segments; 628825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (segment != NULL) 628925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 629025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct output_rule *orule; 629125b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool first_section = true; 629225b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off nobits_size = 0; 629325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off memsize = 0; 629425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 629525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The minimum alignment is a page size. */ 629625b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment->align = ld_state.pagesize; 629725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 629825b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (orule = segment->output_rules; orule != NULL; 629925b3c049e70834cf33790a28643ab058b507b35cBen Cheng orule = orule->next) 630025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (orule->tag == output_section) 630125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 630225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* See whether this output rule corresponds to the next 630325b3c049e70834cf33790a28643ab058b507b35cBen Cheng section. Yes, this is a pointer comparison. */ 630425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.allsections[nsec]->name 630525b3c049e70834cf33790a28643ab058b507b35cBen Cheng != orule->val.section.name) 630625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No, ignore this output rule. */ 630725b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 630825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 630925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We assign addresses only in segments which are actually 631025b3c049e70834cf33790a28643ab058b507b35cBen Cheng loaded. */ 631125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (segment->mode != 0) 631225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 631325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Adjust the offset of the input sections. */ 631425b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *isect; 631525b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *first; 631625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 631725b3c049e70834cf33790a28643ab058b507b35cBen Cheng isect = first = ld_state.allsections[nsec]->last; 631825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (isect != NULL) 631925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 632025b3c049e70834cf33790a28643ab058b507b35cBen Cheng isect->offset += addr; 632125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((isect = isect->next) != first); 632225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 632325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set the address of current section. */ 632425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addr = addr; 632525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 632625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Write the result back. */ 632725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (scn, shdr); 632825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 632925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the address. */ 633025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[nsec]->addr = addr; 633125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 633225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Handle TLS sections. */ 633325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr->sh_flags & SHF_TLS)) 633425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 633525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (tls_start > addr) 633625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 633725b3c049e70834cf33790a28643ab058b507b35cBen Cheng tls_start = addr; 633825b3c049e70834cf33790a28643ab058b507b35cBen Cheng tls_offset = shdr->sh_offset; 633925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 634025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (tls_end < addr + shdr->sh_size) 634125b3c049e70834cf33790a28643ab058b507b35cBen Cheng tls_end = addr + shdr->sh_size; 634225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type != SHT_NOBITS) 634325b3c049e70834cf33790a28643ab058b507b35cBen Cheng tls_filesize += shdr->sh_size; 634425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_addralign > tls_align) 634525b3c049e70834cf33790a28643ab058b507b35cBen Cheng tls_align = shdr->sh_addralign; 634625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 634725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 634825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 634925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (first_section) 635025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 635125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The first segment starts at offset zero. */ 635225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (segment == ld_state.output_segments) 635325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 635425b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment->offset = 0; 635525b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment->addr = addr - shdr->sh_offset; 635625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 635725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 635825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 635925b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment->offset = shdr->sh_offset; 636025b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment->addr = addr; 636125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 636225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 636325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the maximum alignment requirement. */ 636425b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment->align = MAX (segment->align, shdr->sh_addralign); 636525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 636625b3c049e70834cf33790a28643ab058b507b35cBen Cheng first_section = false; 636725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 636825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 636925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* NOBITS TLS sections are not laid out in address space 637025b3c049e70834cf33790a28643ab058b507b35cBen Cheng along with the other sections. */ 637125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type != SHT_NOBITS 637225b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (shdr->sh_flags & SHF_TLS) == 0) 637325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 637425b3c049e70834cf33790a28643ab058b507b35cBen Cheng memsize = (shdr->sh_offset - segment->offset 637525b3c049e70834cf33790a28643ab058b507b35cBen Cheng + shdr->sh_size); 637625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (nobits_size != 0 && shdr->sh_type != SHT_NOTE) 637725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 637825b3c049e70834cf33790a28643ab058b507b35cBen Chenginternal error: non-nobits section follows nobits section")); 637925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type == SHT_NOBITS) 638025b3c049e70834cf33790a28643ab058b507b35cBen Cheng nobits_size += shdr->sh_size; 638125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 638225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 638325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the new address which is computed using 638425b3c049e70834cf33790a28643ab058b507b35cBen Cheng the difference of the offsets on the sections. Note 638525b3c049e70834cf33790a28643ab058b507b35cBen Cheng that this assumes that the sections following each 638625b3c049e70834cf33790a28643ab058b507b35cBen Cheng other in the section header table are also 638725b3c049e70834cf33790a28643ab058b507b35cBen Cheng consecutive in the file. This is true here because 638825b3c049e70834cf33790a28643ab058b507b35cBen Cheng libelf constructs files this way. */ 638925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Off oldoff = shdr->sh_offset; 639025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 639125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (++nsec >= ld_state.nallsections) 639225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 639325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 639425b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = elf_getscn (ld_state.outelf, 639525b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.allsections[nsec]->scnidx); 639625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 639725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 639825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 639925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is the new address resulting from the offsets 640025b3c049e70834cf33790a28643ab058b507b35cBen Cheng in the file. */ 640125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (oldoff <= shdr->sh_offset); 640225b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr += shdr->sh_offset - oldoff; 640325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 640425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 640525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 640625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (orule->tag == output_assignment); 640725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 640825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (orule->val.assignment->variable, ".") == 0) 640925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is a change of the address. */ 641025b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = eval_expression (orule->val.assignment->expression, 641125b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr); 641225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (orule->val.assignment->sym != NULL) 641325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 641425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This symbol is used. Update the symbol table 641525b3c049e70834cf33790a28643ab058b507b35cBen Cheng entry. */ 641625b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 641725b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t idx; 641825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 641925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note that we do not have to use 642025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsymshndx since we only update the 642125b3c049e70834cf33790a28643ab058b507b35cBen Cheng symbol address, not the section 642225b3c049e70834cf33790a28643ab058b507b35cBen Cheng information. */ 642325b3c049e70834cf33790a28643ab058b507b35cBen Cheng idx = dblindirect[orule->val.assignment->sym->outsymidx]; 642425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, idx, sym); 642525b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value = addr; 642625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (symdata, idx, sym); 642725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 642825b3c049e70834cf33790a28643ab058b507b35cBen Cheng idx = orule->val.assignment->sym->outdynsymidx; 642925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (idx != 0) 643025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 643125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (dynsymdata != NULL); 643225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (dynsymdata, idx, sym); 643325b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value = addr; 643425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (dynsymdata, idx, sym); 643525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 643625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 643725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 643825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 643925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the segment parameter for loadable segments. */ 644025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (segment->mode != 0) 644125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 644225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getphdr_ptr (ld_state.outelf, nphdr, phdr); 644325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 644425b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_type = PT_LOAD; 644525b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_offset = segment->offset; 644625b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_vaddr = segment->addr; 644725b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_paddr = phdr->p_vaddr; 644825b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_filesz = memsize - nobits_size; 644925b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_memsz = memsize; 645025b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags = segment->mode; 645125b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_align = segment->align; 645225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 645325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_phdr (ld_state.outelf, nphdr, phdr); 645425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nphdr; 645525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 645625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 645725b3c049e70834cf33790a28643ab058b507b35cBen Cheng segment = segment->next; 645825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 645925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 646025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the other program header entries. */ 646125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getehdr (ld_state.outelf, ehdr); 646225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ehdr != NULL); 646325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 646425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the TLS information. */ 646525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_tls) 646625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 646725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getphdr_ptr (ld_state.outelf, nphdr, phdr); 646825b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_type = PT_TLS; 646925b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_offset = tls_offset; 647025b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_vaddr = tls_start; 647125b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_paddr = tls_start; 647225b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_filesz = tls_filesize; 647325b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_memsz = tls_end - tls_start; 647425b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags = PF_R; 647525b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_align = tls_align; 647625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.tls_tcb = tls_end; 647725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.tls_start = tls_start; 647825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 647925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_phdr (ld_state.outelf, nphdr, phdr); 648025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nphdr; 648125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 648225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 648325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the stack information. */ 648425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getphdr_ptr (ld_state.outelf, nphdr, phdr); 648525b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_type = PT_GNU_STACK; 648625b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_offset = 0; 648725b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_vaddr = 0; 648825b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_paddr = 0; 648925b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_filesz = 0; 649025b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_memsz = 0; 649125b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags = (PF_R | PF_W 649225b3c049e70834cf33790a28643ab058b507b35cBen Cheng | (ld_state.execstack == execstack_true ? PF_X : 0)); 649325b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_align = xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1); 649425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 649525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_phdr (ld_state.outelf, nphdr, phdr); 649625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++nphdr; 649725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 649825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 649925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Adjust the addresses in the address fields of the symbol 650025b3c049e70834cf33790a28643ab058b507b35cBen Cheng records according to the load addresses of the sections. */ 650125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_symtab) 650225b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 1; cnt < nsym; ++cnt) 650325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 650425b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 650525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf32_Word shndx; 650625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 650725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsymshndx (symdata, xndxdata, cnt, sym, shndx); 650825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 650925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 651025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_shndx != SHN_XINDEX) 651125b3c049e70834cf33790a28643ab058b507b35cBen Cheng shndx = sym->st_shndx; 651225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 651325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((shndx > SHN_UNDEF && shndx < SHN_LORESERVE) 651425b3c049e70834cf33790a28643ab058b507b35cBen Cheng || shndx > SHN_HIRESERVE) 651525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 651625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note we subtract 1 from the section index since ALLSECTIONS 651725b3c049e70834cf33790a28643ab058b507b35cBen Cheng does not store the dummy section with offset zero. */ 651825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value += ld_state.allsections[shndx - 1]->addr; 651925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 652025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't have to use 'xelf_update_symshndx' since the 652125b3c049e70834cf33790a28643ab058b507b35cBen Cheng section number doesn't change. */ 652225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (symdata, cnt, sym); 652325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 652425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 652525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 652625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_dynsym) 652725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (cnt = 1; cnt < nsym_dyn; ++cnt) 652825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 652925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 653025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 653125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (dynsymdata, cnt, sym); 653225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 653325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 653425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_shndx > SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) 653525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 653625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note we subtract 1 from the section index since ALLSECTIONS 653725b3c049e70834cf33790a28643ab058b507b35cBen Cheng does not store the dummy section with offset zero. */ 653825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym->st_value += ld_state.allsections[sym->st_shndx - 1]->addr; 653925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 654025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't have to use 'xelf_update_symshndx' since the 654125b3c049e70834cf33790a28643ab058b507b35cBen Cheng section number doesn't change. */ 654225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_sym (dynsymdata, cnt, sym); 654325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 654425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 654525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 654625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now is a good time to determine the values of all the symbols 654725b3c049e70834cf33790a28643ab058b507b35cBen Cheng we encountered. */ 654825b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX This loop is very inefficient. The hash tab iterator also 654925b3c049e70834cf33790a28643ab058b507b35cBen Cheng // returns all symbols in DSOs. 655025b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol *se; 655125b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *p = NULL; 655225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((se = ld_symbol_tab_iterate (&ld_state.symbol_tab, &p)) != NULL) 655325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! se->in_dso) 655425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 655525b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 655625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 655725b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = 0; 655825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 655925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (se->outdynsymidx != 0) 656025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 656125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (dynsymdata, se->outdynsymidx, sym); 656225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 656325b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = sym->st_value; 656425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 656525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (se->outsymidx != 0) 656625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 656725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (dblindirect[se->outsymidx] != 0); 656825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, dblindirect[se->outsymidx], sym); 656925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 657025b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = sym->st_value; 657125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 657225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 657325b3c049e70834cf33790a28643ab058b507b35cBen Cheng abort (); 657425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 657525b3c049e70834cf33790a28643ab058b507b35cBen Cheng se->merge.value = addr; 657625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 657725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 657825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Complete the header of the .rel.dyn/.rela.dyn section. Point 657925b3c049e70834cf33790a28643ab058b507b35cBen Cheng to the symbol table. The sh_info field is left zero since 658025b3c049e70834cf33790a28643ab058b507b35cBen Cheng there is no specific section the contained relocations are 658125b3c049e70834cf33790a28643ab058b507b35cBen Cheng for. */ 658225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.reldynscnidx != 0) 658325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 658425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.dynsymscnidx != 0); 658525b3c049e70834cf33790a28643ab058b507b35cBen Cheng scn = elf_getscn (ld_state.outelf, ld_state.reldynscnidx); 658625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 658725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 658825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 658925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.dynsymscnidx; 659025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 659125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (scn, shdr); 659225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 659325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 659425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fill in the dynamic segment/section. */ 659525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dynamically_linked_p ()) 659625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 659725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *outscn; 659825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 659925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int idx = 0; 660025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.interp != NULL || ld_state.file_type != dso_file_type) 660125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 660225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.interpscnidx != 0); 660325b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, 660425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.interpscnidx), shdr); 660525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 660625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 660725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getphdr_ptr (ld_state.outelf, idx, phdr); 660825b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_type = PT_PHDR; 660925b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_offset = ehdr->e_phoff; 661025b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_vaddr = ld_state.output_segments->addr + phdr->p_offset; 661125b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_paddr = phdr->p_vaddr; 661225b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_filesz = ehdr->e_phnum * ehdr->e_phentsize; 661325b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_memsz = phdr->p_filesz; 661425b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags = 0; /* No need to set PF_R or so. */ 661525b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_align = xelf_fsize (ld_state.outelf, ELF_T_ADDR, 1); 661625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 661725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_phdr (ld_state.outelf, idx, phdr); 661825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++idx; 661925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 662025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The interpreter string. */ 662125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getphdr_ptr (ld_state.outelf, idx, phdr); 662225b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_type = PT_INTERP; 662325b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_offset = shdr->sh_offset; 662425b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_vaddr = shdr->sh_addr; 662525b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_paddr = phdr->p_vaddr; 662625b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_filesz = shdr->sh_size; 662725b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_memsz = phdr->p_filesz; 662825b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags = 0; /* No need to set PF_R or so. */ 662925b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_align = 1; /* It's a string. */ 663025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 663125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_phdr (ld_state.outelf, idx, phdr); 663225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++idx; 663325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 663425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 663525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The pointer to the dynamic section. We this we need to 663625b3c049e70834cf33790a28643ab058b507b35cBen Cheng get the information for the dynamic section first. */ 663725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.dynamicscnidx); 663825b3c049e70834cf33790a28643ab058b507b35cBen Cheng outscn = elf_getscn (ld_state.outelf, ld_state.dynamicscnidx); 663925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (outscn, shdr); 664025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 664125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 664225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getphdr_ptr (ld_state.outelf, idx, phdr); 664325b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_type = PT_DYNAMIC; 664425b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_offset = shdr->sh_offset; 664525b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_vaddr = shdr->sh_addr; 664625b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_paddr = phdr->p_vaddr; 664725b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_filesz = shdr->sh_size; 664825b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_memsz = phdr->p_filesz; 664925b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_flags = 0; /* No need to set PF_R or so. */ 665025b3c049e70834cf33790a28643ab058b507b35cBen Cheng phdr->p_align = shdr->sh_addralign; 665125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 665225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_phdr (ld_state.outelf, idx, phdr); 665325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 665425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fill in the reference to the .dynstr section. */ 665525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.dynstrscnidx != 0); 665625b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.dynstrscnidx; 665725b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (outscn, shdr); 665825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 665925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And fill the remaining entries. */ 666025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *dyndata = elf_getdata (outscn, NULL); 666125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (dyndata != NULL); 666225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 666325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the DT_NEEDED entries. */ 666425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.ndsofiles > 0) 666525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 666625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct usedfiles *runp = ld_state.dsofiles->next; 666725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 666825b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 666925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->used || !runp->as_needed) 667025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 667125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the position-dependent flag if necessary. */ 667225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (runp->lazyload) 667325b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 667425b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_POSFLAG_1, DF_P1_LAZYLOAD); 667525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 667625b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 667725b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_NEEDED, 667825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_strtaboffset (runp->sonameent)); 667925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 668025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((runp = runp->next) != ld_state.dsofiles->next); 668125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 668225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 668325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We can finish the DT_RUNPATH/DT_RPATH entries now. */ 668425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.rxxpath_strent != NULL) 668525b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 668625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.rxxpath_tag, 668725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ebl_strtaboffset (ld_state.rxxpath_strent)); 668825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 668925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Reference to initialization and finalization functions. */ 669025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX This code depends on symbol table being relocated. 669125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.init_symbol != NULL) 669225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 669325b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 669425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 669525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_symtab) 669625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, 669725b3c049e70834cf33790a28643ab058b507b35cBen Cheng dblindirect[ld_state.init_symbol->outsymidx], 669825b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym); 669925b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 670025b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (dynsymdata, ld_state.init_symbol->outdynsymidx, 670125b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym); 670225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 670325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 670425b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 670525b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_INIT, sym->st_value); 670625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 670725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.fini_symbol != NULL) 670825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 670925b3c049e70834cf33790a28643ab058b507b35cBen Cheng XElf_Sym_vardef (sym); 671025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 671125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.need_symtab) 671225b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (symdata, 671325b3c049e70834cf33790a28643ab058b507b35cBen Cheng dblindirect[ld_state.fini_symbol->outsymidx], 671425b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym); 671525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 671625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getsym (dynsymdata, ld_state.fini_symbol->outdynsymidx, 671725b3c049e70834cf33790a28643ab058b507b35cBen Cheng sym); 671825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sym != NULL); 671925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 672025b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 672125b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_FINI, sym->st_value); 672225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 672325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Support init,fini,preinit arrays 672425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 672525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The hash table which comes with dynamic symbol table. */ 672625b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, ld_state.hashscnidx), 672725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr); 672825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 672925b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, DT_HASH, 673025b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addr); 673125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 673225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Reference to the symbol table section. */ 673325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.dynsymscnidx != 0); 673425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, ld_state.dynsymscnidx), 673525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr); 673625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 673725b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, DT_SYMTAB, 673825b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addr); 673925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 674025b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, DT_SYMENT, 674125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_fsize (ld_state.outelf, ELF_T_SYM, 1)); 674225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 674325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And the string table which comes with it. */ 674425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, ld_state.dynstrscnidx), 674525b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr); 674625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 674725b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, DT_STRTAB, 674825b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_addr); 674925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 675025b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, DT_STRSZ, 675125b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_size); 675225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 675325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the entries related to the .plt. */ 675425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.nplt > 0) 675525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 675625b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Make this work if there is no PLT 675725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, 675825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.gotpltscnidx), shdr); 675925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 676025b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 676125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX This should probably be machine 676225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // dependent. 676325b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_PLTGOT, shdr->sh_addr); 676425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 676525b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, 676625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.pltrelscnidx), shdr); 676725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 676825b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 676925b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_PLTRELSZ, shdr->sh_size); 677025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 677125b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 677225b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_JMPREL, shdr->sh_addr); 677325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 677425b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 677525b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_PLTREL, REL_TYPE (statep)); 677625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 677725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 677825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.relsize_total > 0) 677925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 678025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int rel = REL_TYPE (statep); 678125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, 678225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.reldynscnidx), shdr); 678325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 678425b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 678525b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel, shdr->sh_addr); 678625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 678725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Trick ahead. Use arithmetic to get the right tag. 678825b3c049e70834cf33790a28643ab058b507b35cBen Cheng We check the validity of this assumption in the asserts. */ 678925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (DT_RELASZ - DT_RELA == 1); 679025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (DT_RELSZ - DT_REL == 1); 679125b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 679225b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel + 1, shdr->sh_size); 679325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 679425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Similar for the entry size tag. */ 679525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (DT_RELAENT - DT_RELA == 2); 679625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (DT_RELENT - DT_REL == 2); 679725b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 679825b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel + 2, 679925b3c049e70834cf33790a28643ab058b507b35cBen Cheng rel == DT_REL 680025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? xelf_fsize (ld_state.outelf, ELF_T_REL, 1) 680125b3c049e70834cf33790a28643ab058b507b35cBen Cheng : xelf_fsize (ld_state.outelf, ELF_T_RELA, 680225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1)); 680325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 680425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 680525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.verneedscnidx != 0) 680625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 680725b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, 680825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.verneedscnidx), shdr); 680925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 681025b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 681125b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_VERNEED, shdr->sh_addr); 681225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 681325b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 681425b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_VERNEEDNUM, ld_state.nverdeffile); 681525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 681625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 681725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.versymscnidx != 0) 681825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 681925b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (elf_getscn (ld_state.outelf, 682025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.versymscnidx), shdr); 682125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 682225b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 682325b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_VERSYM, shdr->sh_addr); 682425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 682525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 682625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We always create the DT_DEBUG entry. */ 682725b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, DT_DEBUG, 0); 682825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.ndynamic_filled < ld_state.ndynamic); 682925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 683025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the flag words if necessary. */ 683125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.dt_flags != 0) 683225b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, DT_FLAGS, 683325b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.dt_flags); 683425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 683525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create entry for the DT_FLAGS_1 flag. */ 683625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.dt_flags_1 != 0) 683725b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 683825b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_FLAGS_1, ld_state.dt_flags_1); 683925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 684025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create entry for the DT_FEATURE_1 flag. */ 684125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.dt_feature_1 != 0) 684225b3c049e70834cf33790a28643ab058b507b35cBen Cheng new_dynamic_entry (dyndata, ld_state.ndynamic_filled++, 684325b3c049e70834cf33790a28643ab058b507b35cBen Cheng DT_FEATURE_1, ld_state.dt_feature_1); 684425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 684525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.ndynamic_filled <= ld_state.ndynamic); 684625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 684725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 684825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 684925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 685025b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX The following code isn't nice. We use two different 685125b3c049e70834cf33790a28643ab058b507b35cBen Cheng // mechanisms to handle relocations, one for relocatable files, one 685225b3c049e70834cf33790a28643ab058b507b35cBen Cheng // for executables and DSOs. Maybe this is the best method but also 685325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // maybe it can be somewhat unified. 685425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 685525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now that we created the symbol table we can add the reference to 685625b3c049e70834cf33790a28643ab058b507b35cBen Cheng it in the sh_link field of the section headers of the relocation 685725b3c049e70834cf33790a28643ab058b507b35cBen Cheng sections. */ 685825b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (rellist != NULL) 685925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 686025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.file_type == relocatable_file_type); 686125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *outscn; 686225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 686325b3c049e70834cf33790a28643ab058b507b35cBen Cheng outscn = elf_getscn (ld_state.outelf, rellist->scnidx); 686425b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (outscn, shdr); 686525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This must not fail since we did it before. */ 686625b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (shdr != NULL); 686725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 686825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Remember the symbol table which belongs to the relocation section. */ 686925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = ld_state.symscnidx; 687025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 687125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* And the reference to the section which is relocated by this 687225b3c049e70834cf33790a28643ab058b507b35cBen Cheng relocation section. We use the info from the first input 687325b3c049e70834cf33790a28643ab058b507b35cBen Cheng section but all records should have the same information. */ 687425b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_info = 687525b3c049e70834cf33790a28643ab058b507b35cBen Cheng rellist->scninfo->fileinfo->scninfo[SCNINFO_SHDR (rellist->scninfo->shdr).sh_info].outscnndx; 687625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 687725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 687825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Perform the actual relocations. We only have to adjust 687925b3c049e70834cf33790a28643ab058b507b35cBen Cheng offsets and symbol indices. */ 688025b3c049e70834cf33790a28643ab058b507b35cBen Cheng RELOCATE_SECTION (statep, outscn, rellist->scninfo, dblindirect); 688125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 688225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Store the changes. */ 688325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (outscn, shdr); 688425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 688525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Up to the next relocation section. */ 688625b3c049e70834cf33790a28643ab058b507b35cBen Cheng rellist = rellist->next; 688725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 688825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 688925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.rellist != NULL) 689025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 689125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ld_state.file_type != relocatable_file_type); 689225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Create the relocations for the output file. */ 689325b3c049e70834cf33790a28643ab058b507b35cBen Cheng CREATE_RELOCATIONS (statep, dblindirect); 689425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 689525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 689625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 689725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We need the ELF header once more. */ 689825b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getehdr (ld_state.outelf, ehdr); 689925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (ehdr != NULL); 690025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 690125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set the section header string table index. */ 690225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (shstrtab_ndx < SHN_HIRESERVE) 690325b3c049e70834cf33790a28643ab058b507b35cBen Cheng && likely (shstrtab_ndx != SHN_XINDEX)) 690425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_shstrndx = shstrtab_ndx; 690525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 690625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 690725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We have to put the section index in the sh_link field of the 690825b3c049e70834cf33790a28643ab058b507b35cBen Cheng zeroth section header. */ 690925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_getscn (ld_state.outelf, 0); 691025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 691125b3c049e70834cf33790a28643ab058b507b35cBen Cheng xelf_getshdr (scn, shdr); 691225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr == NULL)) 691325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 691425b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot get header of 0th section: %s"), 691525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 691625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 691725b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_link = shstrtab_ndx; 691825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 691925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) xelf_update_shdr (scn, shdr); 692025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 692125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_shstrndx = SHN_XINDEX; 692225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 692325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 692425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.file_type != relocatable_file_type) 692525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* DSOs and executables have to define the entry point symbol. */ 692625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ehdr->e_entry = find_entry_point (); 692725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 692825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (xelf_update_ehdr (ld_state.outelf, ehdr) == 0)) 692925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 693025b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("cannot update ELF header: %s"), 693125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 693225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 693325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 693425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Free the data which we don't need anymore. */ 693525b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (ld_state.dblindirect); 693625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 693725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 693825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Finalize the .plt section and what else belongs to it. */ 693925b3c049e70834cf33790a28643ab058b507b35cBen Cheng FINALIZE_PLT (statep, nsym, nsym_local, ndxtosym); 694025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 694125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 694225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Finally, if we have to compute the build ID. */ 694325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ld_state.build_id != NULL) 694425b3c049e70834cf33790a28643ab058b507b35cBen Cheng compute_build_id (); 694525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 694625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 694725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We don't need the map from the symbol table index to the symbol 694825b3c049e70834cf33790a28643ab058b507b35cBen Cheng structure anymore. */ 694925b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (ndxtosym); 695025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 695125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 695225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 695325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 695425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 695525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* This is a function which must be specified in all backends. */ 695625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 695725b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_relocate_section (struct ld_state *statep, Elf_Scn *outscn, 695825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct scninfo *firstp, 695925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Elf32_Word *dblindirect) 696025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 696125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 696225b3c049e70834cf33790a28643ab058b507b35cBen Chenglinker backend didn't specify function to relocate section")); 696325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* NOTREACHED */ 696425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 696525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 696625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 696725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Finalize the output file. */ 696825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 696925b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_finalize (struct ld_state *statep) 697025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 697125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Write out the ELF file data. */ 697225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_update (ld_state.outelf, ELF_C_WRITE) == -1) 697325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("while writing output file: %s"), 697425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 697525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 697625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Free the resources. */ 697725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_end (ld_state.outelf) != 0) 697825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("while finishing output file: %s"), 697925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_errmsg (-1)); 698025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 698125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the file status of the temporary file. */ 698225b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct stat temp_st; 698325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fstat (ld_state.outfd, &temp_st) != 0) 698425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("cannot stat output file")); 698525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 698625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now it's time to rename the file. Remove an old existing file 698725b3c049e70834cf33790a28643ab058b507b35cBen Cheng first. */ 698825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (rename (ld_state.tempfname, ld_state.outfname) != 0) 698925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Something went wrong. */ 699025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("cannot rename output file")); 699125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 699225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make sure the output file is really the one we created. */ 699325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct stat new_st; 699425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (stat (ld_state.outfname, &new_st) != 0 699525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || new_st.st_ino != temp_st.st_ino 699625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || new_st.st_dev != temp_st.st_dev) 699725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 699825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Wow, somebody overwrote the output file, probably some intruder. */ 699925b3c049e70834cf33790a28643ab058b507b35cBen Cheng unlink (ld_state.outfname); 700025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("\ 700125b3c049e70834cf33790a28643ab058b507b35cBen ChengWARNING: temporary output file overwritten before linking finished")); 700225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 700325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 700425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Close the file descriptor. */ 700525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) close (ld_state.outfd); 700625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 700725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Signal the cleanup handler that the file is correctly created. */ 700825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ld_state.tempfname = NULL; 700925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 701025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 701125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 701225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 701325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 701425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool 701525b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_special_section_number_p (struct ld_state *statep, size_t number) 701625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 701725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There are no special section numbers in the gABI. */ 701825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 701925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 702025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 702125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 702225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool 702325b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_section_type_p (struct ld_state *statep, GElf_Word type) 702425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 702525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (type < SHT_NUM 702625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Enable the following two when implemented. */ 702725b3c049e70834cf33790a28643ab058b507b35cBen Cheng // || type == SHT_GNU_LIBLIST 702825b3c049e70834cf33790a28643ab058b507b35cBen Cheng // || type == SHT_CHECKSUM 702925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* XXX Eventually include SHT_SUNW_move, SHT_SUNW_COMDAT, and 703025b3c049e70834cf33790a28643ab058b507b35cBen Cheng SHT_SUNW_syminfo. */ 703125b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (type >= SHT_GNU_verdef && type <= SHT_GNU_versym)) 703225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return true; 703325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 703425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 703525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 703625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 703725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 703825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic XElf_Xword 703925b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_dynamic_section_flags (struct ld_state *statep) 704025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 704125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* By default the .dynamic section is writable (and is of course 704225b3c049e70834cf33790a28643ab058b507b35cBen Cheng loaded). Few architecture differ from this. */ 704325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return SHF_ALLOC | SHF_WRITE; 704425b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 704525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 704625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 704725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 704825b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_initialize_plt (struct ld_state *statep, Elf_Scn *scn) 704925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 705025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot be implemented generally. There should have been a 705125b3c049e70834cf33790a28643ab058b507b35cBen Cheng machine dependent implementation and we should never have arrived 705225b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 705325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("no machine specific '%s' implementation"), 705425b3c049e70834cf33790a28643ab058b507b35cBen Cheng "initialize_plt"); 705525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 705625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 705725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 705825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 705925b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_initialize_pltrel (struct ld_state *statep, Elf_Scn *scn) 706025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 706125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot be implemented generally. There should have been a 706225b3c049e70834cf33790a28643ab058b507b35cBen Cheng machine dependent implementation and we should never have arrived 706325b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 706425b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("no machine specific '%s' implementation"), 706525b3c049e70834cf33790a28643ab058b507b35cBen Cheng "initialize_pltrel"); 706625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 706725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 706825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 706925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 707025b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_initialize_got (struct ld_state *statep, Elf_Scn *scn) 707125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 707225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot be implemented generally. There should have been a 707325b3c049e70834cf33790a28643ab058b507b35cBen Cheng machine dependent implementation and we should never have arrived 707425b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 707525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("no machine specific '%s' implementation"), 707625b3c049e70834cf33790a28643ab058b507b35cBen Cheng "initialize_got"); 707725b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 707825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 707925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 708025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 708125b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_initialize_gotplt (struct ld_state *statep, Elf_Scn *scn) 708225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 708325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot be implemented generally. There should have been a 708425b3c049e70834cf33790a28643ab058b507b35cBen Cheng machine dependent implementation and we should never have arrived 708525b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 708625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("no machine specific '%s' implementation"), 708725b3c049e70834cf33790a28643ab058b507b35cBen Cheng "initialize_gotplt"); 708825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 708925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 709025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 709125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 709225b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_finalize_plt (struct ld_state *statep, size_t nsym, size_t nsym_dyn, 709325b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct symbol **ndxtosymp) 709425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 709525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* By default we assume that nothing has to be done. */ 709625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 709725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 709825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 709925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 710025b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_rel_type (struct ld_state *statep) 710125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 710225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot be implemented generally. There should have been a 710325b3c049e70834cf33790a28643ab058b507b35cBen Cheng machine dependent implementation and we should never have arrived 710425b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 710525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("no machine specific '%s' implementation"), 710625b3c049e70834cf33790a28643ab058b507b35cBen Cheng "rel_type"); 710725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Just to keep the compiler calm. */ 710825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 710925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 711025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 711125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 711225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 711325b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_count_relocations (struct ld_state *statep, struct scninfo *scninfo) 711425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 711525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot be implemented generally. There should have been a 711625b3c049e70834cf33790a28643ab058b507b35cBen Cheng machine dependent implementation and we should never have arrived 711725b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 711825b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("no machine specific '%s' implementation"), 711925b3c049e70834cf33790a28643ab058b507b35cBen Cheng "count_relocations"); 712025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 712125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 712225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 712325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 712425b3c049e70834cf33790a28643ab058b507b35cBen Chengld_generic_create_relocations (struct ld_state *statep, 712525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const Elf32_Word *dblindirect) 712625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 712725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This cannot be implemented generally. There should have been a 712825b3c049e70834cf33790a28643ab058b507b35cBen Cheng machine dependent implementation and we should never have arrived 712925b3c049e70834cf33790a28643ab058b507b35cBen Cheng here. */ 713025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("no machine specific '%s' implementation"), 713125b3c049e70834cf33790a28643ab058b507b35cBen Cheng "create_relocations"); 713225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 7133