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