diff --git a/binutils-execstack-error.patch b/binutils-execstack-error.patch new file mode 100644 index 0000000..d7c7778 --- /dev/null +++ b/binutils-execstack-error.patch @@ -0,0 +1,63876 @@ +diff -rupN binutils.orig/bfd/elf.c binutils-2.41/bfd/elf.c +--- binutils.orig/bfd/elf.c 2023-10-19 12:11:46.526939794 +0100 ++++ binutils-2.41/bfd/elf.c 2023-10-19 12:11:56.514949624 +0100 +@@ -7013,6 +7013,9 @@ assign_file_positions_except_relocs (bfd + { + if (link_info != NULL && ! link_info->no_warn_rwx_segments) + { ++ bool warned_tls = false; ++ bool warned_rwx = false; ++ + /* Memory resident segments with non-zero size and RWX + permissions are a security risk, so we generate a warning + here if we are creating any. */ +@@ -7025,16 +7028,47 @@ assign_file_positions_except_relocs (bfd + if (phdr->p_memsz == 0) + continue; + +- if (phdr->p_type == PT_TLS && (phdr->p_flags & PF_X)) +- _bfd_error_handler (_("warning: %pB has a TLS segment" +- " with execute permission"), +- abfd); +- else if (phdr->p_type == PT_LOAD ++ if (! warned_tls ++ && phdr->p_type == PT_TLS ++ && (phdr->p_flags & PF_X)) ++ { ++ if (link_info->warn_is_error_for_rwx_segments) ++ { ++ _bfd_error_handler (_("\ ++error: %pB has a TLS segment with execute permission"), ++ abfd); ++ return false; ++ } ++ ++ _bfd_error_handler (_("\ ++warning: %pB has a TLS segment with execute permission"), ++ abfd); ++ if (warned_rwx) ++ break; ++ ++ warned_tls = true; ++ } ++ else if (! warned_rwx ++ && phdr->p_type == PT_LOAD + && ((phdr->p_flags & (PF_R | PF_W | PF_X)) + == (PF_R | PF_W | PF_X))) +- _bfd_error_handler (_("warning: %pB has a LOAD segment" +- " with RWX permissions"), +- abfd); ++ { ++ if (link_info->warn_is_error_for_rwx_segments) ++ { ++ _bfd_error_handler (_("\ ++error: %pB has a LOAD segment with RWX permissions"), ++ abfd); ++ return false; ++ } ++ ++ _bfd_error_handler (_("\ ++warning: %pB has a LOAD segment with RWX permissions"), ++ abfd); ++ if (warned_tls) ++ break; ++ ++ warned_rwx = true; ++ } + } + } + +diff -rupN binutils.orig/bfd/elf.c.orig binutils-2.41/bfd/elf.c.orig +--- binutils.orig/bfd/elf.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/bfd/elf.c.orig 2023-10-19 12:11:39.505932880 +0100 +@@ -0,0 +1,14219 @@ ++/* ELF executable support for BFD. ++ ++ Copyright (C) 1993-2023 Free Software Foundation, Inc. ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++ ++/* ++SECTION ++ ELF backends ++ ++ BFD support for ELF formats is being worked on. ++ Currently, the best supported back ends are for sparc and i386 ++ (running svr4 or Solaris 2). ++ ++ Documentation of the internals of the support code still needs ++ to be written. The code is changing quickly enough that we ++ haven't bothered yet. */ ++ ++/* For sparc64-cross-sparc32. */ ++#define _SYSCALL32 ++#include "sysdep.h" ++#include ++#include "bfd.h" ++#include "bfdlink.h" ++#include "libbfd.h" ++#define ARCH_SIZE 0 ++#include "elf-bfd.h" ++#include "libiberty.h" ++#include "safe-ctype.h" ++#include "elf-linux-core.h" ++ ++#ifdef CORE_HEADER ++#include CORE_HEADER ++#endif ++ ++static int elf_sort_sections (const void *, const void *); ++static bool assign_file_positions_except_relocs (bfd *, struct bfd_link_info *); ++static bool swap_out_syms (bfd *, struct elf_strtab_hash **, int, ++ struct bfd_link_info *); ++static bool elf_parse_notes (bfd *abfd, char *buf, size_t size, ++ file_ptr offset, size_t align); ++ ++/* Swap version information in and out. The version information is ++ currently size independent. If that ever changes, this code will ++ need to move into elfcode.h. */ ++ ++/* Swap in a Verdef structure. */ ++ ++void ++_bfd_elf_swap_verdef_in (bfd *abfd, ++ const Elf_External_Verdef *src, ++ Elf_Internal_Verdef *dst) ++{ ++ dst->vd_version = H_GET_16 (abfd, src->vd_version); ++ dst->vd_flags = H_GET_16 (abfd, src->vd_flags); ++ dst->vd_ndx = H_GET_16 (abfd, src->vd_ndx); ++ dst->vd_cnt = H_GET_16 (abfd, src->vd_cnt); ++ dst->vd_hash = H_GET_32 (abfd, src->vd_hash); ++ dst->vd_aux = H_GET_32 (abfd, src->vd_aux); ++ dst->vd_next = H_GET_32 (abfd, src->vd_next); ++} ++ ++/* Swap out a Verdef structure. */ ++ ++void ++_bfd_elf_swap_verdef_out (bfd *abfd, ++ const Elf_Internal_Verdef *src, ++ Elf_External_Verdef *dst) ++{ ++ H_PUT_16 (abfd, src->vd_version, dst->vd_version); ++ H_PUT_16 (abfd, src->vd_flags, dst->vd_flags); ++ H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx); ++ H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt); ++ H_PUT_32 (abfd, src->vd_hash, dst->vd_hash); ++ H_PUT_32 (abfd, src->vd_aux, dst->vd_aux); ++ H_PUT_32 (abfd, src->vd_next, dst->vd_next); ++} ++ ++/* Swap in a Verdaux structure. */ ++ ++void ++_bfd_elf_swap_verdaux_in (bfd *abfd, ++ const Elf_External_Verdaux *src, ++ Elf_Internal_Verdaux *dst) ++{ ++ dst->vda_name = H_GET_32 (abfd, src->vda_name); ++ dst->vda_next = H_GET_32 (abfd, src->vda_next); ++} ++ ++/* Swap out a Verdaux structure. */ ++ ++void ++_bfd_elf_swap_verdaux_out (bfd *abfd, ++ const Elf_Internal_Verdaux *src, ++ Elf_External_Verdaux *dst) ++{ ++ H_PUT_32 (abfd, src->vda_name, dst->vda_name); ++ H_PUT_32 (abfd, src->vda_next, dst->vda_next); ++} ++ ++/* Swap in a Verneed structure. */ ++ ++void ++_bfd_elf_swap_verneed_in (bfd *abfd, ++ const Elf_External_Verneed *src, ++ Elf_Internal_Verneed *dst) ++{ ++ dst->vn_version = H_GET_16 (abfd, src->vn_version); ++ dst->vn_cnt = H_GET_16 (abfd, src->vn_cnt); ++ dst->vn_file = H_GET_32 (abfd, src->vn_file); ++ dst->vn_aux = H_GET_32 (abfd, src->vn_aux); ++ dst->vn_next = H_GET_32 (abfd, src->vn_next); ++} ++ ++/* Swap out a Verneed structure. */ ++ ++void ++_bfd_elf_swap_verneed_out (bfd *abfd, ++ const Elf_Internal_Verneed *src, ++ Elf_External_Verneed *dst) ++{ ++ H_PUT_16 (abfd, src->vn_version, dst->vn_version); ++ H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt); ++ H_PUT_32 (abfd, src->vn_file, dst->vn_file); ++ H_PUT_32 (abfd, src->vn_aux, dst->vn_aux); ++ H_PUT_32 (abfd, src->vn_next, dst->vn_next); ++} ++ ++/* Swap in a Vernaux structure. */ ++ ++void ++_bfd_elf_swap_vernaux_in (bfd *abfd, ++ const Elf_External_Vernaux *src, ++ Elf_Internal_Vernaux *dst) ++{ ++ dst->vna_hash = H_GET_32 (abfd, src->vna_hash); ++ dst->vna_flags = H_GET_16 (abfd, src->vna_flags); ++ dst->vna_other = H_GET_16 (abfd, src->vna_other); ++ dst->vna_name = H_GET_32 (abfd, src->vna_name); ++ dst->vna_next = H_GET_32 (abfd, src->vna_next); ++} ++ ++/* Swap out a Vernaux structure. */ ++ ++void ++_bfd_elf_swap_vernaux_out (bfd *abfd, ++ const Elf_Internal_Vernaux *src, ++ Elf_External_Vernaux *dst) ++{ ++ H_PUT_32 (abfd, src->vna_hash, dst->vna_hash); ++ H_PUT_16 (abfd, src->vna_flags, dst->vna_flags); ++ H_PUT_16 (abfd, src->vna_other, dst->vna_other); ++ H_PUT_32 (abfd, src->vna_name, dst->vna_name); ++ H_PUT_32 (abfd, src->vna_next, dst->vna_next); ++} ++ ++/* Swap in a Versym structure. */ ++ ++void ++_bfd_elf_swap_versym_in (bfd *abfd, ++ const Elf_External_Versym *src, ++ Elf_Internal_Versym *dst) ++{ ++ dst->vs_vers = H_GET_16 (abfd, src->vs_vers); ++} ++ ++/* Swap out a Versym structure. */ ++ ++void ++_bfd_elf_swap_versym_out (bfd *abfd, ++ const Elf_Internal_Versym *src, ++ Elf_External_Versym *dst) ++{ ++ H_PUT_16 (abfd, src->vs_vers, dst->vs_vers); ++} ++ ++/* Standard ELF hash function. Do not change this function; you will ++ cause invalid hash tables to be generated. */ ++ ++unsigned long ++bfd_elf_hash (const char *namearg) ++{ ++ uint32_t h = 0; ++ ++ for (const unsigned char *name = (const unsigned char *) namearg; ++ *name; name++) ++ { ++ h = (h << 4) + *name; ++ h ^= (h >> 24) & 0xf0; ++ } ++ return h & 0x0fffffff; ++} ++ ++/* DT_GNU_HASH hash function. Do not change this function; you will ++ cause invalid hash tables to be generated. */ ++ ++unsigned long ++bfd_elf_gnu_hash (const char *namearg) ++{ ++ uint32_t h = 5381; ++ ++ for (const unsigned char *name = (const unsigned char *) namearg; ++ *name; name++) ++ h = (h << 5) + h + *name; ++ return h; ++} ++ ++/* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with ++ the object_id field of an elf_obj_tdata field set to OBJECT_ID. */ ++bool ++bfd_elf_allocate_object (bfd *abfd, ++ size_t object_size, ++ enum elf_target_id object_id) ++{ ++ BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata)); ++ abfd->tdata.any = bfd_zalloc (abfd, object_size); ++ if (abfd->tdata.any == NULL) ++ return false; ++ ++ elf_object_id (abfd) = object_id; ++ if (abfd->direction != read_direction) ++ { ++ struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o); ++ if (o == NULL) ++ return false; ++ elf_tdata (abfd)->o = o; ++ elf_program_header_size (abfd) = (bfd_size_type) -1; ++ } ++ return true; ++} ++ ++ ++bool ++bfd_elf_make_object (bfd *abfd) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata), ++ bed->target_id); ++} ++ ++bool ++bfd_elf_mkcorefile (bfd *abfd) ++{ ++ /* I think this can be done just like an object file. */ ++ if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd)) ++ return false; ++ elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core)); ++ return elf_tdata (abfd)->core != NULL; ++} ++ ++char * ++bfd_elf_get_str_section (bfd *abfd, unsigned int shindex) ++{ ++ Elf_Internal_Shdr **i_shdrp; ++ bfd_byte *shstrtab = NULL; ++ file_ptr offset; ++ bfd_size_type shstrtabsize; ++ ++ i_shdrp = elf_elfsections (abfd); ++ if (i_shdrp == 0 ++ || shindex >= elf_numsections (abfd) ++ || i_shdrp[shindex] == 0) ++ return NULL; ++ ++ shstrtab = i_shdrp[shindex]->contents; ++ if (shstrtab == NULL) ++ { ++ /* No cached one, attempt to read, and cache what we read. */ ++ offset = i_shdrp[shindex]->sh_offset; ++ shstrtabsize = i_shdrp[shindex]->sh_size; ++ ++ /* Allocate and clear an extra byte at the end, to prevent crashes ++ in case the string table is not terminated. */ ++ if (shstrtabsize + 1 <= 1 ++ || bfd_seek (abfd, offset, SEEK_SET) != 0 ++ || (shstrtab = _bfd_alloc_and_read (abfd, shstrtabsize + 1, ++ shstrtabsize)) == NULL) ++ { ++ /* Once we've failed to read it, make sure we don't keep ++ trying. Otherwise, we'll keep allocating space for ++ the string table over and over. */ ++ i_shdrp[shindex]->sh_size = 0; ++ } ++ else ++ shstrtab[shstrtabsize] = '\0'; ++ i_shdrp[shindex]->contents = shstrtab; ++ } ++ return (char *) shstrtab; ++} ++ ++char * ++bfd_elf_string_from_elf_section (bfd *abfd, ++ unsigned int shindex, ++ unsigned int strindex) ++{ ++ Elf_Internal_Shdr *hdr; ++ ++ if (strindex == 0) ++ return ""; ++ ++ if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd)) ++ return NULL; ++ ++ hdr = elf_elfsections (abfd)[shindex]; ++ ++ if (hdr->contents == NULL) ++ { ++ if (hdr->sh_type != SHT_STRTAB && hdr->sh_type < SHT_LOOS) ++ { ++ /* PR 17512: file: f057ec89. */ ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: attempt to load strings from" ++ " a non-string section (number %d)"), ++ abfd, shindex); ++ return NULL; ++ } ++ ++ if (bfd_elf_get_str_section (abfd, shindex) == NULL) ++ return NULL; ++ } ++ else ++ { ++ /* PR 24273: The string section's contents may have already ++ been loaded elsewhere, eg because a corrupt file has the ++ string section index in the ELF header pointing at a group ++ section. So be paranoid, and test that the last byte of ++ the section is zero. */ ++ if (hdr->sh_size == 0 || hdr->contents[hdr->sh_size - 1] != 0) ++ return NULL; ++ } ++ ++ if (strindex >= hdr->sh_size) ++ { ++ unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx; ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: invalid string offset %u >= %" PRIu64 " for section `%s'"), ++ abfd, strindex, (uint64_t) hdr->sh_size, ++ (shindex == shstrndx && strindex == hdr->sh_name ++ ? ".shstrtab" ++ : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name))); ++ return NULL; ++ } ++ ++ return ((char *) hdr->contents) + strindex; ++} ++ ++/* Read and convert symbols to internal format. ++ SYMCOUNT specifies the number of symbols to read, starting from ++ symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF ++ are non-NULL, they are used to store the internal symbols, external ++ symbols, and symbol section index extensions, respectively. ++ Returns a pointer to the internal symbol buffer (malloced if necessary) ++ or NULL if there were no symbols or some kind of problem. */ ++ ++Elf_Internal_Sym * ++bfd_elf_get_elf_syms (bfd *ibfd, ++ Elf_Internal_Shdr *symtab_hdr, ++ size_t symcount, ++ size_t symoffset, ++ Elf_Internal_Sym *intsym_buf, ++ void *extsym_buf, ++ Elf_External_Sym_Shndx *extshndx_buf) ++{ ++ Elf_Internal_Shdr *shndx_hdr; ++ void *alloc_ext; ++ const bfd_byte *esym; ++ Elf_External_Sym_Shndx *alloc_extshndx; ++ Elf_External_Sym_Shndx *shndx; ++ Elf_Internal_Sym *alloc_intsym; ++ Elf_Internal_Sym *isym; ++ Elf_Internal_Sym *isymend; ++ const struct elf_backend_data *bed; ++ size_t extsym_size; ++ size_t amt; ++ file_ptr pos; ++ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) ++ abort (); ++ ++ if (symcount == 0) ++ return intsym_buf; ++ ++ if (elf_use_dt_symtab_p (ibfd)) ++ { ++ /* Use dynamic symbol table. */ ++ if (elf_tdata (ibfd)->dt_symtab_count != symcount + symoffset) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ return NULL; ++ } ++ return elf_tdata (ibfd)->dt_symtab + symoffset; ++ } ++ ++ /* Normal syms might have section extension entries. */ ++ shndx_hdr = NULL; ++ if (elf_symtab_shndx_list (ibfd) != NULL) ++ { ++ elf_section_list * entry; ++ Elf_Internal_Shdr **sections = elf_elfsections (ibfd); ++ ++ /* Find an index section that is linked to this symtab section. */ ++ for (entry = elf_symtab_shndx_list (ibfd); entry != NULL; entry = entry->next) ++ { ++ /* PR 20063. */ ++ if (entry->hdr.sh_link >= elf_numsections (ibfd)) ++ continue; ++ ++ if (sections[entry->hdr.sh_link] == symtab_hdr) ++ { ++ shndx_hdr = & entry->hdr; ++ break; ++ }; ++ } ++ ++ if (shndx_hdr == NULL) ++ { ++ if (symtab_hdr == &elf_symtab_hdr (ibfd)) ++ /* Not really accurate, but this was how the old code used ++ to work. */ ++ shndx_hdr = &elf_symtab_shndx_list (ibfd)->hdr; ++ /* Otherwise we do nothing. The assumption is that ++ the index table will not be needed. */ ++ } ++ } ++ ++ /* Read the symbols. */ ++ alloc_ext = NULL; ++ alloc_extshndx = NULL; ++ alloc_intsym = NULL; ++ bed = get_elf_backend_data (ibfd); ++ extsym_size = bed->s->sizeof_sym; ++ if (_bfd_mul_overflow (symcount, extsym_size, &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ intsym_buf = NULL; ++ goto out; ++ } ++ pos = symtab_hdr->sh_offset + symoffset * extsym_size; ++ if (extsym_buf == NULL) ++ { ++ alloc_ext = bfd_malloc (amt); ++ extsym_buf = alloc_ext; ++ } ++ if (extsym_buf == NULL ++ || bfd_seek (ibfd, pos, SEEK_SET) != 0 ++ || bfd_bread (extsym_buf, amt, ibfd) != amt) ++ { ++ intsym_buf = NULL; ++ goto out; ++ } ++ ++ if (shndx_hdr == NULL || shndx_hdr->sh_size == 0) ++ extshndx_buf = NULL; ++ else ++ { ++ if (_bfd_mul_overflow (symcount, sizeof (Elf_External_Sym_Shndx), &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ intsym_buf = NULL; ++ goto out; ++ } ++ pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx); ++ if (extshndx_buf == NULL) ++ { ++ alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt); ++ extshndx_buf = alloc_extshndx; ++ } ++ if (extshndx_buf == NULL ++ || bfd_seek (ibfd, pos, SEEK_SET) != 0 ++ || bfd_bread (extshndx_buf, amt, ibfd) != amt) ++ { ++ intsym_buf = NULL; ++ goto out; ++ } ++ } ++ ++ if (intsym_buf == NULL) ++ { ++ if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto out; ++ } ++ alloc_intsym = (Elf_Internal_Sym *) bfd_malloc (amt); ++ intsym_buf = alloc_intsym; ++ if (intsym_buf == NULL) ++ goto out; ++ } ++ ++ /* Convert the symbols to internal form. */ ++ isymend = intsym_buf + symcount; ++ for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf, ++ shndx = extshndx_buf; ++ isym < isymend; ++ esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL) ++ if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym)) ++ { ++ symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size; ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB symbol number %lu references" ++ " nonexistent SHT_SYMTAB_SHNDX section"), ++ ibfd, (unsigned long) symoffset); ++ free (alloc_intsym); ++ intsym_buf = NULL; ++ goto out; ++ } ++ ++ out: ++ free (alloc_ext); ++ free (alloc_extshndx); ++ ++ return intsym_buf; ++} ++ ++/* Look up a symbol name. */ ++const char * ++bfd_elf_sym_name (bfd *abfd, ++ Elf_Internal_Shdr *symtab_hdr, ++ Elf_Internal_Sym *isym, ++ asection *sym_sec) ++{ ++ const char *name; ++ unsigned int iname = isym->st_name; ++ unsigned int shindex = symtab_hdr->sh_link; ++ ++ if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION ++ /* Check for a bogus st_shndx to avoid crashing. */ ++ && isym->st_shndx < elf_numsections (abfd)) ++ { ++ iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name; ++ shindex = elf_elfheader (abfd)->e_shstrndx; ++ } ++ ++ name = bfd_elf_string_from_elf_section (abfd, shindex, iname); ++ if (name == NULL) ++ name = "(null)"; ++ else if (sym_sec && *name == '\0') ++ name = bfd_section_name (sym_sec); ++ ++ return name; ++} ++ ++/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP ++ sections. The first element is the flags, the rest are section ++ pointers. */ ++ ++typedef union elf_internal_group { ++ Elf_Internal_Shdr *shdr; ++ unsigned int flags; ++} Elf_Internal_Group; ++ ++/* Return the name of the group signature symbol. Why isn't the ++ signature just a string? */ ++ ++static const char * ++group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr) ++{ ++ Elf_Internal_Shdr *hdr; ++ unsigned char esym[sizeof (Elf64_External_Sym)]; ++ Elf_External_Sym_Shndx eshndx; ++ Elf_Internal_Sym isym; ++ ++ /* First we need to ensure the symbol table is available. Make sure ++ that it is a symbol table section. */ ++ if (ghdr->sh_link >= elf_numsections (abfd)) ++ return NULL; ++ hdr = elf_elfsections (abfd) [ghdr->sh_link]; ++ if (hdr->sh_type != SHT_SYMTAB ++ || ! bfd_section_from_shdr (abfd, ghdr->sh_link)) ++ return NULL; ++ ++ /* Go read the symbol. */ ++ hdr = &elf_tdata (abfd)->symtab_hdr; ++ if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info, ++ &isym, esym, &eshndx) == NULL) ++ return NULL; ++ ++ return bfd_elf_sym_name (abfd, hdr, &isym, NULL); ++} ++ ++/* Set next_in_group list pointer, and group name for NEWSECT. */ ++ ++static bool ++setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) ++{ ++ unsigned int num_group = elf_tdata (abfd)->num_group; ++ ++ /* If num_group is zero, read in all SHT_GROUP sections. The count ++ is set to -1 if there are no SHT_GROUP sections. */ ++ if (num_group == 0) ++ { ++ unsigned int i, shnum; ++ ++ /* First count the number of groups. If we have a SHT_GROUP ++ section with just a flag word (ie. sh_size is 4), ignore it. */ ++ shnum = elf_numsections (abfd); ++ num_group = 0; ++ ++#define IS_VALID_GROUP_SECTION_HEADER(shdr, minsize) \ ++ ( (shdr)->sh_type == SHT_GROUP \ ++ && (shdr)->sh_size >= minsize \ ++ && (shdr)->sh_entsize == GRP_ENTRY_SIZE \ ++ && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0) ++ ++ for (i = 0; i < shnum; i++) ++ { ++ Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i]; ++ ++ if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE)) ++ num_group += 1; ++ } ++ ++ if (num_group == 0) ++ { ++ num_group = (unsigned) -1; ++ elf_tdata (abfd)->num_group = num_group; ++ elf_tdata (abfd)->group_sect_ptr = NULL; ++ } ++ else ++ { ++ /* We keep a list of elf section headers for group sections, ++ so we can find them quickly. */ ++ size_t amt; ++ ++ elf_tdata (abfd)->num_group = num_group; ++ amt = num_group * sizeof (Elf_Internal_Shdr *); ++ elf_tdata (abfd)->group_sect_ptr ++ = (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt); ++ if (elf_tdata (abfd)->group_sect_ptr == NULL) ++ return false; ++ num_group = 0; ++ ++ for (i = 0; i < shnum; i++) ++ { ++ Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i]; ++ ++ if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE)) ++ { ++ unsigned char *src; ++ Elf_Internal_Group *dest; ++ ++ /* Make sure the group section has a BFD section ++ attached to it. */ ++ if (!bfd_section_from_shdr (abfd, i)) ++ return false; ++ ++ /* Add to list of sections. */ ++ elf_tdata (abfd)->group_sect_ptr[num_group] = shdr; ++ num_group += 1; ++ ++ /* Read the raw contents. */ ++ BFD_ASSERT (sizeof (*dest) >= 4 && sizeof (*dest) % 4 == 0); ++ shdr->contents = NULL; ++ if (_bfd_mul_overflow (shdr->sh_size, ++ sizeof (*dest) / 4, &amt) ++ || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0 ++ || !(shdr->contents ++ = _bfd_alloc_and_read (abfd, amt, shdr->sh_size))) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: invalid size field in group section" ++ " header: %#" PRIx64 ""), ++ abfd, (uint64_t) shdr->sh_size); ++ bfd_set_error (bfd_error_bad_value); ++ -- num_group; ++ continue; ++ } ++ ++ /* Translate raw contents, a flag word followed by an ++ array of elf section indices all in target byte order, ++ to the flag word followed by an array of elf section ++ pointers. */ ++ src = shdr->contents + shdr->sh_size; ++ dest = (Elf_Internal_Group *) (shdr->contents + amt); ++ ++ while (1) ++ { ++ unsigned int idx; ++ ++ src -= 4; ++ --dest; ++ idx = H_GET_32 (abfd, src); ++ if (src == shdr->contents) ++ { ++ dest->shdr = NULL; ++ dest->flags = idx; ++ if (shdr->bfd_section != NULL && (idx & GRP_COMDAT)) ++ shdr->bfd_section->flags ++ |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; ++ break; ++ } ++ if (idx < shnum) ++ { ++ dest->shdr = elf_elfsections (abfd)[idx]; ++ /* PR binutils/23199: All sections in a ++ section group should be marked with ++ SHF_GROUP. But some tools generate ++ broken objects without SHF_GROUP. Fix ++ them up here. */ ++ dest->shdr->sh_flags |= SHF_GROUP; ++ } ++ if (idx >= shnum ++ || dest->shdr->sh_type == SHT_GROUP) ++ { ++ _bfd_error_handler ++ (_("%pB: invalid entry in SHT_GROUP section [%u]"), ++ abfd, i); ++ dest->shdr = NULL; ++ } ++ } ++ } ++ } ++ ++ /* PR 17510: Corrupt binaries might contain invalid groups. */ ++ if (num_group != (unsigned) elf_tdata (abfd)->num_group) ++ { ++ elf_tdata (abfd)->num_group = num_group; ++ ++ /* If all groups are invalid then fail. */ ++ if (num_group == 0) ++ { ++ elf_tdata (abfd)->group_sect_ptr = NULL; ++ elf_tdata (abfd)->num_group = num_group = -1; ++ _bfd_error_handler ++ (_("%pB: no valid group sections found"), abfd); ++ bfd_set_error (bfd_error_bad_value); ++ } ++ } ++ } ++ } ++ ++ if (num_group != (unsigned) -1) ++ { ++ unsigned int search_offset = elf_tdata (abfd)->group_search_offset; ++ unsigned int j; ++ ++ for (j = 0; j < num_group; j++) ++ { ++ /* Begin search from previous found group. */ ++ unsigned i = (j + search_offset) % num_group; ++ ++ Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i]; ++ Elf_Internal_Group *idx; ++ bfd_size_type n_elt; ++ ++ if (shdr == NULL) ++ continue; ++ ++ idx = (Elf_Internal_Group *) shdr->contents; ++ if (idx == NULL || shdr->sh_size < 4) ++ { ++ /* See PR 21957 for a reproducer. */ ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: group section '%pA' has no contents"), ++ abfd, shdr->bfd_section); ++ elf_tdata (abfd)->group_sect_ptr[i] = NULL; ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ n_elt = shdr->sh_size / 4; ++ ++ /* Look through this group's sections to see if current ++ section is a member. */ ++ while (--n_elt != 0) ++ if ((++idx)->shdr == hdr) ++ { ++ asection *s = NULL; ++ ++ /* We are a member of this group. Go looking through ++ other members to see if any others are linked via ++ next_in_group. */ ++ idx = (Elf_Internal_Group *) shdr->contents; ++ n_elt = shdr->sh_size / 4; ++ while (--n_elt != 0) ++ if ((++idx)->shdr != NULL ++ && (s = idx->shdr->bfd_section) != NULL ++ && elf_next_in_group (s) != NULL) ++ break; ++ if (n_elt != 0) ++ { ++ /* Snarf the group name from other member, and ++ insert current section in circular list. */ ++ elf_group_name (newsect) = elf_group_name (s); ++ elf_next_in_group (newsect) = elf_next_in_group (s); ++ elf_next_in_group (s) = newsect; ++ } ++ else ++ { ++ const char *gname; ++ ++ gname = group_signature (abfd, shdr); ++ if (gname == NULL) ++ return false; ++ elf_group_name (newsect) = gname; ++ ++ /* Start a circular list with one element. */ ++ elf_next_in_group (newsect) = newsect; ++ } ++ ++ /* If the group section has been created, point to the ++ new member. */ ++ if (shdr->bfd_section != NULL) ++ elf_next_in_group (shdr->bfd_section) = newsect; ++ ++ elf_tdata (abfd)->group_search_offset = i; ++ j = num_group - 1; ++ break; ++ } ++ } ++ } ++ ++ if (elf_group_name (newsect) == NULL ++ /* OS specific sections might be in a group (eg ARM's ARM_EXIDX section) ++ but they will not have been added to the group because they do not ++ have contents that the ELF code in the BFD library knows how to ++ process. This is OK though - we rely upon the target backends to ++ handle these sections for us. */ ++ && hdr->sh_type < SHT_LOOS) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: no group info for section '%pA'"), ++ abfd, newsect); ++ /* PR 29532: Return true here, even though the group info has not been ++ read. Separate debug info files can have empty group sections, but ++ we do not want this to prevent them from being loaded as otherwise ++ GDB will not be able to use them. */ ++ return true; ++ } ++ return true; ++} ++ ++bool ++_bfd_elf_setup_sections (bfd *abfd) ++{ ++ unsigned int i; ++ unsigned int num_group = elf_tdata (abfd)->num_group; ++ bool result = true; ++ asection *s; ++ ++ /* Process SHF_LINK_ORDER. */ ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr; ++ if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0) ++ { ++ unsigned int elfsec = this_hdr->sh_link; ++ /* An sh_link value of 0 is now allowed. It indicates that linked ++ to section has already been discarded, but that the current ++ section has been retained for some other reason. This linking ++ section is still a candidate for later garbage collection ++ however. */ ++ if (elfsec == 0) ++ { ++ elf_linked_to_section (s) = NULL; ++ } ++ else ++ { ++ asection *linksec = NULL; ++ ++ if (elfsec < elf_numsections (abfd)) ++ { ++ this_hdr = elf_elfsections (abfd)[elfsec]; ++ linksec = this_hdr->bfd_section; ++ } ++ ++ /* PR 1991, 2008: ++ Some strip/objcopy may leave an incorrect value in ++ sh_link. We don't want to proceed. */ ++ if (linksec == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: sh_link [%d] in section `%pA' is incorrect"), ++ s->owner, elfsec, s); ++ result = false; ++ } ++ ++ elf_linked_to_section (s) = linksec; ++ } ++ } ++ else if (this_hdr->sh_type == SHT_GROUP ++ && elf_next_in_group (s) == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: SHT_GROUP section [index %d] has no SHF_GROUP sections"), ++ abfd, elf_section_data (s)->this_idx); ++ result = false; ++ } ++ } ++ ++ /* Process section groups. */ ++ if (num_group == (unsigned) -1) ++ return result; ++ ++ for (i = 0; i < num_group; i++) ++ { ++ Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i]; ++ Elf_Internal_Group *idx; ++ unsigned int n_elt; ++ ++ /* PR binutils/18758: Beware of corrupt binaries with invalid ++ group data. */ ++ if (shdr == NULL || shdr->bfd_section == NULL || shdr->contents == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: section group entry number %u is corrupt"), ++ abfd, i); ++ result = false; ++ continue; ++ } ++ ++ idx = (Elf_Internal_Group *) shdr->contents; ++ n_elt = shdr->sh_size / 4; ++ ++ while (--n_elt != 0) ++ { ++ ++ idx; ++ ++ if (idx->shdr == NULL) ++ continue; ++ else if (idx->shdr->bfd_section) ++ elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section; ++ else if (idx->shdr->sh_type != SHT_RELA ++ && idx->shdr->sh_type != SHT_REL ++ && idx->shdr->sh_type < SHT_LOOS) ++ { ++ /* There are some unknown sections in the group. */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unknown type [%#x] section `%s' in group [%pA]"), ++ abfd, ++ idx->shdr->sh_type, ++ bfd_elf_string_from_elf_section (abfd, ++ (elf_elfheader (abfd) ++ ->e_shstrndx), ++ idx->shdr->sh_name), ++ shdr->bfd_section); ++ result = false; ++ } ++ } ++ } ++ ++ return result; ++} ++ ++bool ++bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec) ++{ ++ return elf_next_in_group (sec) != NULL; ++} ++ ++const char * ++bfd_elf_group_name (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec) ++{ ++ if (elf_sec_group (sec) != NULL) ++ return elf_group_name (sec); ++ return NULL; ++} ++ ++/* This a copy of lto_section defined in GCC (lto-streamer.h). */ ++ ++struct lto_section ++{ ++ int16_t major_version; ++ int16_t minor_version; ++ unsigned char slim_object; ++ ++ /* Flags is a private field that is not defined publicly. */ ++ uint16_t flags; ++}; ++ ++/* Make a BFD section from an ELF section. We store a pointer to the ++ BFD section in the bfd_section field of the header. */ ++ ++bool ++_bfd_elf_make_section_from_shdr (bfd *abfd, ++ Elf_Internal_Shdr *hdr, ++ const char *name, ++ int shindex) ++{ ++ asection *newsect; ++ flagword flags; ++ const struct elf_backend_data *bed; ++ unsigned int opb = bfd_octets_per_byte (abfd, NULL); ++ ++ if (hdr->bfd_section != NULL) ++ return true; ++ ++ newsect = bfd_make_section_anyway (abfd, name); ++ if (newsect == NULL) ++ return false; ++ ++ hdr->bfd_section = newsect; ++ elf_section_data (newsect)->this_hdr = *hdr; ++ elf_section_data (newsect)->this_idx = shindex; ++ ++ /* Always use the real type/flags. */ ++ elf_section_type (newsect) = hdr->sh_type; ++ elf_section_flags (newsect) = hdr->sh_flags; ++ ++ newsect->filepos = hdr->sh_offset; ++ ++ flags = SEC_NO_FLAGS; ++ if (hdr->sh_type != SHT_NOBITS) ++ flags |= SEC_HAS_CONTENTS; ++ if (hdr->sh_type == SHT_GROUP) ++ flags |= SEC_GROUP; ++ if ((hdr->sh_flags & SHF_ALLOC) != 0) ++ { ++ flags |= SEC_ALLOC; ++ if (hdr->sh_type != SHT_NOBITS) ++ flags |= SEC_LOAD; ++ } ++ if ((hdr->sh_flags & SHF_WRITE) == 0) ++ flags |= SEC_READONLY; ++ if ((hdr->sh_flags & SHF_EXECINSTR) != 0) ++ flags |= SEC_CODE; ++ else if ((flags & SEC_LOAD) != 0) ++ flags |= SEC_DATA; ++ if ((hdr->sh_flags & SHF_MERGE) != 0) ++ { ++ flags |= SEC_MERGE; ++ newsect->entsize = hdr->sh_entsize; ++ } ++ if ((hdr->sh_flags & SHF_STRINGS) != 0) ++ flags |= SEC_STRINGS; ++ if (hdr->sh_flags & SHF_GROUP) ++ if (!setup_group (abfd, hdr, newsect)) ++ return false; ++ if ((hdr->sh_flags & SHF_TLS) != 0) ++ flags |= SEC_THREAD_LOCAL; ++ if ((hdr->sh_flags & SHF_EXCLUDE) != 0) ++ flags |= SEC_EXCLUDE; ++ ++ switch (elf_elfheader (abfd)->e_ident[EI_OSABI]) ++ { ++ /* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE, ++ but binutils as of 2019-07-23 did not set the EI_OSABI header ++ byte. */ ++ case ELFOSABI_GNU: ++ case ELFOSABI_FREEBSD: ++ if ((hdr->sh_flags & SHF_GNU_RETAIN) != 0) ++ elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_retain; ++ /* Fall through */ ++ case ELFOSABI_NONE: ++ if ((hdr->sh_flags & SHF_GNU_MBIND) != 0) ++ elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_mbind; ++ break; ++ } ++ ++ if ((flags & SEC_ALLOC) == 0) ++ { ++ /* The debugging sections appear to be recognized only by name, ++ not any sort of flag. Their SEC_ALLOC bits are cleared. */ ++ if (name [0] == '.') ++ { ++ if (startswith (name, ".debug") ++ || startswith (name, ".gnu.debuglto_.debug_") ++ || startswith (name, ".gnu.linkonce.wi.") ++ || startswith (name, ".zdebug")) ++ flags |= SEC_DEBUGGING | SEC_ELF_OCTETS; ++ else if (startswith (name, GNU_BUILD_ATTRS_SECTION_NAME) ++ || startswith (name, ".note.gnu")) ++ { ++ flags |= SEC_ELF_OCTETS; ++ opb = 1; ++ } ++ else if (startswith (name, ".line") ++ || startswith (name, ".stab") ++ || strcmp (name, ".gdb_index") == 0) ++ flags |= SEC_DEBUGGING; ++ } ++ } ++ ++ if (!bfd_set_section_vma (newsect, hdr->sh_addr / opb) ++ || !bfd_set_section_size (newsect, hdr->sh_size) ++ || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign ++ & -hdr->sh_addralign))) ++ return false; ++ ++ /* As a GNU extension, if the name begins with .gnu.linkonce, we ++ only link a single copy of the section. This is used to support ++ g++. g++ will emit each template expansion in its own section. ++ The symbols will be defined as weak, so that multiple definitions ++ are permitted. The GNU linker extension is to actually discard ++ all but one of the sections. */ ++ if (startswith (name, ".gnu.linkonce") ++ && elf_next_in_group (newsect) == NULL) ++ flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; ++ ++ if (!bfd_set_section_flags (newsect, flags)) ++ return false; ++ ++ bed = get_elf_backend_data (abfd); ++ if (bed->elf_backend_section_flags) ++ if (!bed->elf_backend_section_flags (hdr)) ++ return false; ++ ++ /* We do not parse the PT_NOTE segments as we are interested even in the ++ separate debug info files which may have the segments offsets corrupted. ++ PT_NOTEs from the core files are currently not parsed using BFD. */ ++ if (hdr->sh_type == SHT_NOTE && hdr->sh_size != 0) ++ { ++ bfd_byte *contents; ++ ++ if (!bfd_malloc_and_get_section (abfd, newsect, &contents)) ++ return false; ++ ++ elf_parse_notes (abfd, (char *) contents, hdr->sh_size, ++ hdr->sh_offset, hdr->sh_addralign); ++ free (contents); ++ } ++ ++ if ((newsect->flags & SEC_ALLOC) != 0) ++ { ++ Elf_Internal_Phdr *phdr; ++ unsigned int i, nload; ++ ++ /* Some ELF linkers produce binaries with all the program header ++ p_paddr fields zero. If we have such a binary with more than ++ one PT_LOAD header, then leave the section lma equal to vma ++ so that we don't create sections with overlapping lma. */ ++ phdr = elf_tdata (abfd)->phdr; ++ for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) ++ if (phdr->p_paddr != 0) ++ break; ++ else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0) ++ ++nload; ++ if (i >= elf_elfheader (abfd)->e_phnum && nload > 1) ++ return true; ++ ++ phdr = elf_tdata (abfd)->phdr; ++ for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) ++ { ++ if (((phdr->p_type == PT_LOAD ++ && (hdr->sh_flags & SHF_TLS) == 0) ++ || phdr->p_type == PT_TLS) ++ && ELF_SECTION_IN_SEGMENT (hdr, phdr)) ++ { ++ if ((newsect->flags & SEC_LOAD) == 0) ++ newsect->lma = (phdr->p_paddr ++ + hdr->sh_addr - phdr->p_vaddr) / opb; ++ else ++ /* We used to use the same adjustment for SEC_LOAD ++ sections, but that doesn't work if the segment ++ is packed with code from multiple VMAs. ++ Instead we calculate the section LMA based on ++ the segment LMA. It is assumed that the ++ segment will contain sections with contiguous ++ LMAs, even if the VMAs are not. */ ++ newsect->lma = (phdr->p_paddr ++ + hdr->sh_offset - phdr->p_offset) / opb; ++ ++ /* With contiguous segments, we can't tell from file ++ offsets whether a section with zero size should ++ be placed at the end of one segment or the ++ beginning of the next. Decide based on vaddr. */ ++ if (hdr->sh_addr >= phdr->p_vaddr ++ && (hdr->sh_addr + hdr->sh_size ++ <= phdr->p_vaddr + phdr->p_memsz)) ++ break; ++ } ++ } ++ } ++ ++ /* Compress/decompress DWARF debug sections with names: .debug_*, ++ .zdebug_*, .gnu.debuglto_.debug_, after the section flags is set. */ ++ if ((newsect->flags & SEC_DEBUGGING) != 0 ++ && (newsect->flags & SEC_HAS_CONTENTS) != 0 ++ && (newsect->flags & SEC_ELF_OCTETS) != 0) ++ { ++ enum { nothing, compress, decompress } action = nothing; ++ int compression_header_size; ++ bfd_size_type uncompressed_size; ++ unsigned int uncompressed_align_power; ++ enum compression_type ch_type = ch_none; ++ bool compressed ++ = bfd_is_section_compressed_info (abfd, newsect, ++ &compression_header_size, ++ &uncompressed_size, ++ &uncompressed_align_power, ++ &ch_type); ++ ++ /* Should we decompress? */ ++ if ((abfd->flags & BFD_DECOMPRESS) != 0 && compressed) ++ action = decompress; ++ ++ /* Should we compress? Or convert to a different compression? */ ++ else if ((abfd->flags & BFD_COMPRESS) != 0 ++ && newsect->size != 0 ++ && compression_header_size >= 0 ++ && uncompressed_size > 0) ++ { ++ if (!compressed) ++ action = compress; ++ else ++ { ++ enum compression_type new_ch_type = ch_none; ++ if ((abfd->flags & BFD_COMPRESS_GABI) != 0) ++ new_ch_type = ((abfd->flags & BFD_COMPRESS_ZSTD) != 0 ++ ? ch_compress_zstd : ch_compress_zlib); ++ if (new_ch_type != ch_type) ++ action = compress; ++ } ++ } ++ ++ if (action == compress) ++ { ++ if (!bfd_init_section_compress_status (abfd, newsect)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unable to compress section %s"), abfd, name); ++ return false; ++ } ++ } ++ else if (action == decompress) ++ { ++ if (!bfd_init_section_decompress_status (abfd, newsect)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unable to decompress section %s"), abfd, name); ++ return false; ++ } ++#ifndef HAVE_ZSTD ++ if (newsect->compress_status == DECOMPRESS_SECTION_ZSTD) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_ ("%pB: section %s is compressed with zstd, but BFD " ++ "is not built with zstd support"), ++ abfd, name); ++ newsect->compress_status = COMPRESS_SECTION_NONE; ++ return false; ++ } ++#endif ++ if (abfd->is_linker_input ++ && name[1] == 'z') ++ { ++ /* Rename section from .zdebug_* to .debug_* so that ld ++ scripts will see this section as a debug section. */ ++ char *new_name = bfd_zdebug_name_to_debug (abfd, name); ++ if (new_name == NULL) ++ return false; ++ bfd_rename_section (newsect, new_name); ++ } ++ } ++ } ++ ++ /* GCC uses .gnu.lto_.lto. as a LTO bytecode information ++ section. */ ++ if (startswith (name, ".gnu.lto_.lto.")) ++ { ++ struct lto_section lsection; ++ if (bfd_get_section_contents (abfd, newsect, &lsection, 0, ++ sizeof (struct lto_section))) ++ abfd->lto_slim_object = lsection.slim_object; ++ } ++ ++ return true; ++} ++ ++const char *const bfd_elf_section_type_names[] = ++{ ++ "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB", ++ "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE", ++ "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM", ++}; ++ ++/* ELF relocs are against symbols. If we are producing relocatable ++ output, and the reloc is against an external symbol, and nothing ++ has given us any additional addend, the resulting reloc will also ++ be against the same symbol. In such a case, we don't want to ++ change anything about the way the reloc is handled, since it will ++ all be done at final link time. Rather than put special case code ++ into bfd_perform_relocation, all the reloc types use this howto ++ function, or should call this function for relocatable output. */ ++ ++bfd_reloc_status_type ++bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, ++ arelent *reloc_entry, ++ asymbol *symbol, ++ void *data ATTRIBUTE_UNUSED, ++ asection *input_section, ++ bfd *output_bfd, ++ char **error_message ATTRIBUTE_UNUSED) ++{ ++ if (output_bfd != NULL ++ && (symbol->flags & BSF_SECTION_SYM) == 0 ++ && (! reloc_entry->howto->partial_inplace ++ || reloc_entry->addend == 0)) ++ { ++ reloc_entry->address += input_section->output_offset; ++ return bfd_reloc_ok; ++ } ++ ++ /* In some cases the relocation should be treated as output section ++ relative, as when linking ELF DWARF into PE COFF. Many ELF ++ targets lack section relative relocations and instead use ++ ordinary absolute relocations for references between DWARF ++ sections. That is arguably a bug in those targets but it happens ++ to work for the usual case of linking to non-loaded ELF debug ++ sections with VMAs forced to zero. PE COFF on the other hand ++ doesn't allow a section VMA of zero. */ ++ if (output_bfd == NULL ++ && !reloc_entry->howto->pc_relative ++ && (symbol->section->flags & SEC_DEBUGGING) != 0 ++ && (input_section->flags & SEC_DEBUGGING) != 0) ++ reloc_entry->addend -= symbol->section->output_section->vma; ++ ++ return bfd_reloc_continue; ++} ++ ++/* Returns TRUE if section A matches section B. ++ Names, addresses and links may be different, but everything else ++ should be the same. */ ++ ++static bool ++section_match (const Elf_Internal_Shdr * a, ++ const Elf_Internal_Shdr * b) ++{ ++ if (a->sh_type != b->sh_type ++ || ((a->sh_flags ^ b->sh_flags) & ~SHF_INFO_LINK) != 0 ++ || a->sh_addralign != b->sh_addralign ++ || a->sh_entsize != b->sh_entsize) ++ return false; ++ if (a->sh_type == SHT_SYMTAB ++ || a->sh_type == SHT_STRTAB) ++ return true; ++ return a->sh_size == b->sh_size; ++} ++ ++/* Find a section in OBFD that has the same characteristics ++ as IHEADER. Return the index of this section or SHN_UNDEF if ++ none can be found. Check's section HINT first, as this is likely ++ to be the correct section. */ ++ ++static unsigned int ++find_link (const bfd *obfd, const Elf_Internal_Shdr *iheader, ++ const unsigned int hint) ++{ ++ Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd); ++ unsigned int i; ++ ++ BFD_ASSERT (iheader != NULL); ++ ++ /* See PR 20922 for a reproducer of the NULL test. */ ++ if (hint < elf_numsections (obfd) ++ && oheaders[hint] != NULL ++ && section_match (oheaders[hint], iheader)) ++ return hint; ++ ++ for (i = 1; i < elf_numsections (obfd); i++) ++ { ++ Elf_Internal_Shdr * oheader = oheaders[i]; ++ ++ if (oheader == NULL) ++ continue; ++ if (section_match (oheader, iheader)) ++ /* FIXME: Do we care if there is a potential for ++ multiple matches ? */ ++ return i; ++ } ++ ++ return SHN_UNDEF; ++} ++ ++/* PR 19938: Attempt to set the ELF section header fields of an OS or ++ Processor specific section, based upon a matching input section. ++ Returns TRUE upon success, FALSE otherwise. */ ++ ++static bool ++copy_special_section_fields (const bfd *ibfd, ++ bfd *obfd, ++ const Elf_Internal_Shdr *iheader, ++ Elf_Internal_Shdr *oheader, ++ const unsigned int secnum) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (obfd); ++ const Elf_Internal_Shdr **iheaders ++ = (const Elf_Internal_Shdr **) elf_elfsections (ibfd); ++ bool changed = false; ++ unsigned int sh_link; ++ ++ if (oheader->sh_type == SHT_NOBITS) ++ { ++ /* This is a feature for objcopy --only-keep-debug: ++ When a section's type is changed to NOBITS, we preserve ++ the sh_link and sh_info fields so that they can be ++ matched up with the original. ++ ++ Note: Strictly speaking these assignments are wrong. ++ The sh_link and sh_info fields should point to the ++ relevent sections in the output BFD, which may not be in ++ the same location as they were in the input BFD. But ++ the whole point of this action is to preserve the ++ original values of the sh_link and sh_info fields, so ++ that they can be matched up with the section headers in ++ the original file. So strictly speaking we may be ++ creating an invalid ELF file, but it is only for a file ++ that just contains debug info and only for sections ++ without any contents. */ ++ if (oheader->sh_link == 0) ++ oheader->sh_link = iheader->sh_link; ++ if (oheader->sh_info == 0) ++ oheader->sh_info = iheader->sh_info; ++ return true; ++ } ++ ++ /* Allow the target a chance to decide how these fields should be set. */ ++ if (bed->elf_backend_copy_special_section_fields (ibfd, obfd, ++ iheader, oheader)) ++ return true; ++ ++ /* We have an iheader which might match oheader, and which has non-zero ++ sh_info and/or sh_link fields. Attempt to follow those links and find ++ the section in the output bfd which corresponds to the linked section ++ in the input bfd. */ ++ if (iheader->sh_link != SHN_UNDEF) ++ { ++ /* See PR 20931 for a reproducer. */ ++ if (iheader->sh_link >= elf_numsections (ibfd)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: invalid sh_link field (%d) in section number %d"), ++ ibfd, iheader->sh_link, secnum); ++ return false; ++ } ++ ++ sh_link = find_link (obfd, iheaders[iheader->sh_link], iheader->sh_link); ++ if (sh_link != SHN_UNDEF) ++ { ++ oheader->sh_link = sh_link; ++ changed = true; ++ } ++ else ++ /* FIXME: Should we install iheader->sh_link ++ if we could not find a match ? */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: failed to find link section for section %d"), obfd, secnum); ++ } ++ ++ if (iheader->sh_info) ++ { ++ /* The sh_info field can hold arbitrary information, but if the ++ SHF_LINK_INFO flag is set then it should be interpreted as a ++ section index. */ ++ if (iheader->sh_flags & SHF_INFO_LINK) ++ { ++ sh_link = find_link (obfd, iheaders[iheader->sh_info], ++ iheader->sh_info); ++ if (sh_link != SHN_UNDEF) ++ oheader->sh_flags |= SHF_INFO_LINK; ++ } ++ else ++ /* No idea what it means - just copy it. */ ++ sh_link = iheader->sh_info; ++ ++ if (sh_link != SHN_UNDEF) ++ { ++ oheader->sh_info = sh_link; ++ changed = true; ++ } ++ else ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: failed to find info section for section %d"), obfd, secnum); ++ } ++ ++ return changed; ++} ++ ++/* Copy the program header and other data from one object module to ++ another. */ ++ ++bool ++_bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) ++{ ++ const Elf_Internal_Shdr **iheaders ++ = (const Elf_Internal_Shdr **) elf_elfsections (ibfd); ++ Elf_Internal_Shdr **oheaders = elf_elfsections (obfd); ++ const struct elf_backend_data *bed; ++ unsigned int i; ++ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour ++ || bfd_get_flavour (obfd) != bfd_target_elf_flavour) ++ return true; ++ ++ if (!elf_flags_init (obfd)) ++ { ++ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; ++ elf_flags_init (obfd) = true; ++ } ++ ++ elf_gp (obfd) = elf_gp (ibfd); ++ ++ /* Also copy the EI_OSABI field. */ ++ elf_elfheader (obfd)->e_ident[EI_OSABI] = ++ elf_elfheader (ibfd)->e_ident[EI_OSABI]; ++ ++ /* If set, copy the EI_ABIVERSION field. */ ++ if (elf_elfheader (ibfd)->e_ident[EI_ABIVERSION]) ++ elf_elfheader (obfd)->e_ident[EI_ABIVERSION] ++ = elf_elfheader (ibfd)->e_ident[EI_ABIVERSION]; ++ ++ /* Copy object attributes. */ ++ _bfd_elf_copy_obj_attributes (ibfd, obfd); ++ ++ if (iheaders == NULL || oheaders == NULL) ++ return true; ++ ++ bed = get_elf_backend_data (obfd); ++ ++ /* Possibly copy other fields in the section header. */ ++ for (i = 1; i < elf_numsections (obfd); i++) ++ { ++ unsigned int j; ++ Elf_Internal_Shdr * oheader = oheaders[i]; ++ ++ /* Ignore ordinary sections. SHT_NOBITS sections are considered however ++ because of a special case need for generating separate debug info ++ files. See below for more details. */ ++ if (oheader == NULL ++ || (oheader->sh_type != SHT_NOBITS ++ && oheader->sh_type < SHT_LOOS)) ++ continue; ++ ++ /* Ignore empty sections, and sections whose ++ fields have already been initialised. */ ++ if (oheader->sh_size == 0 ++ || (oheader->sh_info != 0 && oheader->sh_link != 0)) ++ continue; ++ ++ /* Scan for the matching section in the input bfd. ++ First we try for a direct mapping between the input and ++ output sections. */ ++ for (j = 1; j < elf_numsections (ibfd); j++) ++ { ++ const Elf_Internal_Shdr * iheader = iheaders[j]; ++ ++ if (iheader == NULL) ++ continue; ++ ++ if (oheader->bfd_section != NULL ++ && iheader->bfd_section != NULL ++ && iheader->bfd_section->output_section != NULL ++ && iheader->bfd_section->output_section == oheader->bfd_section) ++ { ++ /* We have found a connection from the input section to ++ the output section. Attempt to copy the header fields. ++ If this fails then do not try any further sections - ++ there should only be a one-to-one mapping between ++ input and output. */ ++ if (!copy_special_section_fields (ibfd, obfd, ++ iheader, oheader, i)) ++ j = elf_numsections (ibfd); ++ break; ++ } ++ } ++ ++ if (j < elf_numsections (ibfd)) ++ continue; ++ ++ /* That failed. So try to deduce the corresponding input section. ++ Unfortunately we cannot compare names as the output string table ++ is empty, so instead we check size, address and type. */ ++ for (j = 1; j < elf_numsections (ibfd); j++) ++ { ++ const Elf_Internal_Shdr * iheader = iheaders[j]; ++ ++ if (iheader == NULL) ++ continue; ++ ++ /* Try matching fields in the input section's header. ++ Since --only-keep-debug turns all non-debug sections into ++ SHT_NOBITS sections, the output SHT_NOBITS type matches any ++ input type. */ ++ if ((oheader->sh_type == SHT_NOBITS ++ || iheader->sh_type == oheader->sh_type) ++ && (iheader->sh_flags & ~ SHF_INFO_LINK) ++ == (oheader->sh_flags & ~ SHF_INFO_LINK) ++ && iheader->sh_addralign == oheader->sh_addralign ++ && iheader->sh_entsize == oheader->sh_entsize ++ && iheader->sh_size == oheader->sh_size ++ && iheader->sh_addr == oheader->sh_addr ++ && (iheader->sh_info != oheader->sh_info ++ || iheader->sh_link != oheader->sh_link)) ++ { ++ if (copy_special_section_fields (ibfd, obfd, iheader, oheader, i)) ++ break; ++ } ++ } ++ ++ if (j == elf_numsections (ibfd) && oheader->sh_type >= SHT_LOOS) ++ { ++ /* Final attempt. Call the backend copy function ++ with a NULL input section. */ ++ (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd, ++ NULL, oheader); ++ } ++ } ++ ++ return true; ++} ++ ++static const char * ++get_segment_type (unsigned int p_type) ++{ ++ const char *pt; ++ switch (p_type) ++ { ++ case PT_NULL: pt = "NULL"; break; ++ case PT_LOAD: pt = "LOAD"; break; ++ case PT_DYNAMIC: pt = "DYNAMIC"; break; ++ case PT_INTERP: pt = "INTERP"; break; ++ case PT_NOTE: pt = "NOTE"; break; ++ case PT_SHLIB: pt = "SHLIB"; break; ++ case PT_PHDR: pt = "PHDR"; break; ++ case PT_TLS: pt = "TLS"; break; ++ case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break; ++ case PT_GNU_STACK: pt = "STACK"; break; ++ case PT_GNU_RELRO: pt = "RELRO"; break; ++ case PT_GNU_SFRAME: pt = "SFRAME"; break; ++ default: pt = NULL; break; ++ } ++ return pt; ++} ++ ++/* Print out the program headers. */ ++ ++bool ++_bfd_elf_print_private_bfd_data (bfd *abfd, void *farg) ++{ ++ FILE *f = (FILE *) farg; ++ Elf_Internal_Phdr *p; ++ asection *s; ++ bfd_byte *dynbuf = NULL; ++ ++ p = elf_tdata (abfd)->phdr; ++ if (p != NULL) ++ { ++ unsigned int i, c; ++ ++ fprintf (f, _("\nProgram Header:\n")); ++ c = elf_elfheader (abfd)->e_phnum; ++ for (i = 0; i < c; i++, p++) ++ { ++ const char *pt = get_segment_type (p->p_type); ++ char buf[20]; ++ ++ if (pt == NULL) ++ { ++ sprintf (buf, "0x%lx", p->p_type); ++ pt = buf; ++ } ++ fprintf (f, "%8s off 0x", pt); ++ bfd_fprintf_vma (abfd, f, p->p_offset); ++ fprintf (f, " vaddr 0x"); ++ bfd_fprintf_vma (abfd, f, p->p_vaddr); ++ fprintf (f, " paddr 0x"); ++ bfd_fprintf_vma (abfd, f, p->p_paddr); ++ fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align)); ++ fprintf (f, " filesz 0x"); ++ bfd_fprintf_vma (abfd, f, p->p_filesz); ++ fprintf (f, " memsz 0x"); ++ bfd_fprintf_vma (abfd, f, p->p_memsz); ++ fprintf (f, " flags %c%c%c", ++ (p->p_flags & PF_R) != 0 ? 'r' : '-', ++ (p->p_flags & PF_W) != 0 ? 'w' : '-', ++ (p->p_flags & PF_X) != 0 ? 'x' : '-'); ++ if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0) ++ fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)); ++ fprintf (f, "\n"); ++ } ++ } ++ ++ s = bfd_get_section_by_name (abfd, ".dynamic"); ++ if (s != NULL && (s->flags & SEC_HAS_CONTENTS) != 0) ++ { ++ unsigned int elfsec; ++ unsigned long shlink; ++ bfd_byte *extdyn, *extdynend; ++ size_t extdynsize; ++ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); ++ ++ fprintf (f, _("\nDynamic Section:\n")); ++ ++ if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) ++ goto error_return; ++ ++ elfsec = _bfd_elf_section_from_bfd_section (abfd, s); ++ if (elfsec == SHN_BAD) ++ goto error_return; ++ shlink = elf_elfsections (abfd)[elfsec]->sh_link; ++ ++ extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; ++ swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; ++ ++ for (extdyn = dynbuf, extdynend = dynbuf + s->size; ++ (size_t) (extdynend - extdyn) >= extdynsize; ++ extdyn += extdynsize) ++ { ++ Elf_Internal_Dyn dyn; ++ const char *name = ""; ++ char ab[20]; ++ bool stringp; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ (*swap_dyn_in) (abfd, extdyn, &dyn); ++ ++ if (dyn.d_tag == DT_NULL) ++ break; ++ ++ stringp = false; ++ switch (dyn.d_tag) ++ { ++ default: ++ if (bed->elf_backend_get_target_dtag) ++ name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag); ++ ++ if (!strcmp (name, "")) ++ { ++ sprintf (ab, "%#" PRIx64, (uint64_t) dyn.d_tag); ++ name = ab; ++ } ++ break; ++ ++ case DT_NEEDED: name = "NEEDED"; stringp = true; break; ++ case DT_PLTRELSZ: name = "PLTRELSZ"; break; ++ case DT_PLTGOT: name = "PLTGOT"; break; ++ case DT_HASH: name = "HASH"; break; ++ case DT_STRTAB: name = "STRTAB"; break; ++ case DT_SYMTAB: name = "SYMTAB"; break; ++ case DT_RELA: name = "RELA"; break; ++ case DT_RELASZ: name = "RELASZ"; break; ++ case DT_RELAENT: name = "RELAENT"; break; ++ case DT_STRSZ: name = "STRSZ"; break; ++ case DT_SYMENT: name = "SYMENT"; break; ++ case DT_INIT: name = "INIT"; break; ++ case DT_FINI: name = "FINI"; break; ++ case DT_SONAME: name = "SONAME"; stringp = true; break; ++ case DT_RPATH: name = "RPATH"; stringp = true; break; ++ case DT_SYMBOLIC: name = "SYMBOLIC"; break; ++ case DT_REL: name = "REL"; break; ++ case DT_RELSZ: name = "RELSZ"; break; ++ case DT_RELENT: name = "RELENT"; break; ++ case DT_RELR: name = "RELR"; break; ++ case DT_RELRSZ: name = "RELRSZ"; break; ++ case DT_RELRENT: name = "RELRENT"; break; ++ case DT_PLTREL: name = "PLTREL"; break; ++ case DT_DEBUG: name = "DEBUG"; break; ++ case DT_TEXTREL: name = "TEXTREL"; break; ++ case DT_JMPREL: name = "JMPREL"; break; ++ case DT_BIND_NOW: name = "BIND_NOW"; break; ++ case DT_INIT_ARRAY: name = "INIT_ARRAY"; break; ++ case DT_FINI_ARRAY: name = "FINI_ARRAY"; break; ++ case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break; ++ case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break; ++ case DT_RUNPATH: name = "RUNPATH"; stringp = true; break; ++ case DT_FLAGS: name = "FLAGS"; break; ++ case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break; ++ case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break; ++ case DT_CHECKSUM: name = "CHECKSUM"; break; ++ case DT_PLTPADSZ: name = "PLTPADSZ"; break; ++ case DT_MOVEENT: name = "MOVEENT"; break; ++ case DT_MOVESZ: name = "MOVESZ"; break; ++ case DT_FEATURE: name = "FEATURE"; break; ++ case DT_POSFLAG_1: name = "POSFLAG_1"; break; ++ case DT_SYMINSZ: name = "SYMINSZ"; break; ++ case DT_SYMINENT: name = "SYMINENT"; break; ++ case DT_CONFIG: name = "CONFIG"; stringp = true; break; ++ case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = true; break; ++ case DT_AUDIT: name = "AUDIT"; stringp = true; break; ++ case DT_PLTPAD: name = "PLTPAD"; break; ++ case DT_MOVETAB: name = "MOVETAB"; break; ++ case DT_SYMINFO: name = "SYMINFO"; break; ++ case DT_RELACOUNT: name = "RELACOUNT"; break; ++ case DT_RELCOUNT: name = "RELCOUNT"; break; ++ case DT_FLAGS_1: name = "FLAGS_1"; break; ++ case DT_VERSYM: name = "VERSYM"; break; ++ case DT_VERDEF: name = "VERDEF"; break; ++ case DT_VERDEFNUM: name = "VERDEFNUM"; break; ++ case DT_VERNEED: name = "VERNEED"; break; ++ case DT_VERNEEDNUM: name = "VERNEEDNUM"; break; ++ case DT_AUXILIARY: name = "AUXILIARY"; stringp = true; break; ++ case DT_USED: name = "USED"; break; ++ case DT_FILTER: name = "FILTER"; stringp = true; break; ++ case DT_GNU_HASH: name = "GNU_HASH"; break; ++ } ++ ++ fprintf (f, " %-20s ", name); ++ if (! stringp) ++ { ++ fprintf (f, "0x"); ++ bfd_fprintf_vma (abfd, f, dyn.d_un.d_val); ++ } ++ else ++ { ++ const char *string; ++ unsigned int tagv = dyn.d_un.d_val; ++ ++ string = bfd_elf_string_from_elf_section (abfd, shlink, tagv); ++ if (string == NULL) ++ goto error_return; ++ fprintf (f, "%s", string); ++ } ++ fprintf (f, "\n"); ++ } ++ ++ free (dynbuf); ++ dynbuf = NULL; ++ } ++ ++ if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL) ++ || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL)) ++ { ++ if (! _bfd_elf_slurp_version_tables (abfd, false)) ++ return false; ++ } ++ ++ if (elf_dynverdef (abfd) != 0) ++ { ++ Elf_Internal_Verdef *t; ++ ++ fprintf (f, _("\nVersion definitions:\n")); ++ for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef) ++ { ++ fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx, ++ t->vd_flags, t->vd_hash, ++ t->vd_nodename ? t->vd_nodename : ""); ++ if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL) ++ { ++ Elf_Internal_Verdaux *a; ++ ++ fprintf (f, "\t"); ++ for (a = t->vd_auxptr->vda_nextptr; ++ a != NULL; ++ a = a->vda_nextptr) ++ fprintf (f, "%s ", ++ a->vda_nodename ? a->vda_nodename : ""); ++ fprintf (f, "\n"); ++ } ++ } ++ } ++ ++ if (elf_dynverref (abfd) != 0) ++ { ++ Elf_Internal_Verneed *t; ++ ++ fprintf (f, _("\nVersion References:\n")); ++ for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref) ++ { ++ Elf_Internal_Vernaux *a; ++ ++ fprintf (f, _(" required from %s:\n"), ++ t->vn_filename ? t->vn_filename : ""); ++ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) ++ fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash, ++ a->vna_flags, a->vna_other, ++ a->vna_nodename ? a->vna_nodename : ""); ++ } ++ } ++ ++ return true; ++ ++ error_return: ++ free (dynbuf); ++ return false; ++} ++ ++/* Find the file offset corresponding to VMA by using the program ++ headers. */ ++ ++static file_ptr ++offset_from_vma (Elf_Internal_Phdr *phdrs, size_t phnum, bfd_vma vma, ++ size_t size, size_t *max_size_p) ++{ ++ Elf_Internal_Phdr *seg; ++ size_t i; ++ ++ for (seg = phdrs, i = 0; i < phnum; ++seg, ++i) ++ if (seg->p_type == PT_LOAD ++ && vma >= (seg->p_vaddr & -seg->p_align) ++ && vma + size <= seg->p_vaddr + seg->p_filesz) ++ { ++ if (max_size_p) ++ *max_size_p = seg->p_vaddr + seg->p_filesz - vma; ++ return vma - seg->p_vaddr + seg->p_offset; ++ } ++ ++ if (max_size_p) ++ *max_size_p = 0; ++ bfd_set_error (bfd_error_invalid_operation); ++ return (file_ptr) -1; ++} ++ ++/* Convert hash table to internal form. */ ++ ++static bfd_vma * ++get_hash_table_data (bfd *abfd, bfd_size_type number, ++ unsigned int ent_size, bfd_size_type filesize) ++{ ++ unsigned char *e_data = NULL; ++ bfd_vma *i_data = NULL; ++ bfd_size_type size; ++ ++ if (ent_size != 4 && ent_size != 8) ++ return NULL; ++ ++ if ((size_t) number != number) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return NULL; ++ } ++ ++ size = ent_size * number; ++ /* Be kind to memory checkers (eg valgrind, address sanitizer) by not ++ attempting to allocate memory when the read is bound to fail. */ ++ if (size > filesize ++ || number >= ~(size_t) 0 / ent_size ++ || number >= ~(size_t) 0 / sizeof (*i_data)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return NULL; ++ } ++ ++ e_data = _bfd_malloc_and_read (abfd, size, size); ++ if (e_data == NULL) ++ return NULL; ++ ++ i_data = (bfd_vma *) bfd_malloc (number * sizeof (*i_data)); ++ if (i_data == NULL) ++ { ++ free (e_data); ++ return NULL; ++ } ++ ++ if (ent_size == 4) ++ while (number--) ++ i_data[number] = bfd_get_32 (abfd, e_data + number * ent_size); ++ else ++ while (number--) ++ i_data[number] = bfd_get_64 (abfd, e_data + number * ent_size); ++ ++ free (e_data); ++ return i_data; ++} ++ ++/* Address of .MIPS.xhash section. FIXME: What is the best way to ++ support DT_MIPS_XHASH? */ ++#define DT_MIPS_XHASH 0x70000036 ++ ++/* Reconstruct dynamic symbol table from PT_DYNAMIC segment. */ ++ ++bool ++_bfd_elf_get_dynamic_symbols (bfd *abfd, Elf_Internal_Phdr *phdr, ++ Elf_Internal_Phdr *phdrs, size_t phnum, ++ bfd_size_type filesize) ++{ ++ bfd_byte *extdyn, *extdynend; ++ size_t extdynsize; ++ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); ++ bool (*swap_symbol_in) (bfd *, const void *, const void *, ++ Elf_Internal_Sym *); ++ Elf_Internal_Dyn dyn; ++ bfd_vma dt_hash = 0; ++ bfd_vma dt_gnu_hash = 0; ++ bfd_vma dt_mips_xhash = 0; ++ bfd_vma dt_strtab = 0; ++ bfd_vma dt_symtab = 0; ++ size_t dt_strsz = 0; ++ bfd_vma dt_versym = 0; ++ bfd_vma dt_verdef = 0; ++ bfd_vma dt_verneed = 0; ++ bfd_byte *dynbuf = NULL; ++ char *strbuf = NULL; ++ bfd_vma *gnubuckets = NULL; ++ bfd_vma *gnuchains = NULL; ++ bfd_vma *mipsxlat = NULL; ++ file_ptr saved_filepos, filepos; ++ bool res = false; ++ size_t amt; ++ bfd_byte *esymbuf = NULL, *esym; ++ bfd_size_type symcount; ++ Elf_Internal_Sym *isymbuf = NULL; ++ Elf_Internal_Sym *isym, *isymend; ++ bfd_byte *versym = NULL; ++ bfd_byte *verdef = NULL; ++ bfd_byte *verneed = NULL; ++ size_t verdef_size = 0; ++ size_t verneed_size = 0; ++ size_t extsym_size; ++ const struct elf_backend_data *bed; ++ ++ /* Return TRUE if symbol table is bad. */ ++ if (elf_bad_symtab (abfd)) ++ return true; ++ ++ /* Return TRUE if DT_HASH/DT_GNU_HASH have bee processed before. */ ++ if (elf_tdata (abfd)->dt_strtab != NULL) ++ return true; ++ ++ bed = get_elf_backend_data (abfd); ++ ++ /* Save file position for elf_object_p. */ ++ saved_filepos = bfd_tell (abfd); ++ ++ if (bfd_seek (abfd, phdr->p_offset, SEEK_SET) != 0) ++ goto error_return; ++ ++ dynbuf = _bfd_malloc_and_read (abfd, phdr->p_filesz, phdr->p_filesz); ++ if (dynbuf == NULL) ++ goto error_return; ++ ++ extsym_size = bed->s->sizeof_sym; ++ extdynsize = bed->s->sizeof_dyn; ++ swap_dyn_in = bed->s->swap_dyn_in; ++ ++ extdyn = dynbuf; ++ if (phdr->p_filesz < extdynsize) ++ goto error_return; ++ extdynend = extdyn + phdr->p_filesz; ++ for (; extdyn <= (extdynend - extdynsize); extdyn += extdynsize) ++ { ++ swap_dyn_in (abfd, extdyn, &dyn); ++ ++ if (dyn.d_tag == DT_NULL) ++ break; ++ ++ switch (dyn.d_tag) ++ { ++ case DT_HASH: ++ dt_hash = dyn.d_un.d_val; ++ break; ++ case DT_GNU_HASH: ++ if (bed->elf_machine_code != EM_MIPS ++ && bed->elf_machine_code != EM_MIPS_RS3_LE) ++ dt_gnu_hash = dyn.d_un.d_val; ++ break; ++ case DT_STRTAB: ++ dt_strtab = dyn.d_un.d_val; ++ break; ++ case DT_SYMTAB: ++ dt_symtab = dyn.d_un.d_val; ++ break; ++ case DT_STRSZ: ++ dt_strsz = dyn.d_un.d_val; ++ break; ++ case DT_SYMENT: ++ if (dyn.d_un.d_val != extsym_size) ++ goto error_return; ++ break; ++ case DT_VERSYM: ++ dt_versym = dyn.d_un.d_val; ++ break; ++ case DT_VERDEF: ++ dt_verdef = dyn.d_un.d_val; ++ break; ++ case DT_VERNEED: ++ dt_verneed = dyn.d_un.d_val; ++ break; ++ default: ++ if (dyn.d_tag == DT_MIPS_XHASH ++ && (bed->elf_machine_code == EM_MIPS ++ || bed->elf_machine_code == EM_MIPS_RS3_LE)) ++ { ++ dt_gnu_hash = dyn.d_un.d_val; ++ dt_mips_xhash = dyn.d_un.d_val; ++ } ++ break; ++ } ++ } ++ ++ /* Check if we can reconstruct dynamic symbol table from PT_DYNAMIC ++ segment. */ ++ if ((!dt_hash && !dt_gnu_hash) ++ || !dt_strtab ++ || !dt_symtab ++ || !dt_strsz) ++ goto error_return; ++ ++ /* Get dynamic string table. */ ++ filepos = offset_from_vma (phdrs, phnum, dt_strtab, dt_strsz, NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ ++ /* Dynamic string table must be valid until ABFD is closed. */ ++ strbuf = (char *) _bfd_alloc_and_read (abfd, dt_strsz, dt_strsz); ++ if (strbuf == NULL) ++ goto error_return; ++ ++ /* Get the real symbol count from DT_HASH or DT_GNU_HASH. Prefer ++ DT_HASH since it is simpler than DT_GNU_HASH. */ ++ if (dt_hash) ++ { ++ unsigned char nb[16]; ++ unsigned int hash_ent_size; ++ ++ switch (bed->elf_machine_code) ++ { ++ case EM_ALPHA: ++ case EM_S390: ++ case EM_S390_OLD: ++ if (bed->s->elfclass == ELFCLASS64) ++ { ++ hash_ent_size = 8; ++ break; ++ } ++ /* FALLTHROUGH */ ++ default: ++ hash_ent_size = 4; ++ break; ++ } ++ ++ filepos = offset_from_vma (phdrs, phnum, dt_hash, sizeof (nb), ++ NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0 ++ || (bfd_bread (nb, 2 * hash_ent_size, abfd) ++ != (2 * hash_ent_size))) ++ goto error_return; ++ ++ /* The number of dynamic symbol table entries equals the number ++ of chains. */ ++ if (hash_ent_size == 8) ++ symcount = bfd_get_64 (abfd, nb + hash_ent_size); ++ else ++ symcount = bfd_get_32 (abfd, nb + hash_ent_size); ++ } ++ else ++ { ++ /* For DT_GNU_HASH, only defined symbols with non-STB_LOCAL ++ bindings are in hash table. Since in dynamic symbol table, ++ all symbols with STB_LOCAL binding are placed before symbols ++ with other bindings and all undefined symbols are placed ++ before defined ones, the highest symbol index in DT_GNU_HASH ++ is the highest dynamic symbol table index. */ ++ unsigned char nb[16]; ++ bfd_vma ngnubuckets; ++ bfd_vma gnusymidx; ++ size_t i, ngnuchains; ++ bfd_vma maxchain = 0xffffffff, bitmaskwords; ++ bfd_vma buckets_vma; ++ ++ filepos = offset_from_vma (phdrs, phnum, dt_gnu_hash, ++ sizeof (nb), NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0 ++ || bfd_bread (nb, sizeof (nb), abfd) != sizeof (nb)) ++ goto error_return; ++ ++ ngnubuckets = bfd_get_32 (abfd, nb); ++ gnusymidx = bfd_get_32 (abfd, nb + 4); ++ bitmaskwords = bfd_get_32 (abfd, nb + 8); ++ buckets_vma = dt_gnu_hash + 16; ++ if (bed->s->elfclass == ELFCLASS32) ++ buckets_vma += bitmaskwords * 4; ++ else ++ buckets_vma += bitmaskwords * 8; ++ filepos = offset_from_vma (phdrs, phnum, buckets_vma, 4, NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ ++ gnubuckets = get_hash_table_data (abfd, ngnubuckets, 4, filesize); ++ if (gnubuckets == NULL) ++ goto error_return; ++ ++ for (i = 0; i < ngnubuckets; i++) ++ if (gnubuckets[i] != 0) ++ { ++ if (gnubuckets[i] < gnusymidx) ++ goto error_return; ++ ++ if (maxchain == 0xffffffff || gnubuckets[i] > maxchain) ++ maxchain = gnubuckets[i]; ++ } ++ ++ if (maxchain == 0xffffffff) ++ { ++ symcount = 0; ++ goto empty_gnu_hash; ++ } ++ ++ maxchain -= gnusymidx; ++ filepos = offset_from_vma (phdrs, phnum, ++ (buckets_vma + ++ 4 * (ngnubuckets + maxchain)), ++ 4, NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ ++ do ++ { ++ if (bfd_bread (nb, 4, abfd) != 4) ++ goto error_return; ++ ++maxchain; ++ if (maxchain == 0) ++ goto error_return; ++ } ++ while ((bfd_get_32 (abfd, nb) & 1) == 0); ++ ++ filepos = offset_from_vma (phdrs, phnum, ++ (buckets_vma + 4 * ngnubuckets), ++ 4, NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ ++ gnuchains = get_hash_table_data (abfd, maxchain, 4, filesize); ++ if (gnubuckets == NULL) ++ goto error_return; ++ ngnuchains = maxchain; ++ ++ if (dt_mips_xhash) ++ { ++ filepos = offset_from_vma (phdrs, phnum, ++ (buckets_vma ++ + 4 * (ngnubuckets + maxchain)), ++ 4, NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ ++ mipsxlat = get_hash_table_data (abfd, maxchain, 4, filesize); ++ if (mipsxlat == NULL) ++ goto error_return; ++ } ++ ++ symcount = 0; ++ for (i = 0; i < ngnubuckets; ++i) ++ if (gnubuckets[i] != 0) ++ { ++ bfd_vma si = gnubuckets[i]; ++ bfd_vma off = si - gnusymidx; ++ do ++ { ++ if (mipsxlat) ++ { ++ if (mipsxlat[off] >= symcount) ++ symcount = mipsxlat[off] + 1; ++ } ++ else ++ { ++ if (si >= symcount) ++ symcount = si + 1; ++ } ++ si++; ++ } ++ while (off < ngnuchains && (gnuchains[off++] & 1) == 0); ++ } ++ } ++ ++ /* Swap in dynamic symbol table. */ ++ if (_bfd_mul_overflow (symcount, extsym_size, &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto error_return; ++ } ++ ++ filepos = offset_from_vma (phdrs, phnum, dt_symtab, amt, NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ esymbuf = _bfd_malloc_and_read (abfd, amt, amt); ++ if (esymbuf == NULL) ++ goto error_return; ++ ++ if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto error_return; ++ } ++ ++ /* Dynamic symbol table must be valid until ABFD is closed. */ ++ isymbuf = (Elf_Internal_Sym *) bfd_alloc (abfd, amt); ++ if (isymbuf == NULL) ++ goto error_return; ++ ++ swap_symbol_in = bed->s->swap_symbol_in; ++ ++ /* Convert the symbols to internal form. */ ++ isymend = isymbuf + symcount; ++ for (esym = esymbuf, isym = isymbuf; ++ isym < isymend; ++ esym += extsym_size, isym++) ++ if (!swap_symbol_in (abfd, esym, NULL, isym) ++ || isym->st_name >= dt_strsz) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ goto error_return; ++ } ++ ++ if (dt_versym) ++ { ++ /* Swap in DT_VERSYM. */ ++ if (_bfd_mul_overflow (symcount, 2, &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto error_return; ++ } ++ ++ filepos = offset_from_vma (phdrs, phnum, dt_versym, amt, NULL); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ ++ /* DT_VERSYM info must be valid until ABFD is closed. */ ++ versym = _bfd_alloc_and_read (abfd, amt, amt); ++ ++ if (dt_verdef) ++ { ++ /* Read in DT_VERDEF. */ ++ filepos = offset_from_vma (phdrs, phnum, dt_verdef, ++ 0, &verdef_size); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ ++ /* DT_VERDEF info must be valid until ABFD is closed. */ ++ verdef = _bfd_alloc_and_read (abfd, verdef_size, ++ verdef_size); ++ } ++ ++ if (dt_verneed) ++ { ++ /* Read in DT_VERNEED. */ ++ filepos = offset_from_vma (phdrs, phnum, dt_verneed, ++ 0, &verneed_size); ++ if (filepos == (file_ptr) -1 ++ || bfd_seek (abfd, filepos, SEEK_SET) != 0) ++ goto error_return; ++ ++ /* DT_VERNEED info must be valid until ABFD is closed. */ ++ verneed = _bfd_alloc_and_read (abfd, verneed_size, ++ verneed_size); ++ } ++ } ++ ++ empty_gnu_hash: ++ elf_tdata (abfd)->dt_strtab = strbuf; ++ elf_tdata (abfd)->dt_symtab = isymbuf; ++ elf_tdata (abfd)->dt_symtab_count = symcount; ++ elf_tdata (abfd)->dt_versym = versym; ++ elf_tdata (abfd)->dt_verdef = verdef; ++ elf_tdata (abfd)->dt_verneed = verneed; ++ elf_tdata (abfd)->dt_verdef_count ++ = verdef_size / sizeof (Elf_External_Verdef); ++ elf_tdata (abfd)->dt_verneed_count ++ = verneed_size / sizeof (Elf_External_Verneed); ++ ++ res = true; ++ ++ error_return: ++ /* Restore file position for elf_object_p. */ ++ if (bfd_seek (abfd, saved_filepos, SEEK_SET) != 0) ++ res = false; ++ free (dynbuf); ++ free (esymbuf); ++ free (gnubuckets); ++ free (gnuchains); ++ free (mipsxlat); ++ return res; ++} ++ ++/* Reconstruct section from dynamic symbol. */ ++ ++asection * ++_bfd_elf_get_section_from_dynamic_symbol (bfd *abfd, ++ Elf_Internal_Sym *isym) ++{ ++ asection *sec; ++ flagword flags; ++ ++ if (!elf_use_dt_symtab_p (abfd)) ++ return NULL; ++ ++ flags = SEC_ALLOC | SEC_LOAD; ++ switch (ELF_ST_TYPE (isym->st_info)) ++ { ++ case STT_FUNC: ++ case STT_GNU_IFUNC: ++ sec = bfd_get_section_by_name (abfd, ".text"); ++ if (sec == NULL) ++ sec = bfd_make_section_with_flags (abfd, ++ ".text", ++ flags | SEC_CODE); ++ break; ++ case STT_COMMON: ++ sec = bfd_com_section_ptr; ++ break; ++ case STT_OBJECT: ++ sec = bfd_get_section_by_name (abfd, ".data"); ++ if (sec == NULL) ++ sec = bfd_make_section_with_flags (abfd, ++ ".data", ++ flags | SEC_DATA); ++ break; ++ case STT_TLS: ++ sec = bfd_get_section_by_name (abfd, ".tdata"); ++ if (sec == NULL) ++ sec = bfd_make_section_with_flags (abfd, ++ ".tdata", ++ (flags ++ | SEC_DATA ++ | SEC_THREAD_LOCAL)); ++ break; ++ default: ++ sec = bfd_abs_section_ptr; ++ break; ++ } ++ ++ return sec; ++} ++ ++/* Get version name. If BASE_P is TRUE, return "Base" for VER_FLG_BASE ++ and return symbol version for symbol version itself. */ ++ ++const char * ++_bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol, ++ bool base_p, ++ bool *hidden) ++{ ++ const char *version_string = NULL; ++ if ((elf_dynversym (abfd) != 0 ++ && (elf_dynverdef (abfd) != 0 || elf_dynverref (abfd) != 0)) ++ || (elf_tdata (abfd)->dt_versym != NULL ++ && (elf_tdata (abfd)->dt_verdef != NULL ++ || elf_tdata (abfd)->dt_verneed != NULL))) ++ { ++ unsigned int vernum = ((elf_symbol_type *) symbol)->version; ++ ++ *hidden = (vernum & VERSYM_HIDDEN) != 0; ++ vernum &= VERSYM_VERSION; ++ ++ if (vernum == 0) ++ version_string = ""; ++ else if (vernum == 1 ++ && (vernum > elf_tdata (abfd)->cverdefs ++ || (elf_tdata (abfd)->verdef[0].vd_flags ++ == VER_FLG_BASE))) ++ version_string = base_p ? "Base" : ""; ++ else if (vernum <= elf_tdata (abfd)->cverdefs) ++ { ++ const char *nodename ++ = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; ++ version_string = ""; ++ if (base_p ++ || nodename == NULL ++ || symbol->name == NULL ++ || strcmp (symbol->name, nodename) != 0) ++ version_string = nodename; ++ } ++ else ++ { ++ Elf_Internal_Verneed *t; ++ ++ version_string = _(""); ++ for (t = elf_tdata (abfd)->verref; ++ t != NULL; ++ t = t->vn_nextref) ++ { ++ Elf_Internal_Vernaux *a; ++ ++ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) ++ { ++ if (a->vna_other == vernum) ++ { ++ *hidden = true; ++ version_string = a->vna_nodename; ++ break; ++ } ++ } ++ } ++ } ++ } ++ return version_string; ++} ++ ++/* Display ELF-specific fields of a symbol. */ ++ ++void ++bfd_elf_print_symbol (bfd *abfd, ++ void *filep, ++ asymbol *symbol, ++ bfd_print_symbol_type how) ++{ ++ FILE *file = (FILE *) filep; ++ switch (how) ++ { ++ case bfd_print_symbol_name: ++ fprintf (file, "%s", symbol->name); ++ break; ++ case bfd_print_symbol_more: ++ fprintf (file, "elf "); ++ bfd_fprintf_vma (abfd, file, symbol->value); ++ fprintf (file, " %x", symbol->flags); ++ break; ++ case bfd_print_symbol_all: ++ { ++ const char *section_name; ++ const char *name = NULL; ++ const struct elf_backend_data *bed; ++ unsigned char st_other; ++ bfd_vma val; ++ const char *version_string; ++ bool hidden; ++ ++ section_name = symbol->section ? symbol->section->name : "(*none*)"; ++ ++ bed = get_elf_backend_data (abfd); ++ if (bed->elf_backend_print_symbol_all) ++ name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol); ++ ++ if (name == NULL) ++ { ++ name = symbol->name; ++ bfd_print_symbol_vandf (abfd, file, symbol); ++ } ++ ++ fprintf (file, " %s\t", section_name); ++ /* Print the "other" value for a symbol. For common symbols, ++ we've already printed the size; now print the alignment. ++ For other symbols, we have no specified alignment, and ++ we've printed the address; now print the size. */ ++ if (symbol->section && bfd_is_com_section (symbol->section)) ++ val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value; ++ else ++ val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size; ++ bfd_fprintf_vma (abfd, file, val); ++ ++ /* If we have version information, print it. */ ++ version_string = _bfd_elf_get_symbol_version_string (abfd, ++ symbol, ++ true, ++ &hidden); ++ if (version_string) ++ { ++ if (!hidden) ++ fprintf (file, " %-11s", version_string); ++ else ++ { ++ int i; ++ ++ fprintf (file, " (%s)", version_string); ++ for (i = 10 - strlen (version_string); i > 0; --i) ++ putc (' ', file); ++ } ++ } ++ ++ /* If the st_other field is not zero, print it. */ ++ st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other; ++ ++ switch (st_other) ++ { ++ case 0: break; ++ case STV_INTERNAL: fprintf (file, " .internal"); break; ++ case STV_HIDDEN: fprintf (file, " .hidden"); break; ++ case STV_PROTECTED: fprintf (file, " .protected"); break; ++ default: ++ /* Some other non-defined flags are also present, so print ++ everything hex. */ ++ fprintf (file, " 0x%02x", (unsigned int) st_other); ++ } ++ ++ fprintf (file, " %s", name); ++ } ++ break; ++ } ++} ++ ++/* ELF .o/exec file reading */ ++ ++/* Create a new bfd section from an ELF section header. */ ++ ++bool ++bfd_section_from_shdr (bfd *abfd, unsigned int shindex) ++{ ++ Elf_Internal_Shdr *hdr; ++ Elf_Internal_Ehdr *ehdr; ++ const struct elf_backend_data *bed; ++ const char *name; ++ bool ret = true; ++ ++ if (shindex >= elf_numsections (abfd)) ++ return false; ++ ++ /* PR17512: A corrupt ELF binary might contain a loop of sections via ++ sh_link or sh_info. Detect this here, by refusing to load a ++ section that we are already in the process of loading. */ ++ if (elf_tdata (abfd)->being_created[shindex]) ++ { ++ _bfd_error_handler ++ (_("%pB: warning: loop in section dependencies detected"), abfd); ++ return false; ++ } ++ elf_tdata (abfd)->being_created[shindex] = true; ++ ++ hdr = elf_elfsections (abfd)[shindex]; ++ ehdr = elf_elfheader (abfd); ++ name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx, ++ hdr->sh_name); ++ if (name == NULL) ++ goto fail; ++ ++ bed = get_elf_backend_data (abfd); ++ switch (hdr->sh_type) ++ { ++ case SHT_NULL: ++ /* Inactive section. Throw it away. */ ++ goto success; ++ ++ case SHT_PROGBITS: /* Normal section with contents. */ ++ case SHT_NOBITS: /* .bss section. */ ++ case SHT_HASH: /* .hash section. */ ++ case SHT_NOTE: /* .note section. */ ++ case SHT_INIT_ARRAY: /* .init_array section. */ ++ case SHT_FINI_ARRAY: /* .fini_array section. */ ++ case SHT_PREINIT_ARRAY: /* .preinit_array section. */ ++ case SHT_GNU_LIBLIST: /* .gnu.liblist section. */ ++ case SHT_GNU_HASH: /* .gnu.hash section. */ ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ ++ case SHT_DYNAMIC: /* Dynamic linking information. */ ++ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) ++ goto fail; ++ ++ if (hdr->sh_link > elf_numsections (abfd)) ++ { ++ /* PR 10478: Accept Solaris binaries with a sh_link field ++ set to SHN_BEFORE (LORESERVE) or SHN_AFTER (LORESERVE+1). */ ++ switch (bfd_get_arch (abfd)) ++ { ++ case bfd_arch_i386: ++ case bfd_arch_sparc: ++ if (hdr->sh_link == (SHN_LORESERVE & 0xffff) ++ || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff)) ++ break; ++ /* Otherwise fall through. */ ++ default: ++ goto fail; ++ } ++ } ++ else if (elf_elfsections (abfd)[hdr->sh_link] == NULL) ++ goto fail; ++ else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB) ++ { ++ Elf_Internal_Shdr *dynsymhdr; ++ ++ /* The shared libraries distributed with hpux11 have a bogus ++ sh_link field for the ".dynamic" section. Find the ++ string table for the ".dynsym" section instead. */ ++ if (elf_dynsymtab (abfd) != 0) ++ { ++ dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)]; ++ hdr->sh_link = dynsymhdr->sh_link; ++ } ++ else ++ { ++ unsigned int i, num_sec; ++ ++ num_sec = elf_numsections (abfd); ++ for (i = 1; i < num_sec; i++) ++ { ++ dynsymhdr = elf_elfsections (abfd)[i]; ++ if (dynsymhdr->sh_type == SHT_DYNSYM) ++ { ++ hdr->sh_link = dynsymhdr->sh_link; ++ break; ++ } ++ } ++ } ++ } ++ goto success; ++ ++ case SHT_SYMTAB: /* A symbol table. */ ++ if (elf_onesymtab (abfd) == shindex) ++ goto success; ++ ++ if (hdr->sh_entsize != bed->s->sizeof_sym) ++ goto fail; ++ ++ if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size) ++ { ++ if (hdr->sh_size != 0) ++ goto fail; ++ /* Some assemblers erroneously set sh_info to one with a ++ zero sh_size. ld sees this as a global symbol count ++ of (unsigned) -1. Fix it here. */ ++ hdr->sh_info = 0; ++ goto success; ++ } ++ ++ /* PR 18854: A binary might contain more than one symbol table. ++ Unusual, but possible. Warn, but continue. */ ++ if (elf_onesymtab (abfd) != 0) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: warning: multiple symbol tables detected" ++ " - ignoring the table in section %u"), ++ abfd, shindex); ++ goto success; ++ } ++ elf_onesymtab (abfd) = shindex; ++ elf_symtab_hdr (abfd) = *hdr; ++ elf_elfsections (abfd)[shindex] = hdr = & elf_symtab_hdr (abfd); ++ abfd->flags |= HAS_SYMS; ++ ++ /* Sometimes a shared object will map in the symbol table. If ++ SHF_ALLOC is set, and this is a shared object, then we also ++ treat this section as a BFD section. We can not base the ++ decision purely on SHF_ALLOC, because that flag is sometimes ++ set in a relocatable object file, which would confuse the ++ linker. */ ++ if ((hdr->sh_flags & SHF_ALLOC) != 0 ++ && (abfd->flags & DYNAMIC) != 0 ++ && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name, ++ shindex)) ++ goto fail; ++ ++ /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we ++ can't read symbols without that section loaded as well. It ++ is most likely specified by the next section header. */ ++ { ++ elf_section_list * entry; ++ unsigned int i, num_sec; ++ ++ for (entry = elf_symtab_shndx_list (abfd); entry; entry = entry->next) ++ if (entry->hdr.sh_link == shindex) ++ goto success; ++ ++ num_sec = elf_numsections (abfd); ++ for (i = shindex + 1; i < num_sec; i++) ++ { ++ Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; ++ ++ if (hdr2->sh_type == SHT_SYMTAB_SHNDX ++ && hdr2->sh_link == shindex) ++ break; ++ } ++ ++ if (i == num_sec) ++ for (i = 1; i < shindex; i++) ++ { ++ Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; ++ ++ if (hdr2->sh_type == SHT_SYMTAB_SHNDX ++ && hdr2->sh_link == shindex) ++ break; ++ } ++ ++ if (i != shindex) ++ ret = bfd_section_from_shdr (abfd, i); ++ /* else FIXME: we have failed to find the symbol table. ++ Should we issue an error? */ ++ goto success; ++ } ++ ++ case SHT_DYNSYM: /* A dynamic symbol table. */ ++ if (elf_dynsymtab (abfd) == shindex) ++ goto success; ++ ++ if (hdr->sh_entsize != bed->s->sizeof_sym) ++ goto fail; ++ ++ if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size) ++ { ++ if (hdr->sh_size != 0) ++ goto fail; ++ ++ /* Some linkers erroneously set sh_info to one with a ++ zero sh_size. ld sees this as a global symbol count ++ of (unsigned) -1. Fix it here. */ ++ hdr->sh_info = 0; ++ goto success; ++ } ++ ++ /* PR 18854: A binary might contain more than one dynamic symbol table. ++ Unusual, but possible. Warn, but continue. */ ++ if (elf_dynsymtab (abfd) != 0) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: warning: multiple dynamic symbol tables detected" ++ " - ignoring the table in section %u"), ++ abfd, shindex); ++ goto success; ++ } ++ elf_dynsymtab (abfd) = shindex; ++ elf_tdata (abfd)->dynsymtab_hdr = *hdr; ++ elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr; ++ abfd->flags |= HAS_SYMS; ++ ++ /* Besides being a symbol table, we also treat this as a regular ++ section, so that objcopy can handle it. */ ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ ++ case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections. */ ++ { ++ elf_section_list * entry; ++ ++ for (entry = elf_symtab_shndx_list (abfd); entry; entry = entry->next) ++ if (entry->ndx == shindex) ++ goto success; ++ ++ entry = bfd_alloc (abfd, sizeof (*entry)); ++ if (entry == NULL) ++ goto fail; ++ entry->ndx = shindex; ++ entry->hdr = * hdr; ++ entry->next = elf_symtab_shndx_list (abfd); ++ elf_symtab_shndx_list (abfd) = entry; ++ elf_elfsections (abfd)[shindex] = & entry->hdr; ++ goto success; ++ } ++ ++ case SHT_STRTAB: /* A string table. */ ++ if (hdr->bfd_section != NULL) ++ goto success; ++ ++ if (ehdr->e_shstrndx == shindex) ++ { ++ elf_tdata (abfd)->shstrtab_hdr = *hdr; ++ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr; ++ goto success; ++ } ++ ++ if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex) ++ { ++ symtab_strtab: ++ elf_tdata (abfd)->strtab_hdr = *hdr; ++ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr; ++ goto success; ++ } ++ ++ if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex) ++ { ++ dynsymtab_strtab: ++ elf_tdata (abfd)->dynstrtab_hdr = *hdr; ++ hdr = &elf_tdata (abfd)->dynstrtab_hdr; ++ elf_elfsections (abfd)[shindex] = hdr; ++ /* We also treat this as a regular section, so that objcopy ++ can handle it. */ ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, ++ shindex); ++ goto success; ++ } ++ ++ /* If the string table isn't one of the above, then treat it as a ++ regular section. We need to scan all the headers to be sure, ++ just in case this strtab section appeared before the above. */ ++ if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0) ++ { ++ unsigned int i, num_sec; ++ ++ num_sec = elf_numsections (abfd); ++ for (i = 1; i < num_sec; i++) ++ { ++ Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; ++ if (hdr2->sh_link == shindex) ++ { ++ /* Prevent endless recursion on broken objects. */ ++ if (i == shindex) ++ goto fail; ++ if (! bfd_section_from_shdr (abfd, i)) ++ goto fail; ++ if (elf_onesymtab (abfd) == i) ++ goto symtab_strtab; ++ if (elf_dynsymtab (abfd) == i) ++ goto dynsymtab_strtab; ++ } ++ } ++ } ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ ++ case SHT_REL: ++ case SHT_RELA: ++ case SHT_RELR: ++ /* *These* do a lot of work -- but build no sections! */ ++ { ++ asection *target_sect; ++ Elf_Internal_Shdr *hdr2, **p_hdr; ++ unsigned int num_sec = elf_numsections (abfd); ++ struct bfd_elf_section_data *esdt; ++ bfd_size_type size; ++ ++ if (hdr->sh_type == SHT_REL) ++ size = bed->s->sizeof_rel; ++ else if (hdr->sh_type == SHT_RELA) ++ size = bed->s->sizeof_rela; ++ else ++ size = bed->s->arch_size / 8; ++ if (hdr->sh_entsize != size) ++ goto fail; ++ ++ /* Check for a bogus link to avoid crashing. */ ++ if (hdr->sh_link >= num_sec) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: invalid link %u for reloc section %s (index %u)"), ++ abfd, hdr->sh_link, name, shindex); ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ } ++ ++ /* Get the symbol table. */ ++ if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB ++ || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM) ++ && ! bfd_section_from_shdr (abfd, hdr->sh_link)) ++ goto fail; ++ ++ /* If this is an alloc section in an executable or shared ++ library, or the reloc section does not use the main symbol ++ table we don't treat it as a reloc section. BFD can't ++ adequately represent such a section, so at least for now, ++ we don't try. We just present it as a normal section. We ++ also can't use it as a reloc section if it points to the ++ null section, an invalid section, another reloc section, or ++ its sh_link points to the null section. */ ++ if (((abfd->flags & (DYNAMIC | EXEC_P)) != 0 ++ && (hdr->sh_flags & SHF_ALLOC) != 0) ++ || (hdr->sh_flags & SHF_COMPRESSED) != 0 ++ || hdr->sh_type == SHT_RELR ++ || hdr->sh_link == SHN_UNDEF ++ || hdr->sh_link != elf_onesymtab (abfd) ++ || hdr->sh_info == SHN_UNDEF ++ || hdr->sh_info >= num_sec ++ || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL ++ || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA) ++ { ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ } ++ ++ if (! bfd_section_from_shdr (abfd, hdr->sh_info)) ++ goto fail; ++ ++ target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info); ++ if (target_sect == NULL) ++ goto fail; ++ ++ esdt = elf_section_data (target_sect); ++ if (hdr->sh_type == SHT_RELA) ++ p_hdr = &esdt->rela.hdr; ++ else ++ p_hdr = &esdt->rel.hdr; ++ ++ /* PR 17512: file: 0b4f81b7. ++ Also see PR 24456, for a file which deliberately has two reloc ++ sections. */ ++ if (*p_hdr != NULL) ++ { ++ if (!bed->init_secondary_reloc_section (abfd, hdr, name, shindex)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: warning: secondary relocation section '%s' " ++ "for section %pA found - ignoring"), ++ abfd, name, target_sect); ++ } ++ else ++ esdt->has_secondary_relocs = true; ++ goto success; ++ } ++ ++ hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2)); ++ if (hdr2 == NULL) ++ goto fail; ++ *hdr2 = *hdr; ++ *p_hdr = hdr2; ++ elf_elfsections (abfd)[shindex] = hdr2; ++ target_sect->reloc_count += (NUM_SHDR_ENTRIES (hdr) ++ * bed->s->int_rels_per_ext_rel); ++ target_sect->flags |= SEC_RELOC; ++ target_sect->relocation = NULL; ++ target_sect->rel_filepos = hdr->sh_offset; ++ /* In the section to which the relocations apply, mark whether ++ its relocations are of the REL or RELA variety. */ ++ if (hdr->sh_size != 0) ++ { ++ if (hdr->sh_type == SHT_RELA) ++ target_sect->use_rela_p = 1; ++ } ++ abfd->flags |= HAS_RELOC; ++ goto success; ++ } ++ ++ case SHT_GNU_verdef: ++ if (hdr->sh_info != 0) ++ elf_dynverdef (abfd) = shindex; ++ elf_tdata (abfd)->dynverdef_hdr = *hdr; ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ ++ case SHT_GNU_versym: ++ if (hdr->sh_entsize != sizeof (Elf_External_Versym)) ++ goto fail; ++ ++ elf_dynversym (abfd) = shindex; ++ elf_tdata (abfd)->dynversym_hdr = *hdr; ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ ++ case SHT_GNU_verneed: ++ if (hdr->sh_info != 0) ++ elf_dynverref (abfd) = shindex; ++ elf_tdata (abfd)->dynverref_hdr = *hdr; ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ ++ case SHT_SHLIB: ++ goto success; ++ ++ case SHT_GROUP: ++ if (! IS_VALID_GROUP_SECTION_HEADER (hdr, GRP_ENTRY_SIZE)) ++ goto fail; ++ ++ if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) ++ goto fail; ++ ++ goto success; ++ ++ default: ++ /* Possibly an attributes section. */ ++ if (hdr->sh_type == SHT_GNU_ATTRIBUTES ++ || hdr->sh_type == bed->obj_attrs_section_type) ++ { ++ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) ++ goto fail; ++ _bfd_elf_parse_attributes (abfd, hdr); ++ goto success; ++ } ++ ++ /* Check for any processor-specific section types. */ ++ if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex)) ++ goto success; ++ ++ if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER) ++ { ++ if ((hdr->sh_flags & SHF_ALLOC) != 0) ++ /* FIXME: How to properly handle allocated section reserved ++ for applications? */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unknown type [%#x] section `%s'"), ++ abfd, hdr->sh_type, name); ++ else ++ { ++ /* Allow sections reserved for applications. */ ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ } ++ } ++ else if (hdr->sh_type >= SHT_LOPROC ++ && hdr->sh_type <= SHT_HIPROC) ++ /* FIXME: We should handle this section. */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unknown type [%#x] section `%s'"), ++ abfd, hdr->sh_type, name); ++ else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS) ++ { ++ /* Unrecognised OS-specific sections. */ ++ if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0) ++ /* SHF_OS_NONCONFORMING indicates that special knowledge is ++ required to correctly process the section and the file should ++ be rejected with an error message. */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unknown type [%#x] section `%s'"), ++ abfd, hdr->sh_type, name); ++ else ++ { ++ /* Otherwise it should be processed. */ ++ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++ goto success; ++ } ++ } ++ else ++ /* FIXME: We should handle this section. */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unknown type [%#x] section `%s'"), ++ abfd, hdr->sh_type, name); ++ ++ goto fail; ++ } ++ ++ fail: ++ ret = false; ++ success: ++ elf_tdata (abfd)->being_created[shindex] = false; ++ return ret; ++} ++ ++/* Return the local symbol specified by ABFD, R_SYMNDX. */ ++ ++Elf_Internal_Sym * ++bfd_sym_from_r_symndx (struct sym_cache *cache, ++ bfd *abfd, ++ unsigned long r_symndx) ++{ ++ unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE; ++ ++ if (cache->abfd != abfd || cache->indx[ent] != r_symndx) ++ { ++ Elf_Internal_Shdr *symtab_hdr; ++ unsigned char esym[sizeof (Elf64_External_Sym)]; ++ Elf_External_Sym_Shndx eshndx; ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx, ++ &cache->sym[ent], esym, &eshndx) == NULL) ++ return NULL; ++ ++ if (cache->abfd != abfd) ++ { ++ memset (cache->indx, -1, sizeof (cache->indx)); ++ cache->abfd = abfd; ++ } ++ cache->indx[ent] = r_symndx; ++ } ++ ++ return &cache->sym[ent]; ++} ++ ++/* Given an ELF section number, retrieve the corresponding BFD ++ section. */ ++ ++asection * ++bfd_section_from_elf_index (bfd *abfd, unsigned int sec_index) ++{ ++ if (sec_index >= elf_numsections (abfd)) ++ return NULL; ++ return elf_elfsections (abfd)[sec_index]->bfd_section; ++} ++ ++static const struct bfd_elf_special_section special_sections_b[] = ++{ ++ { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_c[] = ++{ ++ { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".ctf"), 0, SHT_PROGBITS, 0 }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_d[] = ++{ ++ { STRING_COMMA_LEN (".data"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".data1"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, ++ /* There are more DWARF sections than these, but they needn't be added here ++ unless you have to cope with broken compilers that don't emit section ++ attributes or you want to help the user writing assembler. */ ++ { STRING_COMMA_LEN (".debug"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".debug_line"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".debug_info"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".debug_abbrev"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".dynamic"), 0, SHT_DYNAMIC, SHF_ALLOC }, ++ { STRING_COMMA_LEN (".dynstr"), 0, SHT_STRTAB, SHF_ALLOC }, ++ { STRING_COMMA_LEN (".dynsym"), 0, SHT_DYNSYM, SHF_ALLOC }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_f[] = ++{ ++ { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, ++ { STRING_COMMA_LEN (".fini_array"), -2, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE }, ++ { NULL, 0 , 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_g[] = ++{ ++ { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".gnu.linkonce.n"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".gnu.linkonce.p"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".gnu.lto_"), -1, SHT_PROGBITS, SHF_EXCLUDE }, ++ { STRING_COMMA_LEN (".got"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".gnu.version"), 0, SHT_GNU_versym, 0 }, ++ { STRING_COMMA_LEN (".gnu.version_d"), 0, SHT_GNU_verdef, 0 }, ++ { STRING_COMMA_LEN (".gnu.version_r"), 0, SHT_GNU_verneed, 0 }, ++ { STRING_COMMA_LEN (".gnu.liblist"), 0, SHT_GNU_LIBLIST, SHF_ALLOC }, ++ { STRING_COMMA_LEN (".gnu.conflict"), 0, SHT_RELA, SHF_ALLOC }, ++ { STRING_COMMA_LEN (".gnu.hash"), 0, SHT_GNU_HASH, SHF_ALLOC }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_h[] = ++{ ++ { STRING_COMMA_LEN (".hash"), 0, SHT_HASH, SHF_ALLOC }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_i[] = ++{ ++ { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, ++ { STRING_COMMA_LEN (".init_array"), -2, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".interp"), 0, SHT_PROGBITS, 0 }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_l[] = ++{ ++ { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_n[] = ++{ ++ { STRING_COMMA_LEN (".noinit"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".note"), -1, SHT_NOTE, 0 }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_p[] = ++{ ++ { STRING_COMMA_LEN (".persistent.bss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".persistent"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".preinit_array"), -2, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE }, ++ { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_r[] = ++{ ++ { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC }, ++ { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC }, ++ { STRING_COMMA_LEN (".relr.dyn"), 0, SHT_RELR, SHF_ALLOC }, ++ { STRING_COMMA_LEN (".rela"), -1, SHT_RELA, 0 }, ++ { STRING_COMMA_LEN (".rel"), -1, SHT_REL, 0 }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_s[] = ++{ ++ { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 }, ++ { STRING_COMMA_LEN (".strtab"), 0, SHT_STRTAB, 0 }, ++ { STRING_COMMA_LEN (".symtab"), 0, SHT_SYMTAB, 0 }, ++ /* See struct bfd_elf_special_section declaration for the semantics of ++ this special case where .prefix_length != strlen (.prefix). */ ++ { ".stabstr", 5, 3, SHT_STRTAB, 0 }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_t[] = ++{ ++ { STRING_COMMA_LEN (".text"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, ++ { STRING_COMMA_LEN (".tbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, ++ { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section special_sections_z[] = ++{ ++ { STRING_COMMA_LEN (".zdebug_line"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".zdebug_info"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".zdebug_abbrev"), 0, SHT_PROGBITS, 0 }, ++ { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 }, ++ { NULL, 0, 0, 0, 0 } ++}; ++ ++static const struct bfd_elf_special_section * const special_sections[] = ++{ ++ special_sections_b, /* 'b' */ ++ special_sections_c, /* 'c' */ ++ special_sections_d, /* 'd' */ ++ NULL, /* 'e' */ ++ special_sections_f, /* 'f' */ ++ special_sections_g, /* 'g' */ ++ special_sections_h, /* 'h' */ ++ special_sections_i, /* 'i' */ ++ NULL, /* 'j' */ ++ NULL, /* 'k' */ ++ special_sections_l, /* 'l' */ ++ NULL, /* 'm' */ ++ special_sections_n, /* 'n' */ ++ NULL, /* 'o' */ ++ special_sections_p, /* 'p' */ ++ NULL, /* 'q' */ ++ special_sections_r, /* 'r' */ ++ special_sections_s, /* 's' */ ++ special_sections_t, /* 't' */ ++ NULL, /* 'u' */ ++ NULL, /* 'v' */ ++ NULL, /* 'w' */ ++ NULL, /* 'x' */ ++ NULL, /* 'y' */ ++ special_sections_z /* 'z' */ ++}; ++ ++const struct bfd_elf_special_section * ++_bfd_elf_get_special_section (const char *name, ++ const struct bfd_elf_special_section *spec, ++ unsigned int rela) ++{ ++ int i; ++ int len; ++ ++ len = strlen (name); ++ ++ for (i = 0; spec[i].prefix != NULL; i++) ++ { ++ int suffix_len; ++ int prefix_len = spec[i].prefix_length; ++ ++ if (len < prefix_len) ++ continue; ++ if (memcmp (name, spec[i].prefix, prefix_len) != 0) ++ continue; ++ ++ suffix_len = spec[i].suffix_length; ++ if (suffix_len <= 0) ++ { ++ if (name[prefix_len] != 0) ++ { ++ if (suffix_len == 0) ++ continue; ++ if (name[prefix_len] != '.' ++ && (suffix_len == -2 ++ || (rela && spec[i].type == SHT_REL))) ++ continue; ++ } ++ } ++ else ++ { ++ if (len < prefix_len + suffix_len) ++ continue; ++ if (memcmp (name + len - suffix_len, ++ spec[i].prefix + prefix_len, ++ suffix_len) != 0) ++ continue; ++ } ++ return &spec[i]; ++ } ++ ++ return NULL; ++} ++ ++const struct bfd_elf_special_section * ++_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec) ++{ ++ int i; ++ const struct bfd_elf_special_section *spec; ++ const struct elf_backend_data *bed; ++ ++ /* See if this is one of the special sections. */ ++ if (sec->name == NULL) ++ return NULL; ++ ++ bed = get_elf_backend_data (abfd); ++ spec = bed->special_sections; ++ if (spec) ++ { ++ spec = _bfd_elf_get_special_section (sec->name, ++ bed->special_sections, ++ sec->use_rela_p); ++ if (spec != NULL) ++ return spec; ++ } ++ ++ if (sec->name[0] != '.') ++ return NULL; ++ ++ i = sec->name[1] - 'b'; ++ if (i < 0 || i > 'z' - 'b') ++ return NULL; ++ ++ spec = special_sections[i]; ++ ++ if (spec == NULL) ++ return NULL; ++ ++ return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p); ++} ++ ++bool ++_bfd_elf_new_section_hook (bfd *abfd, asection *sec) ++{ ++ struct bfd_elf_section_data *sdata; ++ const struct elf_backend_data *bed; ++ const struct bfd_elf_special_section *ssect; ++ ++ sdata = (struct bfd_elf_section_data *) sec->used_by_bfd; ++ if (sdata == NULL) ++ { ++ sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, ++ sizeof (*sdata)); ++ if (sdata == NULL) ++ return false; ++ sec->used_by_bfd = sdata; ++ } ++ ++ /* Indicate whether or not this section should use RELA relocations. */ ++ bed = get_elf_backend_data (abfd); ++ sec->use_rela_p = bed->default_use_rela_p; ++ ++ /* Set up ELF section type and flags for newly created sections, if ++ there is an ABI mandated section. */ ++ ssect = (*bed->get_sec_type_attr) (abfd, sec); ++ if (ssect != NULL) ++ { ++ elf_section_type (sec) = ssect->type; ++ elf_section_flags (sec) = ssect->attr; ++ } ++ ++ return _bfd_generic_new_section_hook (abfd, sec); ++} ++ ++/* Create a new bfd section from an ELF program header. ++ ++ Since program segments have no names, we generate a synthetic name ++ of the form segment, where NUM is generally the index in the ++ program header table. For segments that are split (see below) we ++ generate the names segmenta and segmentb. ++ ++ Note that some program segments may have a file size that is different than ++ (less than) the memory size. All this means is that at execution the ++ system must allocate the amount of memory specified by the memory size, ++ but only initialize it with the first "file size" bytes read from the ++ file. This would occur for example, with program segments consisting ++ of combined data+bss. ++ ++ To handle the above situation, this routine generates TWO bfd sections ++ for the single program segment. The first has the length specified by ++ the file size of the segment, and the second has the length specified ++ by the difference between the two sizes. In effect, the segment is split ++ into its initialized and uninitialized parts. */ ++ ++bool ++_bfd_elf_make_section_from_phdr (bfd *abfd, ++ Elf_Internal_Phdr *hdr, ++ int hdr_index, ++ const char *type_name) ++{ ++ asection *newsect; ++ char *name; ++ char namebuf[64]; ++ size_t len; ++ int split; ++ unsigned int opb = bfd_octets_per_byte (abfd, NULL); ++ ++ split = ((hdr->p_memsz > 0) ++ && (hdr->p_filesz > 0) ++ && (hdr->p_memsz > hdr->p_filesz)); ++ ++ if (hdr->p_filesz > 0) ++ { ++ sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "a" : ""); ++ len = strlen (namebuf) + 1; ++ name = (char *) bfd_alloc (abfd, len); ++ if (!name) ++ return false; ++ memcpy (name, namebuf, len); ++ newsect = bfd_make_section (abfd, name); ++ if (newsect == NULL) ++ return false; ++ newsect->vma = hdr->p_vaddr / opb; ++ newsect->lma = hdr->p_paddr / opb; ++ newsect->size = hdr->p_filesz; ++ newsect->filepos = hdr->p_offset; ++ newsect->flags |= SEC_HAS_CONTENTS; ++ newsect->alignment_power = bfd_log2 (hdr->p_align); ++ if (hdr->p_type == PT_LOAD) ++ { ++ newsect->flags |= SEC_ALLOC; ++ newsect->flags |= SEC_LOAD; ++ if (hdr->p_flags & PF_X) ++ { ++ /* FIXME: all we known is that it has execute PERMISSION, ++ may be data. */ ++ newsect->flags |= SEC_CODE; ++ } ++ } ++ if (!(hdr->p_flags & PF_W)) ++ { ++ newsect->flags |= SEC_READONLY; ++ } ++ } ++ ++ if (hdr->p_memsz > hdr->p_filesz) ++ { ++ bfd_vma align; ++ ++ sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "b" : ""); ++ len = strlen (namebuf) + 1; ++ name = (char *) bfd_alloc (abfd, len); ++ if (!name) ++ return false; ++ memcpy (name, namebuf, len); ++ newsect = bfd_make_section (abfd, name); ++ if (newsect == NULL) ++ return false; ++ newsect->vma = (hdr->p_vaddr + hdr->p_filesz) / opb; ++ newsect->lma = (hdr->p_paddr + hdr->p_filesz) / opb; ++ newsect->size = hdr->p_memsz - hdr->p_filesz; ++ newsect->filepos = hdr->p_offset + hdr->p_filesz; ++ align = newsect->vma & -newsect->vma; ++ if (align == 0 || align > hdr->p_align) ++ align = hdr->p_align; ++ newsect->alignment_power = bfd_log2 (align); ++ if (hdr->p_type == PT_LOAD) ++ { ++ newsect->flags |= SEC_ALLOC; ++ if (hdr->p_flags & PF_X) ++ newsect->flags |= SEC_CODE; ++ } ++ if (!(hdr->p_flags & PF_W)) ++ newsect->flags |= SEC_READONLY; ++ } ++ ++ return true; ++} ++ ++static bool ++_bfd_elf_core_find_build_id (bfd *templ, bfd_vma offset) ++{ ++ /* The return value is ignored. Build-ids are considered optional. */ ++ if (templ->xvec->flavour == bfd_target_elf_flavour) ++ return (*get_elf_backend_data (templ)->elf_backend_core_find_build_id) ++ (templ, offset); ++ return false; ++} ++ ++bool ++bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index) ++{ ++ const struct elf_backend_data *bed; ++ ++ switch (hdr->p_type) ++ { ++ case PT_NULL: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "null"); ++ ++ case PT_LOAD: ++ if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "load")) ++ return false; ++ if (bfd_get_format (abfd) == bfd_core && abfd->build_id == NULL) ++ _bfd_elf_core_find_build_id (abfd, hdr->p_offset); ++ return true; ++ ++ case PT_DYNAMIC: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "dynamic"); ++ ++ case PT_INTERP: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "interp"); ++ ++ case PT_NOTE: ++ if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note")) ++ return false; ++ if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz, ++ hdr->p_align)) ++ return false; ++ return true; ++ ++ case PT_SHLIB: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "shlib"); ++ ++ case PT_PHDR: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "phdr"); ++ ++ case PT_GNU_EH_FRAME: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, ++ "eh_frame_hdr"); ++ ++ case PT_GNU_STACK: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "stack"); ++ ++ case PT_GNU_RELRO: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "relro"); ++ ++ case PT_GNU_SFRAME: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, ++ "sframe"); ++ ++ default: ++ /* Check for any processor-specific program segment types. */ ++ bed = get_elf_backend_data (abfd); ++ return bed->elf_backend_section_from_phdr (abfd, hdr, hdr_index, "proc"); ++ } ++} ++ ++/* Return the REL_HDR for SEC, assuming there is only a single one, either ++ REL or RELA. */ ++ ++Elf_Internal_Shdr * ++_bfd_elf_single_rel_hdr (asection *sec) ++{ ++ if (elf_section_data (sec)->rel.hdr) ++ { ++ BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL); ++ return elf_section_data (sec)->rel.hdr; ++ } ++ else ++ return elf_section_data (sec)->rela.hdr; ++} ++ ++static bool ++_bfd_elf_set_reloc_sh_name (bfd *abfd, ++ Elf_Internal_Shdr *rel_hdr, ++ const char *sec_name, ++ bool use_rela_p) ++{ ++ char *name = (char *) bfd_alloc (abfd, ++ sizeof ".rela" + strlen (sec_name)); ++ if (name == NULL) ++ return false; ++ ++ sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", sec_name); ++ rel_hdr->sh_name = ++ (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name, ++ false); ++ if (rel_hdr->sh_name == (unsigned int) -1) ++ return false; ++ ++ return true; ++} ++ ++/* Allocate and initialize a section-header for a new reloc section, ++ containing relocations against ASECT. It is stored in RELDATA. If ++ USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL ++ relocations. */ ++ ++static bool ++_bfd_elf_init_reloc_shdr (bfd *abfd, ++ struct bfd_elf_section_reloc_data *reldata, ++ const char *sec_name, ++ bool use_rela_p, ++ bool delay_st_name_p) ++{ ++ Elf_Internal_Shdr *rel_hdr; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ BFD_ASSERT (reldata->hdr == NULL); ++ rel_hdr = bfd_zalloc (abfd, sizeof (*rel_hdr)); ++ reldata->hdr = rel_hdr; ++ ++ if (delay_st_name_p) ++ rel_hdr->sh_name = (unsigned int) -1; ++ else if (!_bfd_elf_set_reloc_sh_name (abfd, rel_hdr, sec_name, ++ use_rela_p)) ++ return false; ++ rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL; ++ rel_hdr->sh_entsize = (use_rela_p ++ ? bed->s->sizeof_rela ++ : bed->s->sizeof_rel); ++ rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; ++ rel_hdr->sh_flags = 0; ++ rel_hdr->sh_addr = 0; ++ rel_hdr->sh_size = 0; ++ rel_hdr->sh_offset = 0; ++ ++ return true; ++} ++ ++/* Return the default section type based on the passed in section flags. */ ++ ++int ++bfd_elf_get_default_section_type (flagword flags) ++{ ++ if ((flags & (SEC_ALLOC | SEC_IS_COMMON)) != 0 ++ && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) ++ return SHT_NOBITS; ++ return SHT_PROGBITS; ++} ++ ++struct fake_section_arg ++{ ++ struct bfd_link_info *link_info; ++ bool failed; ++}; ++ ++/* Set up an ELF internal section header for a section. */ ++ ++static void ++elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) ++{ ++ struct fake_section_arg *arg = (struct fake_section_arg *)fsarg; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct bfd_elf_section_data *esd = elf_section_data (asect); ++ Elf_Internal_Shdr *this_hdr; ++ unsigned int sh_type; ++ const char *name = asect->name; ++ bool delay_st_name_p = false; ++ bfd_vma mask; ++ ++ if (arg->failed) ++ { ++ /* We already failed; just get out of the bfd_map_over_sections ++ loop. */ ++ return; ++ } ++ ++ this_hdr = &esd->this_hdr; ++ ++ /* ld: compress DWARF debug sections with names: .debug_*. */ ++ if (arg->link_info ++ && (abfd->flags & BFD_COMPRESS) != 0 ++ && (asect->flags & SEC_DEBUGGING) != 0 ++ && name[1] == 'd' ++ && name[6] == '_') ++ { ++ /* If this section will be compressed, delay adding section ++ name to section name section after it is compressed in ++ _bfd_elf_assign_file_positions_for_non_load. */ ++ delay_st_name_p = true; ++ } ++ ++ if (delay_st_name_p) ++ this_hdr->sh_name = (unsigned int) -1; ++ else ++ { ++ this_hdr->sh_name ++ = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), ++ name, false); ++ if (this_hdr->sh_name == (unsigned int) -1) ++ { ++ arg->failed = true; ++ return; ++ } ++ } ++ ++ /* Don't clear sh_flags. Assembler may set additional bits. */ ++ ++ if ((asect->flags & SEC_ALLOC) != 0 ++ || asect->user_set_vma) ++ this_hdr->sh_addr = asect->vma * bfd_octets_per_byte (abfd, asect); ++ else ++ this_hdr->sh_addr = 0; ++ ++ this_hdr->sh_offset = 0; ++ this_hdr->sh_size = asect->size; ++ this_hdr->sh_link = 0; ++ /* PR 17512: file: 0eb809fe, 8b0535ee. */ ++ if (asect->alignment_power >= (sizeof (bfd_vma) * 8) - 1) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: error: alignment power %d of section `%pA' is too big"), ++ abfd, asect->alignment_power, asect); ++ arg->failed = true; ++ return; ++ } ++ /* Set sh_addralign to the highest power of two given by alignment ++ consistent with the section VMA. Linker scripts can force VMA. */ ++ mask = ((bfd_vma) 1 << asect->alignment_power) | this_hdr->sh_addr; ++ this_hdr->sh_addralign = mask & -mask; ++ /* The sh_entsize and sh_info fields may have been set already by ++ copy_private_section_data. */ ++ ++ this_hdr->bfd_section = asect; ++ this_hdr->contents = NULL; ++ ++ /* If the section type is unspecified, we set it based on ++ asect->flags. */ ++ if (asect->type != 0) ++ sh_type = asect->type; ++ else if ((asect->flags & SEC_GROUP) != 0) ++ sh_type = SHT_GROUP; ++ else ++ sh_type = bfd_elf_get_default_section_type (asect->flags); ++ ++ if (this_hdr->sh_type == SHT_NULL) ++ this_hdr->sh_type = sh_type; ++ else if (this_hdr->sh_type == SHT_NOBITS ++ && sh_type == SHT_PROGBITS ++ && (asect->flags & SEC_ALLOC) != 0) ++ { ++ /* Warn if we are changing a NOBITS section to PROGBITS, but ++ allow the link to proceed. This can happen when users link ++ non-bss input sections to bss output sections, or emit data ++ to a bss output section via a linker script. */ ++ _bfd_error_handler ++ (_("warning: section `%pA' type changed to PROGBITS"), asect); ++ this_hdr->sh_type = sh_type; ++ } ++ ++ switch (this_hdr->sh_type) ++ { ++ default: ++ break; ++ ++ case SHT_STRTAB: ++ case SHT_NOTE: ++ case SHT_NOBITS: ++ case SHT_PROGBITS: ++ break; ++ ++ case SHT_INIT_ARRAY: ++ case SHT_FINI_ARRAY: ++ case SHT_PREINIT_ARRAY: ++ this_hdr->sh_entsize = bed->s->arch_size / 8; ++ break; ++ ++ case SHT_HASH: ++ this_hdr->sh_entsize = bed->s->sizeof_hash_entry; ++ break; ++ ++ case SHT_DYNSYM: ++ this_hdr->sh_entsize = bed->s->sizeof_sym; ++ break; ++ ++ case SHT_DYNAMIC: ++ this_hdr->sh_entsize = bed->s->sizeof_dyn; ++ break; ++ ++ case SHT_RELA: ++ if (get_elf_backend_data (abfd)->may_use_rela_p) ++ this_hdr->sh_entsize = bed->s->sizeof_rela; ++ break; ++ ++ case SHT_REL: ++ if (get_elf_backend_data (abfd)->may_use_rel_p) ++ this_hdr->sh_entsize = bed->s->sizeof_rel; ++ break; ++ ++ case SHT_GNU_versym: ++ this_hdr->sh_entsize = sizeof (Elf_External_Versym); ++ break; ++ ++ case SHT_GNU_verdef: ++ this_hdr->sh_entsize = 0; ++ /* objcopy or strip will copy over sh_info, but may not set ++ cverdefs. The linker will set cverdefs, but sh_info will be ++ zero. */ ++ if (this_hdr->sh_info == 0) ++ this_hdr->sh_info = elf_tdata (abfd)->cverdefs; ++ else ++ BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0 ++ || this_hdr->sh_info == elf_tdata (abfd)->cverdefs); ++ break; ++ ++ case SHT_GNU_verneed: ++ this_hdr->sh_entsize = 0; ++ /* objcopy or strip will copy over sh_info, but may not set ++ cverrefs. The linker will set cverrefs, but sh_info will be ++ zero. */ ++ if (this_hdr->sh_info == 0) ++ this_hdr->sh_info = elf_tdata (abfd)->cverrefs; ++ else ++ BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0 ++ || this_hdr->sh_info == elf_tdata (abfd)->cverrefs); ++ break; ++ ++ case SHT_GROUP: ++ this_hdr->sh_entsize = GRP_ENTRY_SIZE; ++ break; ++ ++ case SHT_GNU_HASH: ++ this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4; ++ break; ++ } ++ ++ if ((asect->flags & SEC_ALLOC) != 0) ++ this_hdr->sh_flags |= SHF_ALLOC; ++ if ((asect->flags & SEC_READONLY) == 0) ++ this_hdr->sh_flags |= SHF_WRITE; ++ if ((asect->flags & SEC_CODE) != 0) ++ this_hdr->sh_flags |= SHF_EXECINSTR; ++ if ((asect->flags & SEC_MERGE) != 0) ++ { ++ this_hdr->sh_flags |= SHF_MERGE; ++ this_hdr->sh_entsize = asect->entsize; ++ } ++ if ((asect->flags & SEC_STRINGS) != 0) ++ this_hdr->sh_flags |= SHF_STRINGS; ++ if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL) ++ this_hdr->sh_flags |= SHF_GROUP; ++ if ((asect->flags & SEC_THREAD_LOCAL) != 0) ++ { ++ this_hdr->sh_flags |= SHF_TLS; ++ if (asect->size == 0 ++ && (asect->flags & SEC_HAS_CONTENTS) == 0) ++ { ++ struct bfd_link_order *o = asect->map_tail.link_order; ++ ++ this_hdr->sh_size = 0; ++ if (o != NULL) ++ { ++ this_hdr->sh_size = o->offset + o->size; ++ if (this_hdr->sh_size != 0) ++ this_hdr->sh_type = SHT_NOBITS; ++ } ++ } ++ } ++ if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE) ++ this_hdr->sh_flags |= SHF_EXCLUDE; ++ ++ /* If the section has relocs, set up a section header for the ++ SHT_REL[A] section. If two relocation sections are required for ++ this section, it is up to the processor-specific back-end to ++ create the other. */ ++ if ((asect->flags & SEC_RELOC) != 0) ++ { ++ /* When doing a relocatable link, create both REL and RELA sections if ++ needed. */ ++ if (arg->link_info ++ /* Do the normal setup if we wouldn't create any sections here. */ ++ && esd->rel.count + esd->rela.count > 0 ++ && (bfd_link_relocatable (arg->link_info) ++ || arg->link_info->emitrelocations)) ++ { ++ if (esd->rel.count && esd->rel.hdr == NULL ++ && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, name, ++ false, delay_st_name_p)) ++ { ++ arg->failed = true; ++ return; ++ } ++ if (esd->rela.count && esd->rela.hdr == NULL ++ && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, name, ++ true, delay_st_name_p)) ++ { ++ arg->failed = true; ++ return; ++ } ++ } ++ else if (!_bfd_elf_init_reloc_shdr (abfd, ++ (asect->use_rela_p ++ ? &esd->rela : &esd->rel), ++ name, ++ asect->use_rela_p, ++ delay_st_name_p)) ++ { ++ arg->failed = true; ++ return; ++ } ++ } ++ ++ /* Check for processor-specific section types. */ ++ sh_type = this_hdr->sh_type; ++ if (bed->elf_backend_fake_sections ++ && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect)) ++ { ++ arg->failed = true; ++ return; ++ } ++ ++ if (sh_type == SHT_NOBITS && asect->size != 0) ++ { ++ /* Don't change the header type from NOBITS if we are being ++ called for objcopy --only-keep-debug. */ ++ this_hdr->sh_type = sh_type; ++ } ++} ++ ++/* Fill in the contents of a SHT_GROUP section. Called from ++ _bfd_elf_compute_section_file_positions for gas, objcopy, and ++ when ELF targets use the generic linker, ld. Called for ld -r ++ from bfd_elf_final_link. */ ++ ++void ++bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) ++{ ++ bool *failedptr = (bool *) failedptrarg; ++ asection *elt, *first; ++ unsigned char *loc; ++ bool gas; ++ ++ /* Ignore linker created group section. See elfNN_ia64_object_p in ++ elfxx-ia64.c. */ ++ if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP ++ || sec->size == 0 ++ || *failedptr) ++ return; ++ ++ if (elf_section_data (sec)->this_hdr.sh_info == 0) ++ { ++ unsigned long symindx = 0; ++ ++ /* elf_group_id will have been set up by objcopy and the ++ generic linker. */ ++ if (elf_group_id (sec) != NULL) ++ symindx = elf_group_id (sec)->udata.i; ++ ++ if (symindx == 0) ++ { ++ /* If called from the assembler, swap_out_syms will have set up ++ elf_section_syms. ++ PR 25699: A corrupt input file could contain bogus group info. */ ++ if (sec->index >= elf_num_section_syms (abfd) ++ || elf_section_syms (abfd)[sec->index] == NULL) ++ { ++ *failedptr = true; ++ return; ++ } ++ symindx = elf_section_syms (abfd)[sec->index]->udata.i; ++ } ++ elf_section_data (sec)->this_hdr.sh_info = symindx; ++ } ++ else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2) ++ { ++ /* The ELF backend linker sets sh_info to -2 when the group ++ signature symbol is global, and thus the index can't be ++ set until all local symbols are output. */ ++ asection *igroup; ++ struct bfd_elf_section_data *sec_data; ++ unsigned long symndx; ++ unsigned long extsymoff; ++ struct elf_link_hash_entry *h; ++ ++ /* The point of this little dance to the first SHF_GROUP section ++ then back to the SHT_GROUP section is that this gets us to ++ the SHT_GROUP in the input object. */ ++ igroup = elf_sec_group (elf_next_in_group (sec)); ++ sec_data = elf_section_data (igroup); ++ symndx = sec_data->this_hdr.sh_info; ++ extsymoff = 0; ++ if (!elf_bad_symtab (igroup->owner)) ++ { ++ Elf_Internal_Shdr *symtab_hdr; ++ ++ symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr; ++ extsymoff = symtab_hdr->sh_info; ++ } ++ h = elf_sym_hashes (igroup->owner)[symndx - extsymoff]; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ elf_section_data (sec)->this_hdr.sh_info = h->indx; ++ } ++ ++ /* The contents won't be allocated for "ld -r" or objcopy. */ ++ gas = true; ++ if (sec->contents == NULL) ++ { ++ gas = false; ++ sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size); ++ ++ /* Arrange for the section to be written out. */ ++ elf_section_data (sec)->this_hdr.contents = sec->contents; ++ if (sec->contents == NULL) ++ { ++ *failedptr = true; ++ return; ++ } ++ } ++ ++ loc = sec->contents + sec->size; ++ ++ /* Get the pointer to the first section in the group that gas ++ squirreled away here. objcopy arranges for this to be set to the ++ start of the input section group. */ ++ first = elt = elf_next_in_group (sec); ++ ++ /* First element is a flag word. Rest of section is elf section ++ indices for all the sections of the group. Write them backwards ++ just to keep the group in the same order as given in .section ++ directives, not that it matters. */ ++ while (elt != NULL) ++ { ++ asection *s; ++ ++ s = elt; ++ if (!gas) ++ s = s->output_section; ++ if (s != NULL ++ && !bfd_is_abs_section (s)) ++ { ++ struct bfd_elf_section_data *elf_sec = elf_section_data (s); ++ struct bfd_elf_section_data *input_elf_sec = elf_section_data (elt); ++ ++ if (elf_sec->rel.hdr != NULL ++ && (gas ++ || (input_elf_sec->rel.hdr != NULL ++ && input_elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)) ++ { ++ elf_sec->rel.hdr->sh_flags |= SHF_GROUP; ++ loc -= 4; ++ if (loc == sec->contents) ++ break; ++ H_PUT_32 (abfd, elf_sec->rel.idx, loc); ++ } ++ if (elf_sec->rela.hdr != NULL ++ && (gas ++ || (input_elf_sec->rela.hdr != NULL ++ && input_elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)) ++ { ++ elf_sec->rela.hdr->sh_flags |= SHF_GROUP; ++ loc -= 4; ++ if (loc == sec->contents) ++ break; ++ H_PUT_32 (abfd, elf_sec->rela.idx, loc); ++ } ++ loc -= 4; ++ if (loc == sec->contents) ++ break; ++ H_PUT_32 (abfd, elf_sec->this_idx, loc); ++ } ++ elt = elf_next_in_group (elt); ++ if (elt == first) ++ break; ++ } ++ ++ /* We should always get here with loc == sec->contents + 4, but it is ++ possible to craft bogus SHT_GROUP sections that will cause segfaults ++ in objcopy without checking loc here and in the loop above. */ ++ if (loc == sec->contents) ++ BFD_ASSERT (0); ++ else ++ { ++ loc -= 4; ++ if (loc != sec->contents) ++ { ++ BFD_ASSERT (0); ++ memset (sec->contents + 4, 0, loc - sec->contents); ++ loc = sec->contents; ++ } ++ } ++ ++ H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc); ++} ++ ++/* Given NAME, the name of a relocation section stripped of its ++ .rel/.rela prefix, return the section in ABFD to which the ++ relocations apply. */ ++ ++asection * ++_bfd_elf_plt_get_reloc_section (bfd *abfd, const char *name) ++{ ++ /* If a target needs .got.plt section, relocations in rela.plt/rel.plt ++ section likely apply to .got.plt or .got section. */ ++ if (get_elf_backend_data (abfd)->want_got_plt ++ && strcmp (name, ".plt") == 0) ++ { ++ asection *sec; ++ ++ name = ".got.plt"; ++ sec = bfd_get_section_by_name (abfd, name); ++ if (sec != NULL) ++ return sec; ++ name = ".got"; ++ } ++ ++ return bfd_get_section_by_name (abfd, name); ++} ++ ++/* Return the section to which RELOC_SEC applies. */ ++ ++static asection * ++elf_get_reloc_section (asection *reloc_sec) ++{ ++ const char *name; ++ unsigned int type; ++ bfd *abfd; ++ const struct elf_backend_data *bed; ++ ++ type = elf_section_data (reloc_sec)->this_hdr.sh_type; ++ if (type != SHT_REL && type != SHT_RELA) ++ return NULL; ++ ++ /* We look up the section the relocs apply to by name. */ ++ name = reloc_sec->name; ++ if (!startswith (name, ".rel")) ++ return NULL; ++ name += 4; ++ if (type == SHT_RELA && *name++ != 'a') ++ return NULL; ++ ++ abfd = reloc_sec->owner; ++ bed = get_elf_backend_data (abfd); ++ return bed->get_reloc_section (abfd, name); ++} ++ ++/* Assign all ELF section numbers. The dummy first section is handled here ++ too. The link/info pointers for the standard section types are filled ++ in here too, while we're at it. LINK_INFO will be 0 when arriving ++ here for gas, objcopy, and when using the generic ELF linker. */ ++ ++static bool ++assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) ++{ ++ struct elf_obj_tdata *t = elf_tdata (abfd); ++ asection *sec; ++ unsigned int section_number; ++ Elf_Internal_Shdr **i_shdrp; ++ struct bfd_elf_section_data *d; ++ bool need_symtab; ++ size_t amt; ++ ++ section_number = 1; ++ ++ _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd)); ++ ++ /* SHT_GROUP sections are in relocatable files only. */ ++ if (link_info == NULL || !link_info->resolve_section_groups) ++ { ++ size_t reloc_count = 0; ++ ++ /* Put SHT_GROUP sections first. */ ++ for (sec = abfd->sections; sec != NULL; sec = sec->next) ++ { ++ d = elf_section_data (sec); ++ ++ if (d->this_hdr.sh_type == SHT_GROUP) ++ { ++ if (sec->flags & SEC_LINKER_CREATED) ++ { ++ /* Remove the linker created SHT_GROUP sections. */ ++ bfd_section_list_remove (abfd, sec); ++ abfd->section_count--; ++ } ++ else ++ d->this_idx = section_number++; ++ } ++ ++ /* Count relocations. */ ++ reloc_count += sec->reloc_count; ++ } ++ ++ /* Set/clear HAS_RELOC depending on whether there are relocations. */ ++ if (reloc_count == 0) ++ abfd->flags &= ~HAS_RELOC; ++ else ++ abfd->flags |= HAS_RELOC; ++ } ++ ++ for (sec = abfd->sections; sec; sec = sec->next) ++ { ++ d = elf_section_data (sec); ++ ++ if (d->this_hdr.sh_type != SHT_GROUP) ++ d->this_idx = section_number++; ++ if (d->this_hdr.sh_name != (unsigned int) -1) ++ _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name); ++ if (d->rel.hdr) ++ { ++ d->rel.idx = section_number++; ++ if (d->rel.hdr->sh_name != (unsigned int) -1) ++ _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name); ++ } ++ else ++ d->rel.idx = 0; ++ ++ if (d->rela.hdr) ++ { ++ d->rela.idx = section_number++; ++ if (d->rela.hdr->sh_name != (unsigned int) -1) ++ _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name); ++ } ++ else ++ d->rela.idx = 0; ++ } ++ ++ need_symtab = (bfd_get_symcount (abfd) > 0 ++ || (link_info == NULL ++ && ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC)) ++ == HAS_RELOC))); ++ if (need_symtab) ++ { ++ elf_onesymtab (abfd) = section_number++; ++ _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name); ++ if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF)) ++ { ++ elf_section_list *entry; ++ ++ BFD_ASSERT (elf_symtab_shndx_list (abfd) == NULL); ++ ++ entry = bfd_zalloc (abfd, sizeof (*entry)); ++ entry->ndx = section_number++; ++ elf_symtab_shndx_list (abfd) = entry; ++ entry->hdr.sh_name ++ = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), ++ ".symtab_shndx", false); ++ if (entry->hdr.sh_name == (unsigned int) -1) ++ return false; ++ } ++ elf_strtab_sec (abfd) = section_number++; ++ _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name); ++ } ++ ++ elf_shstrtab_sec (abfd) = section_number++; ++ _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name); ++ elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd); ++ ++ if (section_number >= SHN_LORESERVE) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: too many sections: %u"), ++ abfd, section_number); ++ return false; ++ } ++ ++ elf_numsections (abfd) = section_number; ++ elf_elfheader (abfd)->e_shnum = section_number; ++ ++ /* Set up the list of section header pointers, in agreement with the ++ indices. */ ++ amt = section_number * sizeof (Elf_Internal_Shdr *); ++ i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt); ++ if (i_shdrp == NULL) ++ return false; ++ ++ i_shdrp[0] = (Elf_Internal_Shdr *) bfd_zalloc (abfd, ++ sizeof (Elf_Internal_Shdr)); ++ if (i_shdrp[0] == NULL) ++ { ++ bfd_release (abfd, i_shdrp); ++ return false; ++ } ++ ++ elf_elfsections (abfd) = i_shdrp; ++ ++ i_shdrp[elf_shstrtab_sec (abfd)] = &t->shstrtab_hdr; ++ if (need_symtab) ++ { ++ i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr; ++ if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)) ++ { ++ elf_section_list * entry = elf_symtab_shndx_list (abfd); ++ BFD_ASSERT (entry != NULL); ++ i_shdrp[entry->ndx] = & entry->hdr; ++ entry->hdr.sh_link = elf_onesymtab (abfd); ++ } ++ i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr; ++ t->symtab_hdr.sh_link = elf_strtab_sec (abfd); ++ } ++ ++ for (sec = abfd->sections; sec; sec = sec->next) ++ { ++ asection *s; ++ ++ d = elf_section_data (sec); ++ ++ i_shdrp[d->this_idx] = &d->this_hdr; ++ if (d->rel.idx != 0) ++ i_shdrp[d->rel.idx] = d->rel.hdr; ++ if (d->rela.idx != 0) ++ i_shdrp[d->rela.idx] = d->rela.hdr; ++ ++ /* Fill in the sh_link and sh_info fields while we're at it. */ ++ ++ /* sh_link of a reloc section is the section index of the symbol ++ table. sh_info is the section index of the section to which ++ the relocation entries apply. */ ++ if (d->rel.idx != 0) ++ { ++ d->rel.hdr->sh_link = elf_onesymtab (abfd); ++ d->rel.hdr->sh_info = d->this_idx; ++ d->rel.hdr->sh_flags |= SHF_INFO_LINK; ++ } ++ if (d->rela.idx != 0) ++ { ++ d->rela.hdr->sh_link = elf_onesymtab (abfd); ++ d->rela.hdr->sh_info = d->this_idx; ++ d->rela.hdr->sh_flags |= SHF_INFO_LINK; ++ } ++ ++ /* We need to set up sh_link for SHF_LINK_ORDER. */ ++ if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0) ++ { ++ s = elf_linked_to_section (sec); ++ /* We can now have a NULL linked section pointer. ++ This happens when the sh_link field is 0, which is done ++ when a linked to section is discarded but the linking ++ section has been retained for some reason. */ ++ if (s) ++ { ++ /* Check discarded linkonce section. */ ++ if (discarded_section (s)) ++ { ++ asection *kept; ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: sh_link of section `%pA' points to" ++ " discarded section `%pA' of `%pB'"), ++ abfd, d->this_hdr.bfd_section, s, s->owner); ++ /* Point to the kept section if it has the same ++ size as the discarded one. */ ++ kept = _bfd_elf_check_kept_section (s, link_info); ++ if (kept == NULL) ++ { ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ s = kept; ++ } ++ /* Handle objcopy. */ ++ else if (s->output_section == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: sh_link of section `%pA' points to" ++ " removed section `%pA' of `%pB'"), ++ abfd, d->this_hdr.bfd_section, s, s->owner); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ s = s->output_section; ++ d->this_hdr.sh_link = elf_section_data (s)->this_idx; ++ } ++ } ++ ++ switch (d->this_hdr.sh_type) ++ { ++ case SHT_REL: ++ case SHT_RELA: ++ /* sh_link is the section index of the symbol table. ++ sh_info is the section index of the section to which the ++ relocation entries apply. */ ++ if (d->this_hdr.sh_link == 0) ++ { ++ /* FIXME maybe: If this is a reloc section which we are ++ treating as a normal section then we likely should ++ not be assuming its sh_link is .dynsym or .symtab. */ ++ if ((sec->flags & SEC_ALLOC) != 0) ++ { ++ s = bfd_get_section_by_name (abfd, ".dynsym"); ++ if (s != NULL) ++ d->this_hdr.sh_link = elf_section_data (s)->this_idx; ++ } ++ else ++ d->this_hdr.sh_link = elf_onesymtab (abfd); ++ } ++ ++ s = elf_get_reloc_section (sec); ++ if (s != NULL) ++ { ++ d->this_hdr.sh_info = elf_section_data (s)->this_idx; ++ d->this_hdr.sh_flags |= SHF_INFO_LINK; ++ } ++ break; ++ ++ case SHT_STRTAB: ++ /* We assume that a section named .stab*str is a stabs ++ string section. We look for a section with the same name ++ but without the trailing ``str'', and set its sh_link ++ field to point to this section. */ ++ if (startswith (sec->name, ".stab") ++ && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0) ++ { ++ size_t len; ++ char *alc; ++ ++ len = strlen (sec->name); ++ alc = (char *) bfd_malloc (len - 2); ++ if (alc == NULL) ++ return false; ++ memcpy (alc, sec->name, len - 3); ++ alc[len - 3] = '\0'; ++ s = bfd_get_section_by_name (abfd, alc); ++ free (alc); ++ if (s != NULL) ++ { ++ elf_section_data (s)->this_hdr.sh_link = d->this_idx; ++ ++ /* This is a .stab section. */ ++ elf_section_data (s)->this_hdr.sh_entsize = 12; ++ } ++ } ++ break; ++ ++ case SHT_DYNAMIC: ++ case SHT_DYNSYM: ++ case SHT_GNU_verneed: ++ case SHT_GNU_verdef: ++ /* sh_link is the section header index of the string table ++ used for the dynamic entries, or the symbol table, or the ++ version strings. */ ++ s = bfd_get_section_by_name (abfd, ".dynstr"); ++ if (s != NULL) ++ d->this_hdr.sh_link = elf_section_data (s)->this_idx; ++ break; ++ ++ case SHT_GNU_LIBLIST: ++ /* sh_link is the section header index of the prelink library ++ list used for the dynamic entries, or the symbol table, or ++ the version strings. */ ++ s = bfd_get_section_by_name (abfd, ((sec->flags & SEC_ALLOC) ++ ? ".dynstr" : ".gnu.libstr")); ++ if (s != NULL) ++ d->this_hdr.sh_link = elf_section_data (s)->this_idx; ++ break; ++ ++ case SHT_HASH: ++ case SHT_GNU_HASH: ++ case SHT_GNU_versym: ++ /* sh_link is the section header index of the symbol table ++ this hash table or version table is for. */ ++ s = bfd_get_section_by_name (abfd, ".dynsym"); ++ if (s != NULL) ++ d->this_hdr.sh_link = elf_section_data (s)->this_idx; ++ break; ++ ++ case SHT_GROUP: ++ d->this_hdr.sh_link = elf_onesymtab (abfd); ++ } ++ } ++ ++ /* Delay setting sh_name to _bfd_elf_write_object_contents so that ++ _bfd_elf_assign_file_positions_for_non_load can convert DWARF ++ debug section name from .debug_* to .zdebug_* if needed. */ ++ ++ return true; ++} ++ ++static bool ++sym_is_global (bfd *abfd, asymbol *sym) ++{ ++ /* If the backend has a special mapping, use it. */ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ if (bed->elf_backend_sym_is_global) ++ return (*bed->elf_backend_sym_is_global) (abfd, sym); ++ ++ return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 ++ || bfd_is_und_section (bfd_asymbol_section (sym)) ++ || bfd_is_com_section (bfd_asymbol_section (sym))); ++} ++ ++/* Filter global symbols of ABFD to include in the import library. All ++ SYMCOUNT symbols of ABFD can be examined from their pointers in ++ SYMS. Pointers of symbols to keep should be stored contiguously at ++ the beginning of that array. ++ ++ Returns the number of symbols to keep. */ ++ ++unsigned int ++_bfd_elf_filter_global_symbols (bfd *abfd, struct bfd_link_info *info, ++ asymbol **syms, long symcount) ++{ ++ long src_count, dst_count = 0; ++ ++ for (src_count = 0; src_count < symcount; src_count++) ++ { ++ asymbol *sym = syms[src_count]; ++ char *name = (char *) bfd_asymbol_name (sym); ++ struct bfd_link_hash_entry *h; ++ ++ if (!sym_is_global (abfd, sym)) ++ continue; ++ ++ h = bfd_link_hash_lookup (info->hash, name, false, false, false); ++ if (h == NULL) ++ continue; ++ if (h->type != bfd_link_hash_defined && h->type != bfd_link_hash_defweak) ++ continue; ++ if (h->linker_def || h->ldscript_def) ++ continue; ++ ++ syms[dst_count++] = sym; ++ } ++ ++ syms[dst_count] = NULL; ++ ++ return dst_count; ++} ++ ++/* Don't output section symbols for sections that are not going to be ++ output, that are duplicates or there is no BFD section. */ ++ ++static bool ++ignore_section_sym (bfd *abfd, asymbol *sym) ++{ ++ elf_symbol_type *type_ptr; ++ ++ if (sym == NULL) ++ return false; ++ ++ if ((sym->flags & BSF_SECTION_SYM) == 0) ++ return false; ++ ++ /* Ignore the section symbol if it isn't used. */ ++ if ((sym->flags & BSF_SECTION_SYM_USED) == 0) ++ return true; ++ ++ if (sym->section == NULL) ++ return true; ++ ++ type_ptr = elf_symbol_from (sym); ++ return ((type_ptr != NULL ++ && type_ptr->internal_elf_sym.st_shndx != 0 ++ && bfd_is_abs_section (sym->section)) ++ || !(sym->section->owner == abfd ++ || (sym->section->output_section != NULL ++ && sym->section->output_section->owner == abfd ++ && sym->section->output_offset == 0) ++ || bfd_is_abs_section (sym->section))); ++} ++ ++/* Map symbol from it's internal number to the external number, moving ++ all local symbols to be at the head of the list. */ ++ ++static bool ++elf_map_symbols (bfd *abfd, unsigned int *pnum_locals) ++{ ++ unsigned int symcount = bfd_get_symcount (abfd); ++ asymbol **syms = bfd_get_outsymbols (abfd); ++ asymbol **sect_syms; ++ unsigned int num_locals = 0; ++ unsigned int num_globals = 0; ++ unsigned int num_locals2 = 0; ++ unsigned int num_globals2 = 0; ++ unsigned int max_index = 0; ++ unsigned int idx; ++ asection *asect; ++ asymbol **new_syms; ++ size_t amt; ++ ++#ifdef DEBUG ++ fprintf (stderr, "elf_map_symbols\n"); ++ fflush (stderr); ++#endif ++ ++ for (asect = abfd->sections; asect; asect = asect->next) ++ { ++ if (max_index < asect->index) ++ max_index = asect->index; ++ } ++ ++ max_index++; ++ amt = max_index * sizeof (asymbol *); ++ sect_syms = (asymbol **) bfd_zalloc (abfd, amt); ++ if (sect_syms == NULL) ++ return false; ++ elf_section_syms (abfd) = sect_syms; ++ elf_num_section_syms (abfd) = max_index; ++ ++ /* Init sect_syms entries for any section symbols we have already ++ decided to output. */ ++ for (idx = 0; idx < symcount; idx++) ++ { ++ asymbol *sym = syms[idx]; ++ ++ if ((sym->flags & BSF_SECTION_SYM) != 0 ++ && sym->value == 0 ++ && !ignore_section_sym (abfd, sym) ++ && !bfd_is_abs_section (sym->section)) ++ { ++ asection *sec = sym->section; ++ ++ if (sec->owner != abfd) ++ sec = sec->output_section; ++ ++ sect_syms[sec->index] = syms[idx]; ++ } ++ } ++ ++ /* Classify all of the symbols. */ ++ for (idx = 0; idx < symcount; idx++) ++ { ++ if (sym_is_global (abfd, syms[idx])) ++ num_globals++; ++ else if (!ignore_section_sym (abfd, syms[idx])) ++ num_locals++; ++ } ++ ++ /* We will be adding a section symbol for each normal BFD section. Most ++ sections will already have a section symbol in outsymbols, but ++ eg. SHT_GROUP sections will not, and we need the section symbol mapped ++ at least in that case. */ ++ for (asect = abfd->sections; asect; asect = asect->next) ++ { ++ asymbol *sym = asect->symbol; ++ /* Don't include ignored section symbols. */ ++ if (!ignore_section_sym (abfd, sym) ++ && sect_syms[asect->index] == NULL) ++ { ++ if (!sym_is_global (abfd, asect->symbol)) ++ num_locals++; ++ else ++ num_globals++; ++ } ++ } ++ ++ /* Now sort the symbols so the local symbols are first. */ ++ amt = (num_locals + num_globals) * sizeof (asymbol *); ++ new_syms = (asymbol **) bfd_alloc (abfd, amt); ++ if (new_syms == NULL) ++ return false; ++ ++ for (idx = 0; idx < symcount; idx++) ++ { ++ asymbol *sym = syms[idx]; ++ unsigned int i; ++ ++ if (sym_is_global (abfd, sym)) ++ i = num_locals + num_globals2++; ++ /* Don't include ignored section symbols. */ ++ else if (!ignore_section_sym (abfd, sym)) ++ i = num_locals2++; ++ else ++ continue; ++ new_syms[i] = sym; ++ sym->udata.i = i + 1; ++ } ++ for (asect = abfd->sections; asect; asect = asect->next) ++ { ++ asymbol *sym = asect->symbol; ++ if (!ignore_section_sym (abfd, sym) ++ && sect_syms[asect->index] == NULL) ++ { ++ unsigned int i; ++ ++ sect_syms[asect->index] = sym; ++ if (!sym_is_global (abfd, sym)) ++ i = num_locals2++; ++ else ++ i = num_locals + num_globals2++; ++ new_syms[i] = sym; ++ sym->udata.i = i + 1; ++ } ++ } ++ ++ bfd_set_symtab (abfd, new_syms, num_locals + num_globals); ++ ++ *pnum_locals = num_locals; ++ return true; ++} ++ ++/* Align to the maximum file alignment that could be required for any ++ ELF data structure. */ ++ ++static inline file_ptr ++align_file_position (file_ptr off, int align) ++{ ++ return (off + align - 1) & ~(align - 1); ++} ++ ++/* Assign a file position to a section, optionally aligning to the ++ required section alignment. */ ++ ++file_ptr ++_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp, ++ file_ptr offset, ++ bool align) ++{ ++ if (align && i_shdrp->sh_addralign > 1) ++ offset = BFD_ALIGN (offset, i_shdrp->sh_addralign & -i_shdrp->sh_addralign); ++ i_shdrp->sh_offset = offset; ++ if (i_shdrp->bfd_section != NULL) ++ i_shdrp->bfd_section->filepos = offset; ++ if (i_shdrp->sh_type != SHT_NOBITS) ++ offset += i_shdrp->sh_size; ++ return offset; ++} ++ ++/* Compute the file positions we are going to put the sections at, and ++ otherwise prepare to begin writing out the ELF file. If LINK_INFO ++ is not NULL, this is being called by the ELF backend linker. */ ++ ++bool ++_bfd_elf_compute_section_file_positions (bfd *abfd, ++ struct bfd_link_info *link_info) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct fake_section_arg fsargs; ++ bool failed; ++ struct elf_strtab_hash *strtab = NULL; ++ Elf_Internal_Shdr *shstrtab_hdr; ++ bool need_symtab; ++ ++ if (abfd->output_has_begun) ++ return true; ++ ++ /* Do any elf backend specific processing first. */ ++ if (bed->elf_backend_begin_write_processing) ++ (*bed->elf_backend_begin_write_processing) (abfd, link_info); ++ ++ if (!(*bed->elf_backend_init_file_header) (abfd, link_info)) ++ return false; ++ ++ fsargs.failed = false; ++ fsargs.link_info = link_info; ++ bfd_map_over_sections (abfd, elf_fake_sections, &fsargs); ++ if (fsargs.failed) ++ return false; ++ ++ if (!assign_section_numbers (abfd, link_info)) ++ return false; ++ ++ /* The backend linker builds symbol table information itself. */ ++ need_symtab = (link_info == NULL ++ && (bfd_get_symcount (abfd) > 0 ++ || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC)) ++ == HAS_RELOC))); ++ if (need_symtab) ++ { ++ /* Non-zero if doing a relocatable link. */ ++ int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC)); ++ ++ if (! swap_out_syms (abfd, &strtab, relocatable_p, link_info)) ++ return false; ++ } ++ ++ failed = false; ++ if (link_info == NULL) ++ { ++ bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); ++ if (failed) ++ goto err_free_strtab; ++ } ++ ++ shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr; ++ /* sh_name was set in init_file_header. */ ++ shstrtab_hdr->sh_type = SHT_STRTAB; ++ shstrtab_hdr->sh_flags = bed->elf_strtab_flags; ++ shstrtab_hdr->sh_addr = 0; ++ /* sh_size is set in _bfd_elf_assign_file_positions_for_non_load. */ ++ shstrtab_hdr->sh_entsize = 0; ++ shstrtab_hdr->sh_link = 0; ++ shstrtab_hdr->sh_info = 0; ++ /* sh_offset is set in _bfd_elf_assign_file_positions_for_non_load. */ ++ shstrtab_hdr->sh_addralign = 1; ++ ++ if (!assign_file_positions_except_relocs (abfd, link_info)) ++ goto err_free_strtab; ++ ++ if (strtab != NULL) ++ { ++ file_ptr off; ++ Elf_Internal_Shdr *hdr; ++ ++ off = elf_next_file_pos (abfd); ++ ++ hdr = & elf_symtab_hdr (abfd); ++ off = _bfd_elf_assign_file_position_for_section (hdr, off, true); ++ ++ if (elf_symtab_shndx_list (abfd) != NULL) ++ { ++ hdr = & elf_symtab_shndx_list (abfd)->hdr; ++ if (hdr->sh_size != 0) ++ off = _bfd_elf_assign_file_position_for_section (hdr, off, true); ++ /* FIXME: What about other symtab_shndx sections in the list ? */ ++ } ++ ++ hdr = &elf_tdata (abfd)->strtab_hdr; ++ off = _bfd_elf_assign_file_position_for_section (hdr, off, true); ++ ++ elf_next_file_pos (abfd) = off; ++ ++ /* Now that we know where the .strtab section goes, write it ++ out. */ ++ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 ++ || ! _bfd_elf_strtab_emit (abfd, strtab)) ++ goto err_free_strtab; ++ _bfd_elf_strtab_free (strtab); ++ } ++ ++ abfd->output_has_begun = true; ++ return true; ++ ++ err_free_strtab: ++ if (strtab != NULL) ++ _bfd_elf_strtab_free (strtab); ++ return false; ++} ++ ++/* Retrieve .eh_frame_hdr. Prior to size_dynamic_sections the ++ function effectively returns whether --eh-frame-hdr is given on the ++ command line. After size_dynamic_sections the result reflects ++ whether .eh_frame_hdr will actually be output (sizing isn't done ++ until ldemul_after_allocation). */ ++ ++static asection * ++elf_eh_frame_hdr (const struct bfd_link_info *info) ++{ ++ if (info != NULL && is_elf_hash_table (info->hash)) ++ return elf_hash_table (info)->eh_info.hdr_sec; ++ return NULL; ++} ++ ++/* Make an initial estimate of the size of the program header. If we ++ get the number wrong here, we'll redo section placement. */ ++ ++static bfd_size_type ++get_program_header_size (bfd *abfd, struct bfd_link_info *info) ++{ ++ size_t segs; ++ asection *s; ++ const struct elf_backend_data *bed; ++ ++ /* Assume we will need exactly two PT_LOAD segments: one for text ++ and one for data. */ ++ segs = 2; ++ ++ s = bfd_get_section_by_name (abfd, ".interp"); ++ if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->size != 0) ++ { ++ /* If we have a loadable interpreter section, we need a ++ PT_INTERP segment. In this case, assume we also need a ++ PT_PHDR segment, although that may not be true for all ++ targets. */ ++ segs += 2; ++ } ++ ++ if (bfd_get_section_by_name (abfd, ".dynamic") != NULL) ++ { ++ /* We need a PT_DYNAMIC segment. */ ++ ++segs; ++ } ++ ++ if (info != NULL && info->relro) ++ { ++ /* We need a PT_GNU_RELRO segment. */ ++ ++segs; ++ } ++ ++ if (elf_eh_frame_hdr (info)) ++ { ++ /* We need a PT_GNU_EH_FRAME segment. */ ++ ++segs; ++ } ++ ++ if (elf_stack_flags (abfd)) ++ { ++ /* We need a PT_GNU_STACK segment. */ ++ ++segs; ++ } ++ ++ if (elf_sframe (abfd)) ++ { ++ /* We need a PT_GNU_SFRAME segment. */ ++ ++segs; ++ } ++ ++ s = bfd_get_section_by_name (abfd, ++ NOTE_GNU_PROPERTY_SECTION_NAME); ++ if (s != NULL && s->size != 0) ++ { ++ /* We need a PT_GNU_PROPERTY segment. */ ++ ++segs; ++ } ++ ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ if ((s->flags & SEC_LOAD) != 0 ++ && elf_section_type (s) == SHT_NOTE) ++ { ++ unsigned int alignment_power; ++ /* We need a PT_NOTE segment. */ ++ ++segs; ++ /* Try to create just one PT_NOTE segment for all adjacent ++ loadable SHT_NOTE sections. gABI requires that within a ++ PT_NOTE segment (and also inside of each SHT_NOTE section) ++ each note should have the same alignment. So we check ++ whether the sections are correctly aligned. */ ++ alignment_power = s->alignment_power; ++ while (s->next != NULL ++ && s->next->alignment_power == alignment_power ++ && (s->next->flags & SEC_LOAD) != 0 ++ && elf_section_type (s->next) == SHT_NOTE) ++ s = s->next; ++ } ++ } ++ ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ if (s->flags & SEC_THREAD_LOCAL) ++ { ++ /* We need a PT_TLS segment. */ ++ ++segs; ++ break; ++ } ++ } ++ ++ bed = get_elf_backend_data (abfd); ++ ++ if ((abfd->flags & D_PAGED) != 0 ++ && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0) ++ { ++ /* Add a PT_GNU_MBIND segment for each mbind section. */ ++ bfd_vma commonpagesize; ++ unsigned int page_align_power; ++ ++ if (info != NULL) ++ commonpagesize = info->commonpagesize; ++ else ++ commonpagesize = bed->commonpagesize; ++ page_align_power = bfd_log2 (commonpagesize); ++ for (s = abfd->sections; s != NULL; s = s->next) ++ if (elf_section_flags (s) & SHF_GNU_MBIND) ++ { ++ if (elf_section_data (s)->this_hdr.sh_info > PT_GNU_MBIND_NUM) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: GNU_MBIND section `%pA' has invalid " ++ "sh_info field: %d"), ++ abfd, s, elf_section_data (s)->this_hdr.sh_info); ++ continue; ++ } ++ /* Align mbind section to page size. */ ++ if (s->alignment_power < page_align_power) ++ s->alignment_power = page_align_power; ++ segs ++; ++ } ++ } ++ ++ /* Let the backend count up any program headers it might need. */ ++ if (bed->elf_backend_additional_program_headers) ++ { ++ int a; ++ ++ a = (*bed->elf_backend_additional_program_headers) (abfd, info); ++ if (a == -1) ++ abort (); ++ segs += a; ++ } ++ ++ return segs * bed->s->sizeof_phdr; ++} ++ ++/* Find the segment that contains the output_section of section. */ ++ ++Elf_Internal_Phdr * ++_bfd_elf_find_segment_containing_section (bfd * abfd, asection * section) ++{ ++ struct elf_segment_map *m; ++ Elf_Internal_Phdr *p; ++ ++ for (m = elf_seg_map (abfd), p = elf_tdata (abfd)->phdr; ++ m != NULL; ++ m = m->next, p++) ++ { ++ int i; ++ ++ for (i = m->count - 1; i >= 0; i--) ++ if (m->sections[i] == section) ++ return p; ++ } ++ ++ return NULL; ++} ++ ++/* Create a mapping from a set of sections to a program segment. */ ++ ++static struct elf_segment_map * ++make_mapping (bfd *abfd, ++ asection **sections, ++ unsigned int from, ++ unsigned int to, ++ bool phdr) ++{ ++ struct elf_segment_map *m; ++ unsigned int i; ++ asection **hdrpp; ++ size_t amt; ++ ++ amt = sizeof (struct elf_segment_map) - sizeof (asection *); ++ amt += (to - from) * sizeof (asection *); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ return NULL; ++ m->next = NULL; ++ m->p_type = PT_LOAD; ++ for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++) ++ m->sections[i - from] = *hdrpp; ++ m->count = to - from; ++ ++ if (from == 0 && phdr) ++ { ++ /* Include the headers in the first PT_LOAD segment. */ ++ m->includes_filehdr = 1; ++ m->includes_phdrs = 1; ++ } ++ ++ return m; ++} ++ ++/* Create the PT_DYNAMIC segment, which includes DYNSEC. Returns NULL ++ on failure. */ ++ ++struct elf_segment_map * ++_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec) ++{ ++ struct elf_segment_map *m; ++ ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, ++ sizeof (struct elf_segment_map)); ++ if (m == NULL) ++ return NULL; ++ m->next = NULL; ++ m->p_type = PT_DYNAMIC; ++ m->count = 1; ++ m->sections[0] = dynsec; ++ ++ return m; ++} ++ ++/* Possibly add or remove segments from the segment map. */ ++ ++static bool ++elf_modify_segment_map (bfd *abfd, ++ struct bfd_link_info *info, ++ bool remove_empty_load) ++{ ++ struct elf_segment_map **m; ++ const struct elf_backend_data *bed; ++ ++ /* The placement algorithm assumes that non allocated sections are ++ not in PT_LOAD segments. We ensure this here by removing such ++ sections from the segment map. We also remove excluded ++ sections. Finally, any PT_LOAD segment without sections is ++ removed. */ ++ m = &elf_seg_map (abfd); ++ while (*m) ++ { ++ unsigned int i, new_count; ++ ++ for (new_count = 0, i = 0; i < (*m)->count; i++) ++ { ++ if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0 ++ && (((*m)->sections[i]->flags & SEC_ALLOC) != 0 ++ || (*m)->p_type != PT_LOAD)) ++ { ++ (*m)->sections[new_count] = (*m)->sections[i]; ++ new_count++; ++ } ++ } ++ (*m)->count = new_count; ++ ++ if (remove_empty_load ++ && (*m)->p_type == PT_LOAD ++ && (*m)->count == 0 ++ && !(*m)->includes_phdrs) ++ *m = (*m)->next; ++ else ++ m = &(*m)->next; ++ } ++ ++ bed = get_elf_backend_data (abfd); ++ if (bed->elf_backend_modify_segment_map != NULL) ++ { ++ if (!(*bed->elf_backend_modify_segment_map) (abfd, info)) ++ return false; ++ } ++ ++ return true; ++} ++ ++#define IS_TBSS(s) \ ++ ((s->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) == SEC_THREAD_LOCAL) ++ ++/* Set up a mapping from BFD sections to program segments. Update ++ NEED_LAYOUT if the section layout is changed. */ ++ ++bool ++_bfd_elf_map_sections_to_segments (bfd *abfd, ++ struct bfd_link_info *info, ++ bool *need_layout) ++{ ++ unsigned int count; ++ struct elf_segment_map *m; ++ asection **sections = NULL; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ bool no_user_phdrs; ++ ++ no_user_phdrs = elf_seg_map (abfd) == NULL; ++ ++ if (info != NULL) ++ { ++ info->user_phdrs = !no_user_phdrs; ++ ++ /* Size the relative relocations if DT_RELR is enabled. */ ++ if (info->enable_dt_relr ++ && need_layout != NULL ++ && bed->size_relative_relocs ++ && !bed->size_relative_relocs (info, need_layout)) ++ info->callbacks->einfo ++ (_("%F%P: failed to size relative relocations\n")); ++ } ++ ++ if (no_user_phdrs && bfd_count_sections (abfd) != 0) ++ { ++ asection *s; ++ unsigned int i; ++ struct elf_segment_map *mfirst; ++ struct elf_segment_map **pm; ++ asection *last_hdr; ++ bfd_vma last_size; ++ unsigned int hdr_index; ++ bfd_vma maxpagesize; ++ asection **hdrpp; ++ bool phdr_in_segment; ++ bool writable; ++ bool executable; ++ unsigned int tls_count = 0; ++ asection *first_tls = NULL; ++ asection *first_mbind = NULL; ++ asection *dynsec, *eh_frame_hdr; ++ asection *sframe; ++ size_t amt; ++ bfd_vma addr_mask, wrap_to = 0; /* Bytes. */ ++ bfd_size_type phdr_size; /* Octets/bytes. */ ++ unsigned int opb = bfd_octets_per_byte (abfd, NULL); ++ ++ /* Select the allocated sections, and sort them. */ ++ ++ amt = bfd_count_sections (abfd) * sizeof (asection *); ++ sections = (asection **) bfd_malloc (amt); ++ if (sections == NULL) ++ goto error_return; ++ ++ /* Calculate top address, avoiding undefined behaviour of shift ++ left operator when shift count is equal to size of type ++ being shifted. */ ++ addr_mask = ((bfd_vma) 1 << (bfd_arch_bits_per_address (abfd) - 1)) - 1; ++ addr_mask = (addr_mask << 1) + 1; ++ ++ i = 0; ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ if ((s->flags & SEC_ALLOC) != 0) ++ { ++ /* target_index is unused until bfd_elf_final_link ++ starts output of section symbols. Use it to make ++ qsort stable. */ ++ s->target_index = i; ++ sections[i] = s; ++ ++i; ++ /* A wrapping section potentially clashes with header. */ ++ if (((s->lma + s->size / opb) & addr_mask) < (s->lma & addr_mask)) ++ wrap_to = (s->lma + s->size / opb) & addr_mask; ++ } ++ } ++ BFD_ASSERT (i <= bfd_count_sections (abfd)); ++ count = i; ++ ++ qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections); ++ ++ phdr_size = elf_program_header_size (abfd); ++ if (phdr_size == (bfd_size_type) -1) ++ phdr_size = get_program_header_size (abfd, info); ++ phdr_size += bed->s->sizeof_ehdr; ++ /* phdr_size is compared to LMA values which are in bytes. */ ++ phdr_size /= opb; ++ if (info != NULL) ++ maxpagesize = info->maxpagesize; ++ else ++ maxpagesize = bed->maxpagesize; ++ if (maxpagesize == 0) ++ maxpagesize = 1; ++ phdr_in_segment = info != NULL && info->load_phdrs; ++ if (count != 0 ++ && (((sections[0]->lma & addr_mask) & (maxpagesize - 1)) ++ >= (phdr_size & (maxpagesize - 1)))) ++ /* For compatibility with old scripts that may not be using ++ SIZEOF_HEADERS, add headers when it looks like space has ++ been left for them. */ ++ phdr_in_segment = true; ++ ++ /* Build the mapping. */ ++ mfirst = NULL; ++ pm = &mfirst; ++ ++ /* If we have a .interp section, then create a PT_PHDR segment for ++ the program headers and a PT_INTERP segment for the .interp ++ section. */ ++ s = bfd_get_section_by_name (abfd, ".interp"); ++ if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->size != 0) ++ { ++ amt = sizeof (struct elf_segment_map); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_PHDR; ++ m->p_flags = PF_R; ++ m->p_flags_valid = 1; ++ m->includes_phdrs = 1; ++ phdr_in_segment = true; ++ *pm = m; ++ pm = &m->next; ++ ++ amt = sizeof (struct elf_segment_map); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_INTERP; ++ m->count = 1; ++ m->sections[0] = s; ++ ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ /* Look through the sections. We put sections in the same program ++ segment when the start of the second section can be placed within ++ a few bytes of the end of the first section. */ ++ last_hdr = NULL; ++ last_size = 0; ++ hdr_index = 0; ++ writable = false; ++ executable = false; ++ dynsec = bfd_get_section_by_name (abfd, ".dynamic"); ++ if (dynsec != NULL ++ && (dynsec->flags & SEC_LOAD) == 0) ++ dynsec = NULL; ++ ++ if ((abfd->flags & D_PAGED) == 0) ++ phdr_in_segment = false; ++ ++ /* Deal with -Ttext or something similar such that the first section ++ is not adjacent to the program headers. This is an ++ approximation, since at this point we don't know exactly how many ++ program headers we will need. */ ++ if (phdr_in_segment && count > 0) ++ { ++ bfd_vma phdr_lma; /* Bytes. */ ++ bool separate_phdr = false; ++ ++ phdr_lma = (sections[0]->lma - phdr_size) & addr_mask & -maxpagesize; ++ if (info != NULL ++ && info->separate_code ++ && (sections[0]->flags & SEC_CODE) != 0) ++ { ++ /* If data sections should be separate from code and ++ thus not executable, and the first section is ++ executable then put the file and program headers in ++ their own PT_LOAD. */ ++ separate_phdr = true; ++ if ((((phdr_lma + phdr_size - 1) & addr_mask & -maxpagesize) ++ == (sections[0]->lma & addr_mask & -maxpagesize))) ++ { ++ /* The file and program headers are currently on the ++ same page as the first section. Put them on the ++ previous page if we can. */ ++ if (phdr_lma >= maxpagesize) ++ phdr_lma -= maxpagesize; ++ else ++ separate_phdr = false; ++ } ++ } ++ if ((sections[0]->lma & addr_mask) < phdr_lma ++ || (sections[0]->lma & addr_mask) < phdr_size) ++ /* If file and program headers would be placed at the end ++ of memory then it's probably better to omit them. */ ++ phdr_in_segment = false; ++ else if (phdr_lma < wrap_to) ++ /* If a section wraps around to where we'll be placing ++ file and program headers, then the headers will be ++ overwritten. */ ++ phdr_in_segment = false; ++ else if (separate_phdr) ++ { ++ m = make_mapping (abfd, sections, 0, 0, phdr_in_segment); ++ if (m == NULL) ++ goto error_return; ++ m->p_paddr = phdr_lma * opb; ++ m->p_vaddr_offset ++ = (sections[0]->vma - phdr_size) & addr_mask & -maxpagesize; ++ m->p_paddr_valid = 1; ++ *pm = m; ++ pm = &m->next; ++ phdr_in_segment = false; ++ } ++ } ++ ++ for (i = 0, hdrpp = sections; i < count; i++, hdrpp++) ++ { ++ asection *hdr; ++ bool new_segment; ++ ++ hdr = *hdrpp; ++ ++ /* See if this section and the last one will fit in the same ++ segment. */ ++ ++ if (last_hdr == NULL) ++ { ++ /* If we don't have a segment yet, then we don't need a new ++ one (we build the last one after this loop). */ ++ new_segment = false; ++ } ++ else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma) ++ { ++ /* If this section has a different relation between the ++ virtual address and the load address, then we need a new ++ segment. */ ++ new_segment = true; ++ } ++ else if (hdr->lma < last_hdr->lma + last_size ++ || last_hdr->lma + last_size < last_hdr->lma) ++ { ++ /* If this section has a load address that makes it overlap ++ the previous section, then we need a new segment. */ ++ new_segment = true; ++ } ++ else if ((abfd->flags & D_PAGED) != 0 ++ && (((last_hdr->lma + last_size - 1) & -maxpagesize) ++ == (hdr->lma & -maxpagesize))) ++ { ++ /* If we are demand paged then we can't map two disk ++ pages onto the same memory page. */ ++ new_segment = false; ++ } ++ /* In the next test we have to be careful when last_hdr->lma is close ++ to the end of the address space. If the aligned address wraps ++ around to the start of the address space, then there are no more ++ pages left in memory and it is OK to assume that the current ++ section can be included in the current segment. */ ++ else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) ++ + maxpagesize > last_hdr->lma) ++ && (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) ++ + maxpagesize <= hdr->lma)) ++ { ++ /* If putting this section in this segment would force us to ++ skip a page in the segment, then we need a new segment. */ ++ new_segment = true; ++ } ++ else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 ++ && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0) ++ { ++ /* We don't want to put a loaded section after a ++ nonloaded (ie. bss style) section in the same segment ++ as that will force the non-loaded section to be loaded. ++ Consider .tbss sections as loaded for this purpose. */ ++ new_segment = true; ++ } ++ else if ((abfd->flags & D_PAGED) == 0) ++ { ++ /* If the file is not demand paged, which means that we ++ don't require the sections to be correctly aligned in the ++ file, then there is no other reason for a new segment. */ ++ new_segment = false; ++ } ++ else if (info != NULL ++ && info->separate_code ++ && executable != ((hdr->flags & SEC_CODE) != 0)) ++ { ++ new_segment = true; ++ } ++ else if (! writable ++ && (hdr->flags & SEC_READONLY) == 0) ++ { ++ /* We don't want to put a writable section in a read only ++ segment. */ ++ new_segment = true; ++ } ++ else ++ { ++ /* Otherwise, we can use the same segment. */ ++ new_segment = false; ++ } ++ ++ /* Allow interested parties a chance to override our decision. */ ++ if (last_hdr != NULL ++ && info != NULL ++ && info->callbacks->override_segment_assignment != NULL) ++ new_segment ++ = info->callbacks->override_segment_assignment (info, abfd, hdr, ++ last_hdr, ++ new_segment); ++ ++ if (! new_segment) ++ { ++ if ((hdr->flags & SEC_READONLY) == 0) ++ writable = true; ++ if ((hdr->flags & SEC_CODE) != 0) ++ executable = true; ++ last_hdr = hdr; ++ /* .tbss sections effectively have zero size. */ ++ last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb; ++ continue; ++ } ++ ++ /* We need a new program segment. We must create a new program ++ header holding all the sections from hdr_index until hdr. */ ++ ++ m = make_mapping (abfd, sections, hdr_index, i, phdr_in_segment); ++ if (m == NULL) ++ goto error_return; ++ ++ *pm = m; ++ pm = &m->next; ++ ++ if ((hdr->flags & SEC_READONLY) == 0) ++ writable = true; ++ else ++ writable = false; ++ ++ if ((hdr->flags & SEC_CODE) == 0) ++ executable = false; ++ else ++ executable = true; ++ ++ last_hdr = hdr; ++ /* .tbss sections effectively have zero size. */ ++ last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb; ++ hdr_index = i; ++ phdr_in_segment = false; ++ } ++ ++ /* Create a final PT_LOAD program segment, but not if it's just ++ for .tbss. */ ++ if (last_hdr != NULL ++ && (i - hdr_index != 1 ++ || !IS_TBSS (last_hdr))) ++ { ++ m = make_mapping (abfd, sections, hdr_index, i, phdr_in_segment); ++ if (m == NULL) ++ goto error_return; ++ ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ /* If there is a .dynamic section, throw in a PT_DYNAMIC segment. */ ++ if (dynsec != NULL) ++ { ++ m = _bfd_elf_make_dynamic_segment (abfd, dynsec); ++ if (m == NULL) ++ goto error_return; ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ /* For each batch of consecutive loadable SHT_NOTE sections, ++ add a PT_NOTE segment. We don't use bfd_get_section_by_name, ++ because if we link together nonloadable .note sections and ++ loadable .note sections, we will generate two .note sections ++ in the output file. */ ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ if ((s->flags & SEC_LOAD) != 0 ++ && elf_section_type (s) == SHT_NOTE) ++ { ++ asection *s2; ++ unsigned int alignment_power = s->alignment_power; ++ ++ count = 1; ++ for (s2 = s; s2->next != NULL; s2 = s2->next) ++ { ++ if (s2->next->alignment_power == alignment_power ++ && (s2->next->flags & SEC_LOAD) != 0 ++ && elf_section_type (s2->next) == SHT_NOTE ++ && align_power (s2->lma + s2->size / opb, ++ alignment_power) ++ == s2->next->lma) ++ count++; ++ else ++ break; ++ } ++ amt = sizeof (struct elf_segment_map) - sizeof (asection *); ++ amt += count * sizeof (asection *); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_NOTE; ++ m->count = count; ++ while (count > 1) ++ { ++ m->sections[m->count - count--] = s; ++ BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0); ++ s = s->next; ++ } ++ m->sections[m->count - 1] = s; ++ BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0); ++ *pm = m; ++ pm = &m->next; ++ } ++ if (s->flags & SEC_THREAD_LOCAL) ++ { ++ if (! tls_count) ++ first_tls = s; ++ tls_count++; ++ } ++ if (first_mbind == NULL ++ && (elf_section_flags (s) & SHF_GNU_MBIND) != 0) ++ first_mbind = s; ++ } ++ ++ /* If there are any SHF_TLS output sections, add PT_TLS segment. */ ++ if (tls_count > 0) ++ { ++ amt = sizeof (struct elf_segment_map) - sizeof (asection *); ++ amt += tls_count * sizeof (asection *); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_TLS; ++ m->count = tls_count; ++ /* Mandated PF_R. */ ++ m->p_flags = PF_R; ++ m->p_flags_valid = 1; ++ s = first_tls; ++ for (i = 0; i < tls_count; ++i) ++ { ++ if ((s->flags & SEC_THREAD_LOCAL) == 0) ++ { ++ _bfd_error_handler ++ (_("%pB: TLS sections are not adjacent:"), abfd); ++ s = first_tls; ++ i = 0; ++ while (i < tls_count) ++ { ++ if ((s->flags & SEC_THREAD_LOCAL) != 0) ++ { ++ _bfd_error_handler (_(" TLS: %pA"), s); ++ i++; ++ } ++ else ++ _bfd_error_handler (_(" non-TLS: %pA"), s); ++ s = s->next; ++ } ++ bfd_set_error (bfd_error_bad_value); ++ goto error_return; ++ } ++ m->sections[i] = s; ++ s = s->next; ++ } ++ ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ if (first_mbind ++ && (abfd->flags & D_PAGED) != 0 ++ && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0) ++ for (s = first_mbind; s != NULL; s = s->next) ++ if ((elf_section_flags (s) & SHF_GNU_MBIND) != 0 ++ && elf_section_data (s)->this_hdr.sh_info <= PT_GNU_MBIND_NUM) ++ { ++ /* Mandated PF_R. */ ++ unsigned long p_flags = PF_R; ++ if ((s->flags & SEC_READONLY) == 0) ++ p_flags |= PF_W; ++ if ((s->flags & SEC_CODE) != 0) ++ p_flags |= PF_X; ++ ++ amt = sizeof (struct elf_segment_map) + sizeof (asection *); ++ m = bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = (PT_GNU_MBIND_LO ++ + elf_section_data (s)->this_hdr.sh_info); ++ m->count = 1; ++ m->p_flags_valid = 1; ++ m->sections[0] = s; ++ m->p_flags = p_flags; ++ ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ s = bfd_get_section_by_name (abfd, ++ NOTE_GNU_PROPERTY_SECTION_NAME); ++ if (s != NULL && s->size != 0) ++ { ++ amt = sizeof (struct elf_segment_map) + sizeof (asection *); ++ m = bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_GNU_PROPERTY; ++ m->count = 1; ++ m->p_flags_valid = 1; ++ m->sections[0] = s; ++ m->p_flags = PF_R; ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME ++ segment. */ ++ eh_frame_hdr = elf_eh_frame_hdr (info); ++ if (eh_frame_hdr != NULL ++ && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0) ++ { ++ amt = sizeof (struct elf_segment_map); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_GNU_EH_FRAME; ++ m->count = 1; ++ m->sections[0] = eh_frame_hdr->output_section; ++ ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ /* If there is a .sframe section, throw in a PT_GNU_SFRAME ++ segment. */ ++ sframe = elf_sframe (abfd); ++ if (sframe != NULL ++ && (sframe->output_section->flags & SEC_LOAD) != 0 ++ && sframe->size != 0) ++ { ++ amt = sizeof (struct elf_segment_map); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_GNU_SFRAME; ++ m->count = 1; ++ m->sections[0] = sframe->output_section; ++ ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ if (elf_stack_flags (abfd)) ++ { ++ amt = sizeof (struct elf_segment_map); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_GNU_STACK; ++ m->p_flags = elf_stack_flags (abfd); ++ m->p_align = bed->stack_align; ++ m->p_flags_valid = 1; ++ m->p_align_valid = m->p_align != 0; ++ if (info->stacksize > 0) ++ { ++ m->p_size = info->stacksize; ++ m->p_size_valid = 1; ++ } ++ ++ *pm = m; ++ pm = &m->next; ++ } ++ ++ if (info != NULL && info->relro) ++ { ++ for (m = mfirst; m != NULL; m = m->next) ++ { ++ if (m->p_type == PT_LOAD ++ && m->count != 0 ++ && m->sections[0]->vma >= info->relro_start ++ && m->sections[0]->vma < info->relro_end) ++ { ++ i = m->count; ++ while (--i != (unsigned) -1) ++ { ++ if (m->sections[i]->size > 0 ++ && (m->sections[i]->flags & SEC_LOAD) != 0 ++ && (m->sections[i]->flags & SEC_HAS_CONTENTS) != 0) ++ break; ++ } ++ ++ if (i != (unsigned) -1) ++ break; ++ } ++ } ++ ++ /* Make a PT_GNU_RELRO segment only when it isn't empty. */ ++ if (m != NULL) ++ { ++ amt = sizeof (struct elf_segment_map); ++ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_GNU_RELRO; ++ *pm = m; ++ pm = &m->next; ++ } ++ } ++ ++ free (sections); ++ elf_seg_map (abfd) = mfirst; ++ } ++ ++ if (!elf_modify_segment_map (abfd, info, no_user_phdrs)) ++ return false; ++ ++ for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next) ++ ++count; ++ elf_program_header_size (abfd) = count * bed->s->sizeof_phdr; ++ ++ return true; ++ ++ error_return: ++ free (sections); ++ return false; ++} ++ ++/* Sort sections by address. */ ++ ++static int ++elf_sort_sections (const void *arg1, const void *arg2) ++{ ++ const asection *sec1 = *(const asection **) arg1; ++ const asection *sec2 = *(const asection **) arg2; ++ bfd_size_type size1, size2; ++ ++ /* Sort by LMA first, since this is the address used to ++ place the section into a segment. */ ++ if (sec1->lma < sec2->lma) ++ return -1; ++ else if (sec1->lma > sec2->lma) ++ return 1; ++ ++ /* Then sort by VMA. Normally the LMA and the VMA will be ++ the same, and this will do nothing. */ ++ if (sec1->vma < sec2->vma) ++ return -1; ++ else if (sec1->vma > sec2->vma) ++ return 1; ++ ++ /* Put !SEC_LOAD sections after SEC_LOAD ones. */ ++ ++#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 \ ++ && (x)->size != 0) ++ ++ if (TOEND (sec1)) ++ { ++ if (!TOEND (sec2)) ++ return 1; ++ } ++ else if (TOEND (sec2)) ++ return -1; ++ ++#undef TOEND ++ ++ /* Sort by size, to put zero sized sections ++ before others at the same address. */ ++ ++ size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0; ++ size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0; ++ ++ if (size1 < size2) ++ return -1; ++ if (size1 > size2) ++ return 1; ++ ++ return sec1->target_index - sec2->target_index; ++} ++ ++/* This qsort comparison functions sorts PT_LOAD segments first and ++ by p_paddr, for assign_file_positions_for_load_sections. */ ++ ++static int ++elf_sort_segments (const void *arg1, const void *arg2) ++{ ++ const struct elf_segment_map *m1 = *(const struct elf_segment_map **) arg1; ++ const struct elf_segment_map *m2 = *(const struct elf_segment_map **) arg2; ++ ++ if (m1->p_type != m2->p_type) ++ { ++ if (m1->p_type == PT_NULL) ++ return 1; ++ if (m2->p_type == PT_NULL) ++ return -1; ++ return m1->p_type < m2->p_type ? -1 : 1; ++ } ++ if (m1->includes_filehdr != m2->includes_filehdr) ++ return m1->includes_filehdr ? -1 : 1; ++ if (m1->no_sort_lma != m2->no_sort_lma) ++ return m1->no_sort_lma ? -1 : 1; ++ if (m1->p_type == PT_LOAD && !m1->no_sort_lma) ++ { ++ bfd_vma lma1, lma2; /* Octets. */ ++ lma1 = 0; ++ if (m1->p_paddr_valid) ++ lma1 = m1->p_paddr; ++ else if (m1->count != 0) ++ { ++ unsigned int opb = bfd_octets_per_byte (m1->sections[0]->owner, ++ m1->sections[0]); ++ lma1 = (m1->sections[0]->lma + m1->p_vaddr_offset) * opb; ++ } ++ lma2 = 0; ++ if (m2->p_paddr_valid) ++ lma2 = m2->p_paddr; ++ else if (m2->count != 0) ++ { ++ unsigned int opb = bfd_octets_per_byte (m2->sections[0]->owner, ++ m2->sections[0]); ++ lma2 = (m2->sections[0]->lma + m2->p_vaddr_offset) * opb; ++ } ++ if (lma1 != lma2) ++ return lma1 < lma2 ? -1 : 1; ++ } ++ if (m1->idx != m2->idx) ++ return m1->idx < m2->idx ? -1 : 1; ++ return 0; ++} ++ ++/* Ian Lance Taylor writes: ++ ++ We shouldn't be using % with a negative signed number. That's just ++ not good. We have to make sure either that the number is not ++ negative, or that the number has an unsigned type. When the types ++ are all the same size they wind up as unsigned. When file_ptr is a ++ larger signed type, the arithmetic winds up as signed long long, ++ which is wrong. ++ ++ What we're trying to say here is something like ``increase OFF by ++ the least amount that will cause it to be equal to the VMA modulo ++ the page size.'' */ ++/* In other words, something like: ++ ++ vma_offset = m->sections[0]->vma % bed->maxpagesize; ++ off_offset = off % bed->maxpagesize; ++ if (vma_offset < off_offset) ++ adjustment = vma_offset + bed->maxpagesize - off_offset; ++ else ++ adjustment = vma_offset - off_offset; ++ ++ which can be collapsed into the expression below. */ ++ ++static file_ptr ++vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize) ++{ ++ /* PR binutils/16199: Handle an alignment of zero. */ ++ if (maxpagesize == 0) ++ maxpagesize = 1; ++ return ((vma - off) % maxpagesize); ++} ++ ++static void ++print_segment_map (const struct elf_segment_map *m) ++{ ++ unsigned int j; ++ const char *pt = get_segment_type (m->p_type); ++ char buf[32]; ++ ++ if (pt == NULL) ++ { ++ if (m->p_type >= PT_LOPROC && m->p_type <= PT_HIPROC) ++ sprintf (buf, "LOPROC+%7.7x", ++ (unsigned int) (m->p_type - PT_LOPROC)); ++ else if (m->p_type >= PT_LOOS && m->p_type <= PT_HIOS) ++ sprintf (buf, "LOOS+%7.7x", ++ (unsigned int) (m->p_type - PT_LOOS)); ++ else ++ snprintf (buf, sizeof (buf), "%8.8x", ++ (unsigned int) m->p_type); ++ pt = buf; ++ } ++ fflush (stdout); ++ fprintf (stderr, "%s:", pt); ++ for (j = 0; j < m->count; j++) ++ fprintf (stderr, " %s", m->sections [j]->name); ++ putc ('\n',stderr); ++ fflush (stderr); ++} ++ ++/* Assign file positions to the sections based on the mapping from ++ sections to segments. This function also sets up some fields in ++ the file header. */ ++ ++static bool ++assign_file_positions_for_load_sections (bfd *abfd, ++ struct bfd_link_info *link_info) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct elf_segment_map *m; ++ struct elf_segment_map *phdr_load_seg; ++ Elf_Internal_Phdr *phdrs; ++ Elf_Internal_Phdr *p; ++ file_ptr off; /* Octets. */ ++ bfd_size_type maxpagesize; ++ unsigned int alloc, actual; ++ unsigned int i, j; ++ struct elf_segment_map **sorted_seg_map; ++ unsigned int opb = bfd_octets_per_byte (abfd, NULL); ++ ++ if (link_info == NULL ++ && !_bfd_elf_map_sections_to_segments (abfd, link_info, NULL)) ++ return false; ++ ++ alloc = 0; ++ for (m = elf_seg_map (abfd); m != NULL; m = m->next) ++ m->idx = alloc++; ++ ++ if (alloc) ++ { ++ elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr; ++ elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr; ++ } ++ else ++ { ++ /* PR binutils/12467. */ ++ elf_elfheader (abfd)->e_phoff = 0; ++ elf_elfheader (abfd)->e_phentsize = 0; ++ } ++ ++ elf_elfheader (abfd)->e_phnum = alloc; ++ ++ if (elf_program_header_size (abfd) == (bfd_size_type) -1) ++ { ++ actual = alloc; ++ elf_program_header_size (abfd) = alloc * bed->s->sizeof_phdr; ++ } ++ else ++ { ++ actual = elf_program_header_size (abfd) / bed->s->sizeof_phdr; ++ BFD_ASSERT (elf_program_header_size (abfd) ++ == actual * bed->s->sizeof_phdr); ++ BFD_ASSERT (actual >= alloc); ++ } ++ ++ if (alloc == 0) ++ { ++ elf_next_file_pos (abfd) = bed->s->sizeof_ehdr; ++ return true; ++ } ++ ++ /* We're writing the size in elf_program_header_size (abfd), ++ see assign_file_positions_except_relocs, so make sure we have ++ that amount allocated, with trailing space cleared. ++ The variable alloc contains the computed need, while ++ elf_program_header_size (abfd) contains the size used for the ++ layout. ++ See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments ++ where the layout is forced to according to a larger size in the ++ last iterations for the testcase ld-elf/header. */ ++ phdrs = bfd_zalloc (abfd, (actual * sizeof (*phdrs) ++ + alloc * sizeof (*sorted_seg_map))); ++ sorted_seg_map = (struct elf_segment_map **) (phdrs + actual); ++ elf_tdata (abfd)->phdr = phdrs; ++ if (phdrs == NULL) ++ return false; ++ ++ for (m = elf_seg_map (abfd), j = 0; m != NULL; m = m->next, j++) ++ { ++ sorted_seg_map[j] = m; ++ /* If elf_segment_map is not from map_sections_to_segments, the ++ sections may not be correctly ordered. NOTE: sorting should ++ not be done to the PT_NOTE section of a corefile, which may ++ contain several pseudo-sections artificially created by bfd. ++ Sorting these pseudo-sections breaks things badly. */ ++ if (m->count > 1 ++ && !(elf_elfheader (abfd)->e_type == ET_CORE ++ && m->p_type == PT_NOTE)) ++ { ++ for (i = 0; i < m->count; i++) ++ m->sections[i]->target_index = i; ++ qsort (m->sections, (size_t) m->count, sizeof (asection *), ++ elf_sort_sections); ++ } ++ } ++ if (alloc > 1) ++ qsort (sorted_seg_map, alloc, sizeof (*sorted_seg_map), ++ elf_sort_segments); ++ ++ maxpagesize = 1; ++ if ((abfd->flags & D_PAGED) != 0) ++ { ++ if (link_info != NULL) ++ maxpagesize = link_info->maxpagesize; ++ else ++ maxpagesize = bed->maxpagesize; ++ } ++ ++ /* Sections must map to file offsets past the ELF file header. */ ++ off = bed->s->sizeof_ehdr; ++ /* And if one of the PT_LOAD headers doesn't include the program ++ headers then we'll be mapping program headers in the usual ++ position after the ELF file header. */ ++ phdr_load_seg = NULL; ++ for (j = 0; j < alloc; j++) ++ { ++ m = sorted_seg_map[j]; ++ if (m->p_type != PT_LOAD) ++ break; ++ if (m->includes_phdrs) ++ { ++ phdr_load_seg = m; ++ break; ++ } ++ } ++ if (phdr_load_seg == NULL) ++ off += actual * bed->s->sizeof_phdr; ++ ++ for (j = 0; j < alloc; j++) ++ { ++ asection **secpp; ++ bfd_vma off_adjust; /* Octets. */ ++ bool no_contents; ++ bfd_size_type p_align; ++ bool p_align_p; ++ ++ /* An ELF segment (described by Elf_Internal_Phdr) may contain a ++ number of sections with contents contributing to both p_filesz ++ and p_memsz, followed by a number of sections with no contents ++ that just contribute to p_memsz. In this loop, OFF tracks next ++ available file offset for PT_LOAD and PT_NOTE segments. */ ++ m = sorted_seg_map[j]; ++ p = phdrs + m->idx; ++ p->p_type = m->p_type; ++ p->p_flags = m->p_flags; ++ p_align = bed->p_align; ++ p_align_p = false; ++ ++ if (m->count == 0) ++ p->p_vaddr = m->p_vaddr_offset * opb; ++ else ++ p->p_vaddr = (m->sections[0]->vma + m->p_vaddr_offset) * opb; ++ ++ if (m->p_paddr_valid) ++ p->p_paddr = m->p_paddr; ++ else if (m->count == 0) ++ p->p_paddr = 0; ++ else ++ p->p_paddr = (m->sections[0]->lma + m->p_vaddr_offset) * opb; ++ ++ if (p->p_type == PT_LOAD ++ && (abfd->flags & D_PAGED) != 0) ++ { ++ /* p_align in demand paged PT_LOAD segments effectively stores ++ the maximum page size. When copying an executable with ++ objcopy, we set m->p_align from the input file. Use this ++ value for maxpagesize rather than bed->maxpagesize, which ++ may be different. Note that we use maxpagesize for PT_TLS ++ segment alignment later in this function, so we are relying ++ on at least one PT_LOAD segment appearing before a PT_TLS ++ segment. */ ++ if (m->p_align_valid) ++ maxpagesize = m->p_align; ++ else if (p_align != 0 ++ && (link_info == NULL ++ || !link_info->maxpagesize_is_set)) ++ /* Set p_align to the default p_align value while laying ++ out segments aligning to the maximum page size or the ++ largest section alignment. The run-time loader can ++ align segments to the default p_align value or the ++ maximum page size, depending on system page size. */ ++ p_align_p = true; ++ ++ p->p_align = maxpagesize; ++ } ++ else if (m->p_align_valid) ++ p->p_align = m->p_align; ++ else if (m->count == 0) ++ p->p_align = 1 << bed->s->log_file_align; ++ ++ if (m == phdr_load_seg) ++ { ++ if (!m->includes_filehdr) ++ p->p_offset = off; ++ off += actual * bed->s->sizeof_phdr; ++ } ++ ++ no_contents = false; ++ off_adjust = 0; ++ if (p->p_type == PT_LOAD ++ && m->count > 0) ++ { ++ bfd_size_type align; /* Bytes. */ ++ unsigned int align_power = 0; ++ ++ if (m->p_align_valid) ++ align = p->p_align; ++ else ++ { ++ for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) ++ { ++ unsigned int secalign; ++ ++ secalign = bfd_section_alignment (*secpp); ++ if (secalign > align_power) ++ align_power = secalign; ++ } ++ align = (bfd_size_type) 1 << align_power; ++ if (align < maxpagesize) ++ { ++ /* If a section requires alignment higher than the ++ default p_align value, don't set p_align to the ++ default p_align value. */ ++ if (align > p_align) ++ p_align_p = false; ++ align = maxpagesize; ++ } ++ else ++ { ++ /* If a section requires alignment higher than the ++ maximum page size, set p_align to the section ++ alignment. */ ++ p_align_p = true; ++ p_align = align; ++ } ++ } ++ ++ for (i = 0; i < m->count; i++) ++ if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) ++ /* If we aren't making room for this section, then ++ it must be SHT_NOBITS regardless of what we've ++ set via struct bfd_elf_special_section. */ ++ elf_section_type (m->sections[i]) = SHT_NOBITS; ++ ++ /* Find out whether this segment contains any loadable ++ sections. */ ++ no_contents = true; ++ for (i = 0; i < m->count; i++) ++ if (elf_section_type (m->sections[i]) != SHT_NOBITS) ++ { ++ no_contents = false; ++ break; ++ } ++ ++ off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align * opb); ++ ++ /* Broken hardware and/or kernel require that files do not ++ map the same page with different permissions on some hppa ++ processors. */ ++ if (j != 0 ++ && (abfd->flags & D_PAGED) != 0 ++ && bed->no_page_alias ++ && (off & (maxpagesize - 1)) != 0 ++ && ((off & -maxpagesize) ++ == ((off + off_adjust) & -maxpagesize))) ++ off_adjust += maxpagesize; ++ off += off_adjust; ++ if (no_contents) ++ { ++ /* We shouldn't need to align the segment on disk since ++ the segment doesn't need file space, but the gABI ++ arguably requires the alignment and glibc ld.so ++ checks it. So to comply with the alignment ++ requirement but not waste file space, we adjust ++ p_offset for just this segment. (OFF_ADJUST is ++ subtracted from OFF later.) This may put p_offset ++ past the end of file, but that shouldn't matter. */ ++ } ++ else ++ off_adjust = 0; ++ } ++ /* Make sure the .dynamic section is the first section in the ++ PT_DYNAMIC segment. */ ++ else if (p->p_type == PT_DYNAMIC ++ && m->count > 1 ++ && strcmp (m->sections[0]->name, ".dynamic") != 0) ++ { ++ _bfd_error_handler ++ (_("%pB: The first section in the PT_DYNAMIC segment" ++ " is not the .dynamic section"), ++ abfd); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ /* Set the note section type to SHT_NOTE. */ ++ else if (p->p_type == PT_NOTE) ++ for (i = 0; i < m->count; i++) ++ elf_section_type (m->sections[i]) = SHT_NOTE; ++ ++ if (m->includes_filehdr) ++ { ++ if (!m->p_flags_valid) ++ p->p_flags |= PF_R; ++ p->p_filesz = bed->s->sizeof_ehdr; ++ p->p_memsz = bed->s->sizeof_ehdr; ++ if (p->p_type == PT_LOAD) ++ { ++ if (m->count > 0) ++ { ++ if (p->p_vaddr < (bfd_vma) off ++ || (!m->p_paddr_valid ++ && p->p_paddr < (bfd_vma) off)) ++ { ++ _bfd_error_handler ++ (_("%pB: not enough room for program headers," ++ " try linking with -N"), ++ abfd); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ p->p_vaddr -= off; ++ if (!m->p_paddr_valid) ++ p->p_paddr -= off; ++ } ++ } ++ else if (sorted_seg_map[0]->includes_filehdr) ++ { ++ Elf_Internal_Phdr *filehdr = phdrs + sorted_seg_map[0]->idx; ++ p->p_vaddr = filehdr->p_vaddr; ++ if (!m->p_paddr_valid) ++ p->p_paddr = filehdr->p_paddr; ++ } ++ } ++ ++ if (m->includes_phdrs) ++ { ++ if (!m->p_flags_valid) ++ p->p_flags |= PF_R; ++ p->p_filesz += actual * bed->s->sizeof_phdr; ++ p->p_memsz += actual * bed->s->sizeof_phdr; ++ if (!m->includes_filehdr) ++ { ++ if (p->p_type == PT_LOAD) ++ { ++ elf_elfheader (abfd)->e_phoff = p->p_offset; ++ if (m->count > 0) ++ { ++ p->p_vaddr -= off - p->p_offset; ++ if (!m->p_paddr_valid) ++ p->p_paddr -= off - p->p_offset; ++ } ++ } ++ else if (phdr_load_seg != NULL) ++ { ++ Elf_Internal_Phdr *phdr = phdrs + phdr_load_seg->idx; ++ bfd_vma phdr_off = 0; /* Octets. */ ++ if (phdr_load_seg->includes_filehdr) ++ phdr_off = bed->s->sizeof_ehdr; ++ p->p_vaddr = phdr->p_vaddr + phdr_off; ++ if (!m->p_paddr_valid) ++ p->p_paddr = phdr->p_paddr + phdr_off; ++ p->p_offset = phdr->p_offset + phdr_off; ++ } ++ else ++ p->p_offset = bed->s->sizeof_ehdr; ++ } ++ } ++ ++ if (p->p_type == PT_LOAD ++ || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)) ++ { ++ if (!m->includes_filehdr && !m->includes_phdrs) ++ { ++ p->p_offset = off; ++ if (no_contents) ++ { ++ /* Put meaningless p_offset for PT_LOAD segments ++ without file contents somewhere within the first ++ page, in an attempt to not point past EOF. */ ++ bfd_size_type align = maxpagesize; ++ if (align < p->p_align) ++ align = p->p_align; ++ if (align < 1) ++ align = 1; ++ p->p_offset = off % align; ++ } ++ } ++ else ++ { ++ file_ptr adjust; /* Octets. */ ++ ++ adjust = off - (p->p_offset + p->p_filesz); ++ if (!no_contents) ++ p->p_filesz += adjust; ++ p->p_memsz += adjust; ++ } ++ } ++ ++ /* Set up p_filesz, p_memsz, p_align and p_flags from the section ++ maps. Set filepos for sections in PT_LOAD segments, and in ++ core files, for sections in PT_NOTE segments. ++ assign_file_positions_for_non_load_sections will set filepos ++ for other sections and update p_filesz for other segments. */ ++ for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) ++ { ++ asection *sec; ++ bfd_size_type align; ++ Elf_Internal_Shdr *this_hdr; ++ ++ sec = *secpp; ++ this_hdr = &elf_section_data (sec)->this_hdr; ++ align = (bfd_size_type) 1 << bfd_section_alignment (sec); ++ ++ if ((p->p_type == PT_LOAD ++ || p->p_type == PT_TLS) ++ && (this_hdr->sh_type != SHT_NOBITS ++ || ((this_hdr->sh_flags & SHF_ALLOC) != 0 ++ && ((this_hdr->sh_flags & SHF_TLS) == 0 ++ || p->p_type == PT_TLS)))) ++ { ++ bfd_vma p_start = p->p_paddr; /* Octets. */ ++ bfd_vma p_end = p_start + p->p_memsz; /* Octets. */ ++ bfd_vma s_start = sec->lma * opb; /* Octets. */ ++ bfd_vma adjust = s_start - p_end; /* Octets. */ ++ ++ if (adjust != 0 ++ && (s_start < p_end ++ || p_end < p_start)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: section %pA lma %#" PRIx64 ++ " adjusted to %#" PRIx64), ++ abfd, sec, (uint64_t) s_start / opb, ++ (uint64_t) p_end / opb); ++ adjust = 0; ++ sec->lma = p_end / opb; ++ } ++ p->p_memsz += adjust; ++ ++ if (p->p_type == PT_LOAD) ++ { ++ if (this_hdr->sh_type != SHT_NOBITS) ++ { ++ off_adjust = 0; ++ if (p->p_filesz + adjust < p->p_memsz) ++ { ++ /* We have a PROGBITS section following NOBITS ones. ++ Allocate file space for the NOBITS section(s). ++ We don't need to write out the zeros, posix ++ fseek past the end of data already written ++ followed by a write at that location is ++ guaranteed to result in zeros being read ++ from the gap. */ ++ adjust = p->p_memsz - p->p_filesz; ++ } ++ } ++ /* We only adjust sh_offset in SHT_NOBITS sections ++ as would seem proper for their address when the ++ section is first in the segment. sh_offset ++ doesn't really have any significance for ++ SHT_NOBITS anyway, apart from a notional position ++ relative to other sections. Historically we ++ didn't bother with adjusting sh_offset and some ++ programs depend on it not being adjusted. See ++ pr12921 and pr25662. */ ++ if (this_hdr->sh_type != SHT_NOBITS || i == 0) ++ { ++ off += adjust; ++ if (this_hdr->sh_type == SHT_NOBITS) ++ off_adjust += adjust; ++ } ++ } ++ if (this_hdr->sh_type != SHT_NOBITS) ++ p->p_filesz += adjust; ++ } ++ ++ if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core) ++ { ++ /* The section at i == 0 is the one that actually contains ++ everything. */ ++ if (i == 0) ++ { ++ this_hdr->sh_offset = sec->filepos = off; ++ off += this_hdr->sh_size; ++ p->p_filesz = this_hdr->sh_size; ++ p->p_memsz = 0; ++ p->p_align = 1; ++ } ++ else ++ { ++ /* The rest are fake sections that shouldn't be written. */ ++ sec->filepos = 0; ++ sec->size = 0; ++ sec->flags = 0; ++ continue; ++ } ++ } ++ else ++ { ++ if (p->p_type == PT_LOAD) ++ { ++ this_hdr->sh_offset = sec->filepos = off; ++ if (this_hdr->sh_type != SHT_NOBITS) ++ off += this_hdr->sh_size; ++ } ++ else if (this_hdr->sh_type == SHT_NOBITS ++ && (this_hdr->sh_flags & SHF_TLS) != 0 ++ && this_hdr->sh_offset == 0) ++ { ++ /* This is a .tbss section that didn't get a PT_LOAD. ++ (See _bfd_elf_map_sections_to_segments "Create a ++ final PT_LOAD".) Set sh_offset to the value it ++ would have if we had created a zero p_filesz and ++ p_memsz PT_LOAD header for the section. This ++ also makes the PT_TLS header have the same ++ p_offset value. */ ++ bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr, ++ off, align); ++ this_hdr->sh_offset = sec->filepos = off + adjust; ++ } ++ ++ if (this_hdr->sh_type != SHT_NOBITS) ++ { ++ p->p_filesz += this_hdr->sh_size; ++ /* A load section without SHF_ALLOC is something like ++ a note section in a PT_NOTE segment. These take ++ file space but are not loaded into memory. */ ++ if ((this_hdr->sh_flags & SHF_ALLOC) != 0) ++ p->p_memsz += this_hdr->sh_size; ++ } ++ else if ((this_hdr->sh_flags & SHF_ALLOC) != 0) ++ { ++ if (p->p_type == PT_TLS) ++ p->p_memsz += this_hdr->sh_size; ++ ++ /* .tbss is special. It doesn't contribute to p_memsz of ++ normal segments. */ ++ else if ((this_hdr->sh_flags & SHF_TLS) == 0) ++ p->p_memsz += this_hdr->sh_size; ++ } ++ ++ if (align > p->p_align ++ && !m->p_align_valid ++ && (p->p_type != PT_LOAD ++ || (abfd->flags & D_PAGED) == 0)) ++ p->p_align = align; ++ } ++ ++ if (!m->p_flags_valid) ++ { ++ p->p_flags |= PF_R; ++ if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0) ++ p->p_flags |= PF_X; ++ if ((this_hdr->sh_flags & SHF_WRITE) != 0) ++ p->p_flags |= PF_W; ++ } ++ } ++ ++ off -= off_adjust; ++ ++ /* PR ld/20815 - Check that the program header segment, if ++ present, will be loaded into memory. */ ++ if (p->p_type == PT_PHDR ++ && phdr_load_seg == NULL ++ && !(bed->elf_backend_allow_non_load_phdr != NULL ++ && bed->elf_backend_allow_non_load_phdr (abfd, phdrs, alloc))) ++ { ++ /* The fix for this error is usually to edit the linker script being ++ used and set up the program headers manually. Either that or ++ leave room for the headers at the start of the SECTIONS. */ ++ _bfd_error_handler (_("%pB: error: PHDR segment not covered" ++ " by LOAD segment"), ++ abfd); ++ if (link_info == NULL) ++ return false; ++ /* Arrange for the linker to exit with an error, deleting ++ the output file unless --noinhibit-exec is given. */ ++ link_info->callbacks->info ("%X"); ++ } ++ ++ /* Check that all sections are in a PT_LOAD segment. ++ Don't check funky gdb generated core files. */ ++ if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core) ++ { ++ bool check_vma = true; ++ ++ for (i = 1; i < m->count; i++) ++ if (m->sections[i]->vma == m->sections[i - 1]->vma ++ && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i]) ++ ->this_hdr), p) != 0 ++ && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i - 1]) ++ ->this_hdr), p) != 0) ++ { ++ /* Looks like we have overlays packed into the segment. */ ++ check_vma = false; ++ break; ++ } ++ ++ for (i = 0; i < m->count; i++) ++ { ++ Elf_Internal_Shdr *this_hdr; ++ asection *sec; ++ ++ sec = m->sections[i]; ++ this_hdr = &(elf_section_data(sec)->this_hdr); ++ if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0) ++ && !ELF_TBSS_SPECIAL (this_hdr, p)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: section `%pA' can't be allocated in segment %d"), ++ abfd, sec, j); ++ print_segment_map (m); ++ } ++ } ++ ++ if (p_align_p) ++ p->p_align = p_align; ++ } ++ } ++ ++ elf_next_file_pos (abfd) = off; ++ ++ if (link_info != NULL ++ && phdr_load_seg != NULL ++ && phdr_load_seg->includes_filehdr) ++ { ++ /* There is a segment that contains both the file headers and the ++ program headers, so provide a symbol __ehdr_start pointing there. ++ A program can use this to examine itself robustly. */ ++ ++ struct elf_link_hash_entry *hash ++ = elf_link_hash_lookup (elf_hash_table (link_info), "__ehdr_start", ++ false, false, true); ++ /* If the symbol was referenced and not defined, define it. */ ++ if (hash != NULL ++ && (hash->root.type == bfd_link_hash_new ++ || hash->root.type == bfd_link_hash_undefined ++ || hash->root.type == bfd_link_hash_undefweak ++ || hash->root.type == bfd_link_hash_common)) ++ { ++ asection *s = NULL; ++ bfd_vma filehdr_vaddr = phdrs[phdr_load_seg->idx].p_vaddr / opb; ++ ++ if (phdr_load_seg->count != 0) ++ /* The segment contains sections, so use the first one. */ ++ s = phdr_load_seg->sections[0]; ++ else ++ /* Use the first (i.e. lowest-addressed) section in any segment. */ ++ for (m = elf_seg_map (abfd); m != NULL; m = m->next) ++ if (m->p_type == PT_LOAD && m->count != 0) ++ { ++ s = m->sections[0]; ++ break; ++ } ++ ++ if (s != NULL) ++ { ++ hash->root.u.def.value = filehdr_vaddr - s->vma; ++ hash->root.u.def.section = s; ++ } ++ else ++ { ++ hash->root.u.def.value = filehdr_vaddr; ++ hash->root.u.def.section = bfd_abs_section_ptr; ++ } ++ ++ hash->root.type = bfd_link_hash_defined; ++ hash->def_regular = 1; ++ hash->non_elf = 0; ++ } ++ } ++ ++ return true; ++} ++ ++/* Determine if a bfd is a debuginfo file. Unfortunately there ++ is no defined method for detecting such files, so we have to ++ use heuristics instead. */ ++ ++bool ++is_debuginfo_file (bfd *abfd) ++{ ++ if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_elf_flavour) ++ return false; ++ ++ Elf_Internal_Shdr **start_headers = elf_elfsections (abfd); ++ Elf_Internal_Shdr **end_headers = start_headers + elf_numsections (abfd); ++ Elf_Internal_Shdr **headerp; ++ ++ for (headerp = start_headers; headerp < end_headers; headerp ++) ++ { ++ Elf_Internal_Shdr *header = * headerp; ++ ++ /* Debuginfo files do not have any allocated SHT_PROGBITS sections. ++ The only allocated sections are SHT_NOBITS or SHT_NOTES. */ ++ if ((header->sh_flags & SHF_ALLOC) == SHF_ALLOC ++ && header->sh_type != SHT_NOBITS ++ && header->sh_type != SHT_NOTE) ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Assign file positions for other sections, except for compressed debug ++ and sections assigned in _bfd_elf_assign_file_positions_for_non_load. */ ++ ++static bool ++assign_file_positions_for_non_load_sections (bfd *abfd, ++ struct bfd_link_info *link_info) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ Elf_Internal_Shdr **i_shdrpp; ++ Elf_Internal_Shdr **hdrpp, **end_hdrpp; ++ Elf_Internal_Phdr *phdrs; ++ Elf_Internal_Phdr *p; ++ struct elf_segment_map *m; ++ file_ptr off; ++ unsigned int opb = bfd_octets_per_byte (abfd, NULL); ++ bfd_vma maxpagesize; ++ ++ if (link_info != NULL) ++ maxpagesize = link_info->maxpagesize; ++ else ++ maxpagesize = bed->maxpagesize; ++ i_shdrpp = elf_elfsections (abfd); ++ end_hdrpp = i_shdrpp + elf_numsections (abfd); ++ off = elf_next_file_pos (abfd); ++ for (hdrpp = i_shdrpp + 1; hdrpp < end_hdrpp; hdrpp++) ++ { ++ Elf_Internal_Shdr *hdr; ++ bfd_vma align; ++ ++ hdr = *hdrpp; ++ if (hdr->bfd_section != NULL ++ && (hdr->bfd_section->filepos != 0 ++ || (hdr->sh_type == SHT_NOBITS ++ && hdr->contents == NULL))) ++ BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos); ++ else if ((hdr->sh_flags & SHF_ALLOC) != 0) ++ { ++ if (hdr->sh_size != 0 ++ /* PR 24717 - debuginfo files are known to be not strictly ++ compliant with the ELF standard. In particular they often ++ have .note.gnu.property sections that are outside of any ++ loadable segment. This is not a problem for such files, ++ so do not warn about them. */ ++ && ! is_debuginfo_file (abfd)) ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: warning: allocated section `%s' not in segment"), ++ abfd, ++ (hdr->bfd_section == NULL ++ ? "*unknown*" ++ : hdr->bfd_section->name)); ++ /* We don't need to page align empty sections. */ ++ if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0) ++ align = maxpagesize; ++ else ++ align = hdr->sh_addralign & -hdr->sh_addralign; ++ off += vma_page_aligned_bias (hdr->sh_addr, off, align); ++ off = _bfd_elf_assign_file_position_for_section (hdr, off, ++ false); ++ } ++ else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) ++ && hdr->bfd_section == NULL) ++ /* We don't know the offset of these sections yet: ++ their size has not been decided. */ ++ || (abfd->is_linker_output ++ && hdr->bfd_section != NULL ++ && (hdr->sh_name == -1u ++ || bfd_section_is_ctf (hdr->bfd_section))) ++ || hdr == i_shdrpp[elf_onesymtab (abfd)] ++ || (elf_symtab_shndx_list (abfd) != NULL ++ && hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx]) ++ || hdr == i_shdrpp[elf_strtab_sec (abfd)] ++ || hdr == i_shdrpp[elf_shstrtab_sec (abfd)]) ++ hdr->sh_offset = -1; ++ else ++ off = _bfd_elf_assign_file_position_for_section (hdr, off, true); ++ } ++ elf_next_file_pos (abfd) = off; ++ ++ /* Now that we have set the section file positions, we can set up ++ the file positions for the non PT_LOAD segments. */ ++ phdrs = elf_tdata (abfd)->phdr; ++ for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++) ++ { ++ if (p->p_type == PT_GNU_RELRO) ++ { ++ bfd_vma start, end; /* Bytes. */ ++ bool ok; ++ ++ if (link_info != NULL) ++ { ++ /* During linking the range of the RELRO segment is passed ++ in link_info. Note that there may be padding between ++ relro_start and the first RELRO section. */ ++ start = link_info->relro_start; ++ end = link_info->relro_end; ++ } ++ else if (m->count != 0) ++ { ++ if (!m->p_size_valid) ++ abort (); ++ start = m->sections[0]->vma; ++ end = start + m->p_size / opb; ++ } ++ else ++ { ++ start = 0; ++ end = 0; ++ } ++ ++ ok = false; ++ if (start < end) ++ { ++ struct elf_segment_map *lm; ++ const Elf_Internal_Phdr *lp; ++ unsigned int i; ++ ++ /* Find a LOAD segment containing a section in the RELRO ++ segment. */ ++ for (lm = elf_seg_map (abfd), lp = phdrs; ++ lm != NULL; ++ lm = lm->next, lp++) ++ { ++ if (lp->p_type == PT_LOAD ++ && lm->count != 0 ++ && (lm->sections[lm->count - 1]->vma ++ + (!IS_TBSS (lm->sections[lm->count - 1]) ++ ? lm->sections[lm->count - 1]->size / opb ++ : 0)) > start ++ && lm->sections[0]->vma < end) ++ break; ++ } ++ ++ if (lm != NULL) ++ { ++ /* Find the section starting the RELRO segment. */ ++ for (i = 0; i < lm->count; i++) ++ { ++ asection *s = lm->sections[i]; ++ if (s->vma >= start ++ && s->vma < end ++ && s->size != 0) ++ break; ++ } ++ ++ if (i < lm->count) ++ { ++ p->p_vaddr = lm->sections[i]->vma * opb; ++ p->p_paddr = lm->sections[i]->lma * opb; ++ p->p_offset = lm->sections[i]->filepos; ++ p->p_memsz = end * opb - p->p_vaddr; ++ p->p_filesz = p->p_memsz; ++ ++ /* The RELRO segment typically ends a few bytes ++ into .got.plt but other layouts are possible. ++ In cases where the end does not match any ++ loaded section (for instance is in file ++ padding), trim p_filesz back to correspond to ++ the end of loaded section contents. */ ++ if (p->p_filesz > lp->p_vaddr + lp->p_filesz - p->p_vaddr) ++ p->p_filesz = lp->p_vaddr + lp->p_filesz - p->p_vaddr; ++ ++ /* Preserve the alignment and flags if they are ++ valid. The gold linker generates RW/4 for ++ the PT_GNU_RELRO section. It is better for ++ objcopy/strip to honor these attributes ++ otherwise gdb will choke when using separate ++ debug files. */ ++ if (!m->p_align_valid) ++ p->p_align = 1; ++ if (!m->p_flags_valid) ++ p->p_flags = PF_R; ++ ok = true; ++ } ++ } ++ } ++ ++ if (!ok) ++ { ++ if (link_info != NULL) ++ _bfd_error_handler ++ (_("%pB: warning: unable to allocate any sections" ++ " to PT_GNU_RELRO segment"), ++ abfd); ++ memset (p, 0, sizeof *p); ++ } ++ } ++ else if (p->p_type == PT_GNU_STACK) ++ { ++ if (m->p_size_valid) ++ p->p_memsz = m->p_size; ++ } ++ else if (m->count != 0) ++ { ++ unsigned int i; ++ ++ if (p->p_type != PT_LOAD ++ && (p->p_type != PT_NOTE ++ || bfd_get_format (abfd) != bfd_core)) ++ { ++ /* A user specified segment layout may include a PHDR ++ segment that overlaps with a LOAD segment... */ ++ if (p->p_type == PT_PHDR) ++ { ++ m->count = 0; ++ continue; ++ } ++ ++ if (m->includes_filehdr || m->includes_phdrs) ++ { ++ /* PR 17512: file: 2195325e. */ ++ _bfd_error_handler ++ (_("%pB: error: non-load segment %d includes file header " ++ "and/or program header"), ++ abfd, (int) (p - phdrs)); ++ return false; ++ } ++ ++ p->p_filesz = 0; ++ p->p_offset = m->sections[0]->filepos; ++ for (i = m->count; i-- != 0;) ++ { ++ asection *sect = m->sections[i]; ++ Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr; ++ if (hdr->sh_type != SHT_NOBITS) ++ { ++ p->p_filesz = sect->filepos - p->p_offset + hdr->sh_size; ++ /* NB: p_memsz of the loadable PT_NOTE segment ++ should be the same as p_filesz. */ ++ if (p->p_type == PT_NOTE ++ && (hdr->sh_flags & SHF_ALLOC) != 0) ++ p->p_memsz = p->p_filesz; ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ return true; ++} ++ ++static elf_section_list * ++find_section_in_list (unsigned int i, elf_section_list * list) ++{ ++ for (;list != NULL; list = list->next) ++ if (list->ndx == i) ++ break; ++ return list; ++} ++ ++/* Work out the file positions of all the sections. This is called by ++ _bfd_elf_compute_section_file_positions. All the section sizes and ++ VMAs must be known before this is called. ++ ++ Reloc sections come in two flavours: Those processed specially as ++ "side-channel" data attached to a section to which they apply, and ++ those that bfd doesn't process as relocations. The latter sort are ++ stored in a normal bfd section by bfd_section_from_shdr. We don't ++ consider the former sort here, unless they form part of the loadable ++ image. Reloc sections not assigned here (and compressed debugging ++ sections and CTF sections which nothing else in the file can rely ++ upon) will be handled later by assign_file_positions_for_relocs. ++ ++ We also don't set the positions of the .symtab and .strtab here. */ ++ ++static bool ++assign_file_positions_except_relocs (bfd *abfd, ++ struct bfd_link_info *link_info) ++{ ++ struct elf_obj_tdata *tdata = elf_tdata (abfd); ++ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd); ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ unsigned int alloc; ++ ++ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 ++ && bfd_get_format (abfd) != bfd_core) ++ { ++ Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); ++ unsigned int num_sec = elf_numsections (abfd); ++ Elf_Internal_Shdr **hdrpp; ++ unsigned int i; ++ file_ptr off; ++ ++ /* Start after the ELF header. */ ++ off = i_ehdrp->e_ehsize; ++ ++ /* We are not creating an executable, which means that we are ++ not creating a program header, and that the actual order of ++ the sections in the file is unimportant. */ ++ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) ++ { ++ Elf_Internal_Shdr *hdr; ++ ++ hdr = *hdrpp; ++ if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) ++ && hdr->bfd_section == NULL) ++ /* Do not assign offsets for these sections yet: we don't know ++ their sizes. */ ++ || (abfd->is_linker_output ++ && hdr->bfd_section != NULL ++ && (hdr->sh_name == -1u ++ || bfd_section_is_ctf (hdr->bfd_section))) ++ || i == elf_onesymtab (abfd) ++ || (elf_symtab_shndx_list (abfd) != NULL ++ && hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx]) ++ || i == elf_strtab_sec (abfd) ++ || i == elf_shstrtab_sec (abfd)) ++ { ++ hdr->sh_offset = -1; ++ } ++ else ++ off = _bfd_elf_assign_file_position_for_section (hdr, off, true); ++ } ++ ++ elf_next_file_pos (abfd) = off; ++ elf_program_header_size (abfd) = 0; ++ } ++ else ++ { ++ /* Assign file positions for the loaded sections based on the ++ assignment of sections to segments. */ ++ if (!assign_file_positions_for_load_sections (abfd, link_info)) ++ return false; ++ ++ /* And for non-load sections. */ ++ if (!assign_file_positions_for_non_load_sections (abfd, link_info)) ++ return false; ++ } ++ ++ if (!(*bed->elf_backend_modify_headers) (abfd, link_info)) ++ return false; ++ ++ /* Write out the program headers. */ ++ alloc = i_ehdrp->e_phnum; ++ if (alloc != 0) ++ { ++ if (link_info != NULL && ! link_info->no_warn_rwx_segments) ++ { ++ /* Memory resident segments with non-zero size and RWX ++ permissions are a security risk, so we generate a warning ++ here if we are creating any. */ ++ unsigned int i; ++ ++ for (i = 0; i < alloc; i++) ++ { ++ const Elf_Internal_Phdr * phdr = tdata->phdr + i; ++ ++ if (phdr->p_memsz == 0) ++ continue; ++ ++ if (phdr->p_type == PT_TLS && (phdr->p_flags & PF_X)) ++ _bfd_error_handler (_("warning: %pB has a TLS segment" ++ " with execute permission"), ++ abfd); ++ else if (phdr->p_type == PT_LOAD ++ && ((phdr->p_flags & (PF_R | PF_W | PF_X)) ++ == (PF_R | PF_W | PF_X))) ++ _bfd_error_handler (_("warning: %pB has a LOAD segment" ++ " with RWX permissions"), ++ abfd); ++ } ++ } ++ ++ if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0 ++ || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0) ++ return false; ++ } ++ ++ return true; ++} ++ ++bool ++_bfd_elf_init_file_header (bfd *abfd, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED) ++{ ++ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form. */ ++ struct elf_strtab_hash *shstrtab; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ i_ehdrp = elf_elfheader (abfd); ++ ++ shstrtab = _bfd_elf_strtab_init (); ++ if (shstrtab == NULL) ++ return false; ++ ++ elf_shstrtab (abfd) = shstrtab; ++ ++ i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; ++ i_ehdrp->e_ident[EI_MAG1] = ELFMAG1; ++ i_ehdrp->e_ident[EI_MAG2] = ELFMAG2; ++ i_ehdrp->e_ident[EI_MAG3] = ELFMAG3; ++ ++ i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass; ++ i_ehdrp->e_ident[EI_DATA] = ++ bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB; ++ i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current; ++ ++ if ((abfd->flags & DYNAMIC) != 0) ++ i_ehdrp->e_type = ET_DYN; ++ else if ((abfd->flags & EXEC_P) != 0) ++ i_ehdrp->e_type = ET_EXEC; ++ else if (bfd_get_format (abfd) == bfd_core) ++ i_ehdrp->e_type = ET_CORE; ++ else ++ i_ehdrp->e_type = ET_REL; ++ ++ switch (bfd_get_arch (abfd)) ++ { ++ case bfd_arch_unknown: ++ i_ehdrp->e_machine = EM_NONE; ++ break; ++ ++ /* There used to be a long list of cases here, each one setting ++ e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE ++ in the corresponding bfd definition. To avoid duplication, ++ the switch was removed. Machines that need special handling ++ can generally do it in elf_backend_final_write_processing(), ++ unless they need the information earlier than the final write. ++ Such need can generally be supplied by replacing the tests for ++ e_machine with the conditions used to determine it. */ ++ default: ++ i_ehdrp->e_machine = bed->elf_machine_code; ++ } ++ ++ i_ehdrp->e_version = bed->s->ev_current; ++ i_ehdrp->e_ehsize = bed->s->sizeof_ehdr; ++ ++ /* No program header, for now. */ ++ i_ehdrp->e_phoff = 0; ++ i_ehdrp->e_phentsize = 0; ++ i_ehdrp->e_phnum = 0; ++ ++ /* Each bfd section is section header entry. */ ++ i_ehdrp->e_entry = bfd_get_start_address (abfd); ++ i_ehdrp->e_shentsize = bed->s->sizeof_shdr; ++ ++ elf_tdata (abfd)->symtab_hdr.sh_name = ++ (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", false); ++ elf_tdata (abfd)->strtab_hdr.sh_name = ++ (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", false); ++ elf_tdata (abfd)->shstrtab_hdr.sh_name = ++ (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", false); ++ if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 ++ || elf_tdata (abfd)->strtab_hdr.sh_name == (unsigned int) -1 ++ || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1) ++ return false; ++ ++ return true; ++} ++ ++/* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=. ++ ++ FIXME: We used to have code here to sort the PT_LOAD segments into ++ ascending order, as per the ELF spec. But this breaks some programs, ++ including the Linux kernel. But really either the spec should be ++ changed or the programs updated. */ ++ ++bool ++_bfd_elf_modify_headers (bfd *obfd, struct bfd_link_info *link_info) ++{ ++ if (link_info != NULL && bfd_link_pie (link_info)) ++ { ++ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (obfd); ++ unsigned int num_segments = i_ehdrp->e_phnum; ++ struct elf_obj_tdata *tdata = elf_tdata (obfd); ++ Elf_Internal_Phdr *segment = tdata->phdr; ++ Elf_Internal_Phdr *end_segment = &segment[num_segments]; ++ ++ /* Find the lowest p_vaddr in PT_LOAD segments. */ ++ bfd_vma p_vaddr = (bfd_vma) -1; ++ for (; segment < end_segment; segment++) ++ if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr) ++ p_vaddr = segment->p_vaddr; ++ ++ /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD ++ segments is non-zero. */ ++ if (p_vaddr) ++ i_ehdrp->e_type = ET_EXEC; ++ } ++ return true; ++} ++ ++/* Assign file positions for all the reloc sections which are not part ++ of the loadable file image, and the file position of section headers. */ ++ ++static bool ++_bfd_elf_assign_file_positions_for_non_load (bfd *abfd) ++{ ++ file_ptr off; ++ Elf_Internal_Shdr **shdrpp, **end_shdrpp; ++ Elf_Internal_Shdr *shdrp; ++ Elf_Internal_Ehdr *i_ehdrp; ++ const struct elf_backend_data *bed; ++ ++ /* Skip non-load sections without section header. */ ++ if ((abfd->flags & BFD_NO_SECTION_HEADER) != 0) ++ return true; ++ ++ off = elf_next_file_pos (abfd); ++ ++ shdrpp = elf_elfsections (abfd); ++ end_shdrpp = shdrpp + elf_numsections (abfd); ++ for (shdrpp++; shdrpp < end_shdrpp; shdrpp++) ++ { ++ shdrp = *shdrpp; ++ if (shdrp->sh_offset == -1) ++ { ++ asection *sec = shdrp->bfd_section; ++ if (sec == NULL ++ || shdrp->sh_type == SHT_REL ++ || shdrp->sh_type == SHT_RELA) ++ ; ++ else if (bfd_section_is_ctf (sec)) ++ { ++ /* Update section size and contents. */ ++ shdrp->sh_size = sec->size; ++ shdrp->contents = sec->contents; ++ } ++ else if (shdrp->sh_name == -1u) ++ { ++ const char *name = sec->name; ++ struct bfd_elf_section_data *d; ++ ++ /* Compress DWARF debug sections. */ ++ if (!bfd_compress_section (abfd, sec, shdrp->contents)) ++ return false; ++ ++ if (sec->compress_status == COMPRESS_SECTION_DONE ++ && (abfd->flags & BFD_COMPRESS_GABI) == 0 ++ && name[1] == 'd') ++ { ++ /* If section is compressed with zlib-gnu, convert ++ section name from .debug_* to .zdebug_*. */ ++ char *new_name = bfd_debug_name_to_zdebug (abfd, name); ++ if (new_name == NULL) ++ return false; ++ name = new_name; ++ } ++ /* Add section name to section name section. */ ++ shdrp->sh_name ++ = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), ++ name, false); ++ d = elf_section_data (sec); ++ ++ /* Add reloc section name to section name section. */ ++ if (d->rel.hdr ++ && !_bfd_elf_set_reloc_sh_name (abfd, d->rel.hdr, ++ name, false)) ++ return false; ++ if (d->rela.hdr ++ && !_bfd_elf_set_reloc_sh_name (abfd, d->rela.hdr, ++ name, true)) ++ return false; ++ ++ /* Update section size and contents. */ ++ shdrp->sh_size = sec->size; ++ shdrp->contents = sec->contents; ++ sec->contents = NULL; ++ } ++ ++ off = _bfd_elf_assign_file_position_for_section (shdrp, off, true); ++ } ++ } ++ ++ /* Place section name section after DWARF debug sections have been ++ compressed. */ ++ _bfd_elf_strtab_finalize (elf_shstrtab (abfd)); ++ shdrp = &elf_tdata (abfd)->shstrtab_hdr; ++ shdrp->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd)); ++ off = _bfd_elf_assign_file_position_for_section (shdrp, off, true); ++ ++ /* Place the section headers. */ ++ i_ehdrp = elf_elfheader (abfd); ++ bed = get_elf_backend_data (abfd); ++ off = align_file_position (off, 1 << bed->s->log_file_align); ++ i_ehdrp->e_shoff = off; ++ off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; ++ elf_next_file_pos (abfd) = off; ++ ++ return true; ++} ++ ++bool ++_bfd_elf_write_object_contents (bfd *abfd) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ Elf_Internal_Shdr **i_shdrp; ++ bool failed; ++ unsigned int count, num_sec; ++ struct elf_obj_tdata *t; ++ ++ if (! abfd->output_has_begun ++ && ! _bfd_elf_compute_section_file_positions (abfd, NULL)) ++ return false; ++ /* Do not rewrite ELF data when the BFD has been opened for update. ++ abfd->output_has_begun was set to TRUE on opening, so creation of ++ new sections, and modification of existing section sizes was ++ restricted. This means the ELF header, program headers and ++ section headers can't have changed. If the contents of any ++ sections has been modified, then those changes have already been ++ written to the BFD. */ ++ else if (abfd->direction == both_direction) ++ { ++ BFD_ASSERT (abfd->output_has_begun); ++ return true; ++ } ++ ++ i_shdrp = elf_elfsections (abfd); ++ ++ failed = false; ++ bfd_map_over_sections (abfd, bed->s->write_relocs, &failed); ++ if (failed) ++ return false; ++ ++ if (!_bfd_elf_assign_file_positions_for_non_load (abfd)) ++ return false; ++ ++ /* After writing the headers, we need to write the sections too... */ ++ num_sec = elf_numsections (abfd); ++ for (count = 1; count < num_sec; count++) ++ { ++ /* Don't set the sh_name field without section header. */ ++ if ((abfd->flags & BFD_NO_SECTION_HEADER) == 0) ++ i_shdrp[count]->sh_name ++ = _bfd_elf_strtab_offset (elf_shstrtab (abfd), ++ i_shdrp[count]->sh_name); ++ if (bed->elf_backend_section_processing) ++ if (!(*bed->elf_backend_section_processing) (abfd, i_shdrp[count])) ++ return false; ++ if (i_shdrp[count]->contents) ++ { ++ bfd_size_type amt = i_shdrp[count]->sh_size; ++ ++ if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0 ++ || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt) ++ return false; ++ } ++ } ++ ++ /* Write out the section header names. */ ++ t = elf_tdata (abfd); ++ if (elf_shstrtab (abfd) != NULL ++ && t->shstrtab_hdr.sh_offset != -1 ++ && (bfd_seek (abfd, t->shstrtab_hdr.sh_offset, SEEK_SET) != 0 ++ || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd)))) ++ return false; ++ ++ if (!(*bed->elf_backend_final_write_processing) (abfd)) ++ return false; ++ ++ if (!bed->s->write_shdrs_and_ehdr (abfd)) ++ return false; ++ ++ /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0]. */ ++ if (t->o->build_id.after_write_object_contents != NULL ++ && !(*t->o->build_id.after_write_object_contents) (abfd)) ++ return false; ++ if (t->o->package_metadata.after_write_object_contents != NULL ++ && !(*t->o->package_metadata.after_write_object_contents) (abfd)) ++ return false; ++ ++ return true; ++} ++ ++bool ++_bfd_elf_write_corefile_contents (bfd *abfd) ++{ ++ /* Hopefully this can be done just like an object file. */ ++ return _bfd_elf_write_object_contents (abfd); ++} ++ ++/* Given a section, search the header to find them. */ ++ ++unsigned int ++_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect) ++{ ++ const struct elf_backend_data *bed; ++ unsigned int sec_index; ++ ++ if (elf_section_data (asect) != NULL ++ && elf_section_data (asect)->this_idx != 0) ++ return elf_section_data (asect)->this_idx; ++ ++ if (bfd_is_abs_section (asect)) ++ sec_index = SHN_ABS; ++ else if (bfd_is_com_section (asect)) ++ sec_index = SHN_COMMON; ++ else if (bfd_is_und_section (asect)) ++ sec_index = SHN_UNDEF; ++ else ++ sec_index = SHN_BAD; ++ ++ bed = get_elf_backend_data (abfd); ++ if (bed->elf_backend_section_from_bfd_section) ++ { ++ int retval = sec_index; ++ ++ if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval)) ++ return retval; ++ } ++ ++ if (sec_index == SHN_BAD) ++ bfd_set_error (bfd_error_nonrepresentable_section); ++ ++ return sec_index; ++} ++ ++/* Given a BFD symbol, return the index in the ELF symbol table, or -1 ++ on error. */ ++ ++int ++_bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr) ++{ ++ asymbol *asym_ptr = *asym_ptr_ptr; ++ int idx; ++ flagword flags = asym_ptr->flags; ++ ++ /* When gas creates relocations against local labels, it creates its ++ own symbol for the section, but does put the symbol into the ++ symbol chain, so udata is 0. When the linker is generating ++ relocatable output, this section symbol may be for one of the ++ input sections rather than the output section. */ ++ if (asym_ptr->udata.i == 0 ++ && (flags & BSF_SECTION_SYM) ++ && asym_ptr->section) ++ { ++ asection *sec; ++ ++ sec = asym_ptr->section; ++ if (sec->owner != abfd && sec->output_section != NULL) ++ sec = sec->output_section; ++ if (sec->owner == abfd ++ && sec->index < elf_num_section_syms (abfd) ++ && elf_section_syms (abfd)[sec->index] != NULL) ++ asym_ptr->udata.i = elf_section_syms (abfd)[sec->index]->udata.i; ++ } ++ ++ idx = asym_ptr->udata.i; ++ ++ if (idx == 0) ++ { ++ /* This case can occur when using --strip-symbol on a symbol ++ which is used in a relocation entry. */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: symbol `%s' required but not present"), ++ abfd, bfd_asymbol_name (asym_ptr)); ++ bfd_set_error (bfd_error_no_symbols); ++ return -1; ++ } ++ ++#if DEBUG & 4 ++ { ++ fprintf (stderr, ++ "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d," ++ " flags = 0x%.8x\n", ++ (long) asym_ptr, asym_ptr->name, idx, flags); ++ fflush (stderr); ++ } ++#endif ++ ++ return idx; ++} ++ ++static inline bfd_vma ++segment_size (Elf_Internal_Phdr *segment) ++{ ++ return (segment->p_memsz > segment->p_filesz ++ ? segment->p_memsz : segment->p_filesz); ++} ++ ++ ++/* Returns the end address of the segment + 1. */ ++static inline bfd_vma ++segment_end (Elf_Internal_Phdr *segment, bfd_vma start) ++{ ++ return start + segment_size (segment); ++} ++ ++static inline bfd_size_type ++section_size (asection *section, Elf_Internal_Phdr *segment) ++{ ++ if ((section->flags & SEC_HAS_CONTENTS) != 0 ++ || (section->flags & SEC_THREAD_LOCAL) == 0 ++ || segment->p_type == PT_TLS) ++ return section->size; ++ return 0; ++} ++ ++/* Returns TRUE if the given section is contained within the given ++ segment. LMA addresses are compared against PADDR when ++ USE_VADDR is false, VMA against VADDR when true. */ ++static bool ++is_contained_by (asection *section, Elf_Internal_Phdr *segment, ++ bfd_vma paddr, bfd_vma vaddr, unsigned int opb, ++ bool use_vaddr) ++{ ++ bfd_vma seg_addr = !use_vaddr ? paddr : vaddr; ++ bfd_vma addr = !use_vaddr ? section->lma : section->vma; ++ bfd_vma octet; ++ if (_bfd_mul_overflow (addr, opb, &octet)) ++ return false; ++ /* The third and fourth lines below are testing that the section end ++ address is within the segment. It's written this way to avoid ++ overflow. Add seg_addr + section_size to both sides of the ++ inequality to make it obvious. */ ++ return (octet >= seg_addr ++ && segment_size (segment) >= section_size (section, segment) ++ && (octet - seg_addr ++ <= segment_size (segment) - section_size (section, segment))); ++} ++ ++/* Handle PT_NOTE segment. */ ++static bool ++is_note (asection *s, Elf_Internal_Phdr *p) ++{ ++ return (p->p_type == PT_NOTE ++ && elf_section_type (s) == SHT_NOTE ++ && (ufile_ptr) s->filepos >= p->p_offset ++ && p->p_filesz >= s->size ++ && (ufile_ptr) s->filepos - p->p_offset <= p->p_filesz - s->size); ++} ++ ++/* Rewrite program header information. */ ++ ++static bool ++rewrite_elf_program_header (bfd *ibfd, bfd *obfd, bfd_vma maxpagesize) ++{ ++ Elf_Internal_Ehdr *iehdr; ++ struct elf_segment_map *map; ++ struct elf_segment_map *map_first; ++ struct elf_segment_map **pointer_to_map; ++ Elf_Internal_Phdr *segment; ++ asection *section; ++ unsigned int i; ++ unsigned int num_segments; ++ bool phdr_included = false; ++ bool p_paddr_valid; ++ struct elf_segment_map *phdr_adjust_seg = NULL; ++ unsigned int phdr_adjust_num = 0; ++ const struct elf_backend_data *bed; ++ unsigned int opb = bfd_octets_per_byte (ibfd, NULL); ++ ++ bed = get_elf_backend_data (ibfd); ++ iehdr = elf_elfheader (ibfd); ++ ++ map_first = NULL; ++ pointer_to_map = &map_first; ++ ++ num_segments = elf_elfheader (ibfd)->e_phnum; ++ ++ /* The complicated case when p_vaddr is 0 is to handle the Solaris ++ linker, which generates a PT_INTERP section with p_vaddr and ++ p_memsz set to 0. */ ++#define IS_SOLARIS_PT_INTERP(p, s) \ ++ (p->p_vaddr == 0 \ ++ && p->p_paddr == 0 \ ++ && p->p_memsz == 0 \ ++ && p->p_filesz > 0 \ ++ && (s->flags & SEC_HAS_CONTENTS) != 0 \ ++ && s->size > 0 \ ++ && (bfd_vma) s->filepos >= p->p_offset \ ++ && ((bfd_vma) s->filepos + s->size \ ++ <= p->p_offset + p->p_filesz)) ++ ++ /* Decide if the given section should be included in the given segment. ++ A section will be included if: ++ 1. It is within the address space of the segment -- we use the LMA ++ if that is set for the segment and the VMA otherwise, ++ 2. It is an allocated section or a NOTE section in a PT_NOTE ++ segment. ++ 3. There is an output section associated with it, ++ 4. The section has not already been allocated to a previous segment. ++ 5. PT_GNU_STACK segments do not include any sections. ++ 6. PT_TLS segment includes only SHF_TLS sections. ++ 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments. ++ 8. PT_DYNAMIC should not contain empty sections at the beginning ++ (with the possible exception of .dynamic). */ ++#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed, opb) \ ++ (((is_contained_by (section, segment, segment->p_paddr, \ ++ segment->p_vaddr, opb, \ ++ bed->want_p_paddr_set_to_zero) \ ++ && (section->flags & SEC_ALLOC) != 0) \ ++ || is_note (section, segment)) \ ++ && segment->p_type != PT_GNU_STACK \ ++ && (segment->p_type != PT_TLS \ ++ || (section->flags & SEC_THREAD_LOCAL)) \ ++ && (segment->p_type == PT_LOAD \ ++ || segment->p_type == PT_TLS \ ++ || (section->flags & SEC_THREAD_LOCAL) == 0) \ ++ && (segment->p_type != PT_DYNAMIC \ ++ || section_size (section, segment) > 0 \ ++ || (segment->p_paddr \ ++ ? segment->p_paddr != section->lma * (opb) \ ++ : segment->p_vaddr != section->vma * (opb)) \ ++ || (strcmp (bfd_section_name (section), ".dynamic") == 0)) \ ++ && (segment->p_type != PT_LOAD || !section->segment_mark)) ++ ++/* If the output section of a section in the input segment is NULL, ++ it is removed from the corresponding output segment. */ ++#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed, opb) \ ++ (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb) \ ++ && section->output_section != NULL) ++ ++ /* Returns TRUE iff seg1 starts after the end of seg2. */ ++#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field) \ ++ (seg1->field >= segment_end (seg2, seg2->field)) ++ ++ /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both ++ their VMA address ranges and their LMA address ranges overlap. ++ It is possible to have overlapping VMA ranges without overlapping LMA ++ ranges. RedBoot images for example can have both .data and .bss mapped ++ to the same VMA range, but with the .data section mapped to a different ++ LMA. */ ++#define SEGMENT_OVERLAPS(seg1, seg2) \ ++ ( !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr) \ ++ || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr)) \ ++ && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr) \ ++ || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr))) ++ ++ /* Initialise the segment mark field, and discard stupid alignment. */ ++ for (section = ibfd->sections; section != NULL; section = section->next) ++ { ++ asection *o = section->output_section; ++ if (o != NULL && o->alignment_power >= (sizeof (bfd_vma) * 8) - 1) ++ o->alignment_power = 0; ++ section->segment_mark = false; ++ } ++ ++ /* The Solaris linker creates program headers in which all the ++ p_paddr fields are zero. When we try to objcopy or strip such a ++ file, we get confused. Check for this case, and if we find it ++ don't set the p_paddr_valid fields. */ ++ p_paddr_valid = false; ++ for (i = 0, segment = elf_tdata (ibfd)->phdr; ++ i < num_segments; ++ i++, segment++) ++ if (segment->p_paddr != 0) ++ { ++ p_paddr_valid = true; ++ break; ++ } ++ ++ /* Scan through the segments specified in the program header ++ of the input BFD. For this first scan we look for overlaps ++ in the loadable segments. These can be created by weird ++ parameters to objcopy. Also, fix some solaris weirdness. */ ++ for (i = 0, segment = elf_tdata (ibfd)->phdr; ++ i < num_segments; ++ i++, segment++) ++ { ++ unsigned int j; ++ Elf_Internal_Phdr *segment2; ++ ++ if (segment->p_type == PT_INTERP) ++ for (section = ibfd->sections; section; section = section->next) ++ if (IS_SOLARIS_PT_INTERP (segment, section)) ++ { ++ /* Mininal change so that the normal section to segment ++ assignment code will work. */ ++ segment->p_vaddr = section->vma * opb; ++ break; ++ } ++ ++ if (segment->p_type != PT_LOAD) ++ { ++ /* Remove PT_GNU_RELRO segment. */ ++ if (segment->p_type == PT_GNU_RELRO) ++ segment->p_type = PT_NULL; ++ continue; ++ } ++ ++ /* Determine if this segment overlaps any previous segments. */ ++ for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++) ++ { ++ bfd_signed_vma extra_length; ++ ++ if (segment2->p_type != PT_LOAD ++ || !SEGMENT_OVERLAPS (segment, segment2)) ++ continue; ++ ++ /* Merge the two segments together. */ ++ if (segment2->p_vaddr < segment->p_vaddr) ++ { ++ /* Extend SEGMENT2 to include SEGMENT and then delete ++ SEGMENT. */ ++ extra_length = (segment_end (segment, segment->p_vaddr) ++ - segment_end (segment2, segment2->p_vaddr)); ++ ++ if (extra_length > 0) ++ { ++ segment2->p_memsz += extra_length; ++ segment2->p_filesz += extra_length; ++ } ++ ++ segment->p_type = PT_NULL; ++ ++ /* Since we have deleted P we must restart the outer loop. */ ++ i = 0; ++ segment = elf_tdata (ibfd)->phdr; ++ break; ++ } ++ else ++ { ++ /* Extend SEGMENT to include SEGMENT2 and then delete ++ SEGMENT2. */ ++ extra_length = (segment_end (segment2, segment2->p_vaddr) ++ - segment_end (segment, segment->p_vaddr)); ++ ++ if (extra_length > 0) ++ { ++ segment->p_memsz += extra_length; ++ segment->p_filesz += extra_length; ++ } ++ ++ segment2->p_type = PT_NULL; ++ } ++ } ++ } ++ ++ /* The second scan attempts to assign sections to segments. */ ++ for (i = 0, segment = elf_tdata (ibfd)->phdr; ++ i < num_segments; ++ i++, segment++) ++ { ++ unsigned int section_count; ++ asection **sections; ++ asection *output_section; ++ unsigned int isec; ++ asection *matching_lma; ++ asection *suggested_lma; ++ unsigned int j; ++ size_t amt; ++ asection *first_section; ++ ++ if (segment->p_type == PT_NULL) ++ continue; ++ ++ first_section = NULL; ++ /* Compute how many sections might be placed into this segment. */ ++ for (section = ibfd->sections, section_count = 0; ++ section != NULL; ++ section = section->next) ++ { ++ /* Find the first section in the input segment, which may be ++ removed from the corresponding output segment. */ ++ if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb)) ++ { ++ if (first_section == NULL) ++ first_section = section; ++ if (section->output_section != NULL) ++ ++section_count; ++ } ++ } ++ ++ /* Allocate a segment map big enough to contain ++ all of the sections we have selected. */ ++ amt = sizeof (struct elf_segment_map) - sizeof (asection *); ++ amt += section_count * sizeof (asection *); ++ map = (struct elf_segment_map *) bfd_zalloc (obfd, amt); ++ if (map == NULL) ++ return false; ++ ++ /* Initialise the fields of the segment map. Default to ++ using the physical address of the segment in the input BFD. */ ++ map->next = NULL; ++ map->p_type = segment->p_type; ++ map->p_flags = segment->p_flags; ++ map->p_flags_valid = 1; ++ ++ if (map->p_type == PT_LOAD ++ && (ibfd->flags & D_PAGED) != 0 ++ && maxpagesize > 1 ++ && segment->p_align > 1) ++ { ++ map->p_align = segment->p_align; ++ if (segment->p_align > maxpagesize) ++ map->p_align = maxpagesize; ++ map->p_align_valid = 1; ++ } ++ ++ /* If the first section in the input segment is removed, there is ++ no need to preserve segment physical address in the corresponding ++ output segment. */ ++ if (!first_section || first_section->output_section != NULL) ++ { ++ map->p_paddr = segment->p_paddr; ++ map->p_paddr_valid = p_paddr_valid; ++ } ++ ++ /* Determine if this segment contains the ELF file header ++ and if it contains the program headers themselves. */ ++ map->includes_filehdr = (segment->p_offset == 0 ++ && segment->p_filesz >= iehdr->e_ehsize); ++ map->includes_phdrs = 0; ++ ++ if (!phdr_included || segment->p_type != PT_LOAD) ++ { ++ map->includes_phdrs = ++ (segment->p_offset <= (bfd_vma) iehdr->e_phoff ++ && (segment->p_offset + segment->p_filesz ++ >= ((bfd_vma) iehdr->e_phoff ++ + iehdr->e_phnum * iehdr->e_phentsize))); ++ ++ if (segment->p_type == PT_LOAD && map->includes_phdrs) ++ phdr_included = true; ++ } ++ ++ if (section_count == 0) ++ { ++ /* Special segments, such as the PT_PHDR segment, may contain ++ no sections, but ordinary, loadable segments should contain ++ something. They are allowed by the ELF spec however, so only ++ a warning is produced. ++ Don't warn if an empty PT_LOAD contains the program headers. ++ There is however the valid use case of embedded systems which ++ have segments with p_filesz of 0 and a p_memsz > 0 to initialize ++ flash memory with zeros. No warning is shown for that case. */ ++ if (segment->p_type == PT_LOAD ++ && !map->includes_phdrs ++ && (segment->p_filesz > 0 || segment->p_memsz == 0)) ++ /* xgettext:c-format */ ++ _bfd_error_handler ++ (_("%pB: warning: empty loadable segment detected" ++ " at vaddr=%#" PRIx64 ", is this intentional?"), ++ ibfd, (uint64_t) segment->p_vaddr); ++ ++ map->p_vaddr_offset = segment->p_vaddr / opb; ++ map->count = 0; ++ *pointer_to_map = map; ++ pointer_to_map = &map->next; ++ ++ continue; ++ } ++ ++ /* Now scan the sections in the input BFD again and attempt ++ to add their corresponding output sections to the segment map. ++ The problem here is how to handle an output section which has ++ been moved (ie had its LMA changed). There are four possibilities: ++ ++ 1. None of the sections have been moved. ++ In this case we can continue to use the segment LMA from the ++ input BFD. ++ ++ 2. All of the sections have been moved by the same amount. ++ In this case we can change the segment's LMA to match the LMA ++ of the first section. ++ ++ 3. Some of the sections have been moved, others have not. ++ In this case those sections which have not been moved can be ++ placed in the current segment which will have to have its size, ++ and possibly its LMA changed, and a new segment or segments will ++ have to be created to contain the other sections. ++ ++ 4. The sections have been moved, but not by the same amount. ++ In this case we can change the segment's LMA to match the LMA ++ of the first section and we will have to create a new segment ++ or segments to contain the other sections. ++ ++ In order to save time, we allocate an array to hold the section ++ pointers that we are interested in. As these sections get assigned ++ to a segment, they are removed from this array. */ ++ ++ amt = section_count * sizeof (asection *); ++ sections = (asection **) bfd_malloc (amt); ++ if (sections == NULL) ++ return false; ++ ++ /* Step One: Scan for segment vs section LMA conflicts. ++ Also add the sections to the section array allocated above. ++ Also add the sections to the current segment. In the common ++ case, where the sections have not been moved, this means that ++ we have completely filled the segment, and there is nothing ++ more to do. */ ++ isec = 0; ++ matching_lma = NULL; ++ suggested_lma = NULL; ++ ++ for (section = first_section, j = 0; ++ section != NULL; ++ section = section->next) ++ { ++ if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed, opb)) ++ { ++ output_section = section->output_section; ++ ++ sections[j++] = section; ++ ++ /* The Solaris native linker always sets p_paddr to 0. ++ We try to catch that case here, and set it to the ++ correct value. Note - some backends require that ++ p_paddr be left as zero. */ ++ if (!p_paddr_valid ++ && segment->p_vaddr != 0 ++ && !bed->want_p_paddr_set_to_zero ++ && isec == 0 ++ && output_section->lma != 0 ++ && (align_power (segment->p_vaddr ++ + (map->includes_filehdr ++ ? iehdr->e_ehsize : 0) ++ + (map->includes_phdrs ++ ? iehdr->e_phnum * iehdr->e_phentsize ++ : 0), ++ output_section->alignment_power * opb) ++ == (output_section->vma * opb))) ++ map->p_paddr = segment->p_vaddr; ++ ++ /* Match up the physical address of the segment with the ++ LMA address of the output section. */ ++ if (is_contained_by (output_section, segment, map->p_paddr, ++ 0, opb, false) ++ || is_note (section, segment)) ++ { ++ if (matching_lma == NULL ++ || output_section->lma < matching_lma->lma) ++ matching_lma = output_section; ++ ++ /* We assume that if the section fits within the segment ++ then it does not overlap any other section within that ++ segment. */ ++ map->sections[isec++] = output_section; ++ } ++ else if (suggested_lma == NULL) ++ suggested_lma = output_section; ++ ++ if (j == section_count) ++ break; ++ } ++ } ++ ++ BFD_ASSERT (j == section_count); ++ ++ /* Step Two: Adjust the physical address of the current segment, ++ if necessary. */ ++ if (isec == section_count) ++ { ++ /* All of the sections fitted within the segment as currently ++ specified. This is the default case. Add the segment to ++ the list of built segments and carry on to process the next ++ program header in the input BFD. */ ++ map->count = section_count; ++ *pointer_to_map = map; ++ pointer_to_map = &map->next; ++ ++ if (p_paddr_valid ++ && !bed->want_p_paddr_set_to_zero) ++ { ++ bfd_vma hdr_size = 0; ++ if (map->includes_filehdr) ++ hdr_size = iehdr->e_ehsize; ++ if (map->includes_phdrs) ++ hdr_size += iehdr->e_phnum * iehdr->e_phentsize; ++ ++ /* Account for padding before the first section in the ++ segment. */ ++ map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb ++ - matching_lma->lma); ++ } ++ ++ free (sections); ++ continue; ++ } ++ else ++ { ++ /* Change the current segment's physical address to match ++ the LMA of the first section that fitted, or if no ++ section fitted, the first section. */ ++ if (matching_lma == NULL) ++ matching_lma = suggested_lma; ++ ++ map->p_paddr = matching_lma->lma * opb; ++ ++ /* Offset the segment physical address from the lma ++ to allow for space taken up by elf headers. */ ++ if (map->includes_phdrs) ++ { ++ map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize; ++ ++ /* iehdr->e_phnum is just an estimate of the number ++ of program headers that we will need. Make a note ++ here of the number we used and the segment we chose ++ to hold these headers, so that we can adjust the ++ offset when we know the correct value. */ ++ phdr_adjust_num = iehdr->e_phnum; ++ phdr_adjust_seg = map; ++ } ++ ++ if (map->includes_filehdr) ++ { ++ bfd_vma align = (bfd_vma) 1 << matching_lma->alignment_power; ++ map->p_paddr -= iehdr->e_ehsize; ++ /* We've subtracted off the size of headers from the ++ first section lma, but there may have been some ++ alignment padding before that section too. Try to ++ account for that by adjusting the segment lma down to ++ the same alignment. */ ++ if (segment->p_align != 0 && segment->p_align < align) ++ align = segment->p_align; ++ map->p_paddr &= -(align * opb); ++ } ++ } ++ ++ /* Step Three: Loop over the sections again, this time assigning ++ those that fit to the current segment and removing them from the ++ sections array; but making sure not to leave large gaps. Once all ++ possible sections have been assigned to the current segment it is ++ added to the list of built segments and if sections still remain ++ to be assigned, a new segment is constructed before repeating ++ the loop. */ ++ isec = 0; ++ do ++ { ++ map->count = 0; ++ suggested_lma = NULL; ++ ++ /* Fill the current segment with sections that fit. */ ++ for (j = 0; j < section_count; j++) ++ { ++ section = sections[j]; ++ ++ if (section == NULL) ++ continue; ++ ++ output_section = section->output_section; ++ ++ BFD_ASSERT (output_section != NULL); ++ ++ if (is_contained_by (output_section, segment, map->p_paddr, ++ 0, opb, false) ++ || is_note (section, segment)) ++ { ++ if (map->count == 0) ++ { ++ /* If the first section in a segment does not start at ++ the beginning of the segment, then something is ++ wrong. */ ++ if (align_power (map->p_paddr ++ + (map->includes_filehdr ++ ? iehdr->e_ehsize : 0) ++ + (map->includes_phdrs ++ ? iehdr->e_phnum * iehdr->e_phentsize ++ : 0), ++ output_section->alignment_power * opb) ++ != output_section->lma * opb) ++ goto sorry; ++ } ++ else ++ { ++ asection *prev_sec; ++ ++ prev_sec = map->sections[map->count - 1]; ++ ++ /* If the gap between the end of the previous section ++ and the start of this section is more than ++ maxpagesize then we need to start a new segment. */ ++ if ((BFD_ALIGN (prev_sec->lma + prev_sec->size, ++ maxpagesize) ++ < BFD_ALIGN (output_section->lma, maxpagesize)) ++ || (prev_sec->lma + prev_sec->size ++ > output_section->lma)) ++ { ++ if (suggested_lma == NULL) ++ suggested_lma = output_section; ++ ++ continue; ++ } ++ } ++ ++ map->sections[map->count++] = output_section; ++ ++isec; ++ sections[j] = NULL; ++ if (segment->p_type == PT_LOAD) ++ section->segment_mark = true; ++ } ++ else if (suggested_lma == NULL) ++ suggested_lma = output_section; ++ } ++ ++ /* PR 23932. A corrupt input file may contain sections that cannot ++ be assigned to any segment - because for example they have a ++ negative size - or segments that do not contain any sections. ++ But there are also valid reasons why a segment can be empty. ++ So allow a count of zero. */ ++ ++ /* Add the current segment to the list of built segments. */ ++ *pointer_to_map = map; ++ pointer_to_map = &map->next; ++ ++ if (isec < section_count) ++ { ++ /* We still have not allocated all of the sections to ++ segments. Create a new segment here, initialise it ++ and carry on looping. */ ++ amt = sizeof (struct elf_segment_map) - sizeof (asection *); ++ amt += section_count * sizeof (asection *); ++ map = (struct elf_segment_map *) bfd_zalloc (obfd, amt); ++ if (map == NULL) ++ { ++ free (sections); ++ return false; ++ } ++ ++ /* Initialise the fields of the segment map. Set the physical ++ physical address to the LMA of the first section that has ++ not yet been assigned. */ ++ map->next = NULL; ++ map->p_type = segment->p_type; ++ map->p_flags = segment->p_flags; ++ map->p_flags_valid = 1; ++ map->p_paddr = suggested_lma->lma * opb; ++ map->p_paddr_valid = p_paddr_valid; ++ map->includes_filehdr = 0; ++ map->includes_phdrs = 0; ++ } ++ ++ continue; ++ sorry: ++ bfd_set_error (bfd_error_sorry); ++ free (sections); ++ return false; ++ } ++ while (isec < section_count); ++ ++ free (sections); ++ } ++ ++ elf_seg_map (obfd) = map_first; ++ ++ /* If we had to estimate the number of program headers that were ++ going to be needed, then check our estimate now and adjust ++ the offset if necessary. */ ++ if (phdr_adjust_seg != NULL) ++ { ++ unsigned int count; ++ ++ for (count = 0, map = map_first; map != NULL; map = map->next) ++ count++; ++ ++ if (count > phdr_adjust_num) ++ phdr_adjust_seg->p_paddr ++ -= (count - phdr_adjust_num) * iehdr->e_phentsize; ++ ++ for (map = map_first; map != NULL; map = map->next) ++ if (map->p_type == PT_PHDR) ++ { ++ bfd_vma adjust ++ = phdr_adjust_seg->includes_filehdr ? iehdr->e_ehsize : 0; ++ map->p_paddr = phdr_adjust_seg->p_paddr + adjust; ++ break; ++ } ++ } ++ ++#undef IS_SOLARIS_PT_INTERP ++#undef IS_SECTION_IN_INPUT_SEGMENT ++#undef INCLUDE_SECTION_IN_SEGMENT ++#undef SEGMENT_AFTER_SEGMENT ++#undef SEGMENT_OVERLAPS ++ return true; ++} ++ ++/* Return true if p_align in the ELF program header in ABFD is valid. */ ++ ++static bool ++elf_is_p_align_valid (bfd *abfd) ++{ ++ unsigned int i; ++ Elf_Internal_Phdr *segment; ++ unsigned int num_segments; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ bfd_size_type maxpagesize = bed->maxpagesize; ++ bfd_size_type p_align = bed->p_align; ++ ++ /* Return true if the default p_align value isn't set or the maximum ++ page size is the same as the minimum page size. */ ++ if (p_align == 0 || maxpagesize == bed->minpagesize) ++ return true; ++ ++ /* When the default p_align value is set, p_align may be set to the ++ default p_align value while segments are aligned to the maximum ++ page size. In this case, the input p_align will be ignored and ++ the maximum page size will be used to align the output segments. */ ++ segment = elf_tdata (abfd)->phdr; ++ num_segments = elf_elfheader (abfd)->e_phnum; ++ for (i = 0; i < num_segments; i++, segment++) ++ if (segment->p_type == PT_LOAD ++ && (segment->p_align != p_align ++ || vma_page_aligned_bias (segment->p_vaddr, ++ segment->p_offset, ++ maxpagesize) != 0)) ++ return true; ++ ++ return false; ++} ++ ++/* Copy ELF program header information. */ ++ ++static bool ++copy_elf_program_header (bfd *ibfd, bfd *obfd) ++{ ++ Elf_Internal_Ehdr *iehdr; ++ struct elf_segment_map *map; ++ struct elf_segment_map *map_first; ++ struct elf_segment_map **pointer_to_map; ++ Elf_Internal_Phdr *segment; ++ unsigned int i; ++ unsigned int num_segments; ++ bool phdr_included = false; ++ bool p_paddr_valid; ++ bool p_palign_valid; ++ unsigned int opb = bfd_octets_per_byte (ibfd, NULL); ++ ++ iehdr = elf_elfheader (ibfd); ++ ++ map_first = NULL; ++ pointer_to_map = &map_first; ++ ++ /* If all the segment p_paddr fields are zero, don't set ++ map->p_paddr_valid. */ ++ p_paddr_valid = false; ++ num_segments = elf_elfheader (ibfd)->e_phnum; ++ for (i = 0, segment = elf_tdata (ibfd)->phdr; ++ i < num_segments; ++ i++, segment++) ++ if (segment->p_paddr != 0) ++ { ++ p_paddr_valid = true; ++ break; ++ } ++ ++ p_palign_valid = elf_is_p_align_valid (ibfd); ++ ++ for (i = 0, segment = elf_tdata (ibfd)->phdr; ++ i < num_segments; ++ i++, segment++) ++ { ++ asection *section; ++ unsigned int section_count; ++ size_t amt; ++ Elf_Internal_Shdr *this_hdr; ++ asection *first_section = NULL; ++ asection *lowest_section; ++ ++ /* Compute how many sections are in this segment. */ ++ for (section = ibfd->sections, section_count = 0; ++ section != NULL; ++ section = section->next) ++ { ++ this_hdr = &(elf_section_data(section)->this_hdr); ++ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) ++ { ++ if (first_section == NULL) ++ first_section = section; ++ section_count++; ++ } ++ } ++ ++ /* Allocate a segment map big enough to contain ++ all of the sections we have selected. */ ++ amt = sizeof (struct elf_segment_map) - sizeof (asection *); ++ amt += section_count * sizeof (asection *); ++ map = (struct elf_segment_map *) bfd_zalloc (obfd, amt); ++ if (map == NULL) ++ return false; ++ ++ /* Initialize the fields of the output segment map with the ++ input segment. */ ++ map->next = NULL; ++ map->p_type = segment->p_type; ++ map->p_flags = segment->p_flags; ++ map->p_flags_valid = 1; ++ map->p_paddr = segment->p_paddr; ++ map->p_paddr_valid = p_paddr_valid; ++ map->p_align = segment->p_align; ++ /* Keep p_align of PT_GNU_STACK for stack alignment. */ ++ map->p_align_valid = (map->p_type == PT_GNU_STACK ++ || p_palign_valid); ++ map->p_vaddr_offset = 0; ++ ++ if (map->p_type == PT_GNU_RELRO ++ || map->p_type == PT_GNU_STACK) ++ { ++ /* The PT_GNU_RELRO segment may contain the first a few ++ bytes in the .got.plt section even if the whole .got.plt ++ section isn't in the PT_GNU_RELRO segment. We won't ++ change the size of the PT_GNU_RELRO segment. ++ Similarly, PT_GNU_STACK size is significant on uclinux ++ systems. */ ++ map->p_size = segment->p_memsz; ++ map->p_size_valid = 1; ++ } ++ ++ /* Determine if this segment contains the ELF file header ++ and if it contains the program headers themselves. */ ++ map->includes_filehdr = (segment->p_offset == 0 ++ && segment->p_filesz >= iehdr->e_ehsize); ++ ++ map->includes_phdrs = 0; ++ if (! phdr_included || segment->p_type != PT_LOAD) ++ { ++ map->includes_phdrs = ++ (segment->p_offset <= (bfd_vma) iehdr->e_phoff ++ && (segment->p_offset + segment->p_filesz ++ >= ((bfd_vma) iehdr->e_phoff ++ + iehdr->e_phnum * iehdr->e_phentsize))); ++ ++ if (segment->p_type == PT_LOAD && map->includes_phdrs) ++ phdr_included = true; ++ } ++ ++ lowest_section = NULL; ++ if (section_count != 0) ++ { ++ unsigned int isec = 0; ++ ++ for (section = first_section; ++ section != NULL; ++ section = section->next) ++ { ++ this_hdr = &(elf_section_data(section)->this_hdr); ++ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) ++ { ++ map->sections[isec++] = section->output_section; ++ if ((section->flags & SEC_ALLOC) != 0) ++ { ++ bfd_vma seg_off; ++ ++ if (lowest_section == NULL ++ || section->lma < lowest_section->lma) ++ lowest_section = section; ++ ++ /* Section lmas are set up from PT_LOAD header ++ p_paddr in _bfd_elf_make_section_from_shdr. ++ If this header has a p_paddr that disagrees ++ with the section lma, flag the p_paddr as ++ invalid. */ ++ if ((section->flags & SEC_LOAD) != 0) ++ seg_off = this_hdr->sh_offset - segment->p_offset; ++ else ++ seg_off = this_hdr->sh_addr - segment->p_vaddr; ++ if (section->lma * opb - segment->p_paddr != seg_off) ++ map->p_paddr_valid = false; ++ } ++ if (isec == section_count) ++ break; ++ } ++ } ++ } ++ ++ if (section_count == 0) ++ map->p_vaddr_offset = segment->p_vaddr / opb; ++ else if (map->p_paddr_valid) ++ { ++ /* Account for padding before the first section in the segment. */ ++ bfd_vma hdr_size = 0; ++ if (map->includes_filehdr) ++ hdr_size = iehdr->e_ehsize; ++ if (map->includes_phdrs) ++ hdr_size += iehdr->e_phnum * iehdr->e_phentsize; ++ ++ map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb ++ - (lowest_section ? lowest_section->lma : 0)); ++ } ++ ++ map->count = section_count; ++ *pointer_to_map = map; ++ pointer_to_map = &map->next; ++ } ++ ++ elf_seg_map (obfd) = map_first; ++ return true; ++} ++ ++/* Copy private BFD data. This copies or rewrites ELF program header ++ information. */ ++ ++static bool ++copy_private_bfd_data (bfd *ibfd, bfd *obfd) ++{ ++ bfd_vma maxpagesize; ++ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour ++ || bfd_get_flavour (obfd) != bfd_target_elf_flavour) ++ return true; ++ ++ if (elf_tdata (ibfd)->phdr == NULL) ++ return true; ++ ++ if (ibfd->xvec == obfd->xvec) ++ { ++ /* Check to see if any sections in the input BFD ++ covered by ELF program header have changed. */ ++ Elf_Internal_Phdr *segment; ++ asection *section, *osec; ++ unsigned int i, num_segments; ++ Elf_Internal_Shdr *this_hdr; ++ const struct elf_backend_data *bed; ++ ++ bed = get_elf_backend_data (ibfd); ++ ++ /* Regenerate the segment map if p_paddr is set to 0. */ ++ if (bed->want_p_paddr_set_to_zero) ++ goto rewrite; ++ ++ /* Initialize the segment mark field. */ ++ for (section = obfd->sections; section != NULL; ++ section = section->next) ++ section->segment_mark = false; ++ ++ num_segments = elf_elfheader (ibfd)->e_phnum; ++ for (i = 0, segment = elf_tdata (ibfd)->phdr; ++ i < num_segments; ++ i++, segment++) ++ { ++ /* PR binutils/3535. The Solaris linker always sets the p_paddr ++ and p_memsz fields of special segments (DYNAMIC, INTERP) to 0 ++ which severly confuses things, so always regenerate the segment ++ map in this case. */ ++ if (segment->p_paddr == 0 ++ && segment->p_memsz == 0 ++ && (segment->p_type == PT_INTERP ++ || segment->p_type == PT_DYNAMIC)) ++ goto rewrite; ++ ++ for (section = ibfd->sections; ++ section != NULL; section = section->next) ++ { ++ /* We mark the output section so that we know it comes ++ from the input BFD. */ ++ osec = section->output_section; ++ if (osec) ++ osec->segment_mark = true; ++ ++ /* Check if this section is covered by the segment. */ ++ this_hdr = &(elf_section_data(section)->this_hdr); ++ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) ++ { ++ /* FIXME: Check if its output section is changed or ++ removed. What else do we need to check? */ ++ if (osec == NULL ++ || section->flags != osec->flags ++ || section->lma != osec->lma ++ || section->vma != osec->vma ++ || section->size != osec->size ++ || section->rawsize != osec->rawsize ++ || section->alignment_power != osec->alignment_power) ++ goto rewrite; ++ } ++ } ++ } ++ ++ /* Check to see if any output section do not come from the ++ input BFD. */ ++ for (section = obfd->sections; section != NULL; ++ section = section->next) ++ { ++ if (!section->segment_mark) ++ goto rewrite; ++ else ++ section->segment_mark = false; ++ } ++ ++ return copy_elf_program_header (ibfd, obfd); ++ } ++ ++ rewrite: ++ maxpagesize = 0; ++ if (ibfd->xvec == obfd->xvec) ++ { ++ /* When rewriting program header, set the output maxpagesize to ++ the maximum alignment of input PT_LOAD segments. */ ++ Elf_Internal_Phdr *segment; ++ unsigned int i; ++ unsigned int num_segments = elf_elfheader (ibfd)->e_phnum; ++ ++ for (i = 0, segment = elf_tdata (ibfd)->phdr; ++ i < num_segments; ++ i++, segment++) ++ if (segment->p_type == PT_LOAD ++ && maxpagesize < segment->p_align) ++ { ++ /* PR 17512: file: f17299af. */ ++ if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2)) ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: warning: segment alignment of %#" ++ PRIx64 " is too large"), ++ ibfd, (uint64_t) segment->p_align); ++ else ++ maxpagesize = segment->p_align; ++ } ++ } ++ if (maxpagesize == 0) ++ maxpagesize = get_elf_backend_data (obfd)->maxpagesize; ++ ++ return rewrite_elf_program_header (ibfd, obfd, maxpagesize); ++} ++ ++/* Initialize private output section information from input section. */ ++ ++bool ++_bfd_elf_init_private_section_data (bfd *ibfd, ++ asection *isec, ++ bfd *obfd, ++ asection *osec, ++ struct bfd_link_info *link_info) ++ ++{ ++ Elf_Internal_Shdr *ihdr, *ohdr; ++ bool final_link = (link_info != NULL ++ && !bfd_link_relocatable (link_info)); ++ ++ if (ibfd->xvec->flavour != bfd_target_elf_flavour ++ || obfd->xvec->flavour != bfd_target_elf_flavour) ++ return true; ++ ++ BFD_ASSERT (elf_section_data (osec) != NULL); ++ ++ /* If this is a known ABI section, ELF section type and flags may ++ have been set up when OSEC was created. For normal sections we ++ allow the user to override the type and flags other than ++ SHF_MASKOS and SHF_MASKPROC. */ ++ if (elf_section_type (osec) == SHT_PROGBITS ++ || elf_section_type (osec) == SHT_NOTE ++ || elf_section_type (osec) == SHT_NOBITS) ++ elf_section_type (osec) = SHT_NULL; ++ /* For objcopy and relocatable link, copy the ELF section type from ++ the input file if the BFD section flags are the same. (If they ++ are different the user may be doing something like ++ "objcopy --set-section-flags .text=alloc,data".) For a final ++ link allow some flags that the linker clears to differ. */ ++ if (elf_section_type (osec) == SHT_NULL ++ && (osec->flags == isec->flags ++ || (final_link ++ && ((osec->flags ^ isec->flags) ++ & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0))) ++ elf_section_type (osec) = elf_section_type (isec); ++ ++ /* FIXME: Is this correct for all OS/PROC specific flags? */ ++ elf_section_flags (osec) = (elf_section_flags (isec) ++ & (SHF_MASKOS | SHF_MASKPROC)); ++ ++ /* Copy sh_info from input for mbind section. */ ++ if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0 ++ && elf_section_flags (isec) & SHF_GNU_MBIND) ++ elf_section_data (osec)->this_hdr.sh_info ++ = elf_section_data (isec)->this_hdr.sh_info; ++ ++ /* Set things up for objcopy and relocatable link. The output ++ SHT_GROUP section will have its elf_next_in_group pointing back ++ to the input group members. Ignore linker created group section. ++ See elfNN_ia64_object_p in elfxx-ia64.c. */ ++ if ((link_info == NULL ++ || !link_info->resolve_section_groups) ++ && (elf_sec_group (isec) == NULL ++ || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)) ++ { ++ if (elf_section_flags (isec) & SHF_GROUP) ++ elf_section_flags (osec) |= SHF_GROUP; ++ elf_next_in_group (osec) = elf_next_in_group (isec); ++ elf_section_data (osec)->group = elf_section_data (isec)->group; ++ } ++ ++ /* If not decompress, preserve SHF_COMPRESSED. */ ++ if (!final_link && (ibfd->flags & BFD_DECOMPRESS) == 0) ++ elf_section_flags (osec) |= (elf_section_flags (isec) ++ & SHF_COMPRESSED); ++ ++ ihdr = &elf_section_data (isec)->this_hdr; ++ ++ /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We ++ don't use the output section of the linked-to section since it ++ may be NULL at this point. */ ++ if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0) ++ { ++ ohdr = &elf_section_data (osec)->this_hdr; ++ ohdr->sh_flags |= SHF_LINK_ORDER; ++ elf_linked_to_section (osec) = elf_linked_to_section (isec); ++ } ++ ++ osec->use_rela_p = isec->use_rela_p; ++ ++ return true; ++} ++ ++/* Copy private section information. This copies over the entsize ++ field, and sometimes the info field. */ ++ ++bool ++_bfd_elf_copy_private_section_data (bfd *ibfd, ++ asection *isec, ++ bfd *obfd, ++ asection *osec) ++{ ++ Elf_Internal_Shdr *ihdr, *ohdr; ++ ++ if (ibfd->xvec->flavour != bfd_target_elf_flavour ++ || obfd->xvec->flavour != bfd_target_elf_flavour) ++ return true; ++ ++ ihdr = &elf_section_data (isec)->this_hdr; ++ ohdr = &elf_section_data (osec)->this_hdr; ++ ++ ohdr->sh_entsize = ihdr->sh_entsize; ++ ++ if (ihdr->sh_type == SHT_SYMTAB ++ || ihdr->sh_type == SHT_DYNSYM ++ || ihdr->sh_type == SHT_GNU_verneed ++ || ihdr->sh_type == SHT_GNU_verdef) ++ ohdr->sh_info = ihdr->sh_info; ++ ++ return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec, ++ NULL); ++} ++ ++/* Look at all the SHT_GROUP sections in IBFD, making any adjustments ++ necessary if we are removing either the SHT_GROUP section or any of ++ the group member sections. DISCARDED is the value that a section's ++ output_section has if the section will be discarded, NULL when this ++ function is called from objcopy, bfd_abs_section_ptr when called ++ from the linker. */ ++ ++bool ++_bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded) ++{ ++ asection *isec; ++ ++ for (isec = ibfd->sections; isec != NULL; isec = isec->next) ++ if (elf_section_type (isec) == SHT_GROUP) ++ { ++ asection *first = elf_next_in_group (isec); ++ asection *s = first; ++ bfd_size_type removed = 0; ++ ++ while (s != NULL) ++ { ++ /* If this member section is being output but the ++ SHT_GROUP section is not, then clear the group info ++ set up by _bfd_elf_copy_private_section_data. */ ++ if (s->output_section != discarded ++ && isec->output_section == discarded) ++ { ++ elf_section_flags (s->output_section) &= ~SHF_GROUP; ++ elf_group_name (s->output_section) = NULL; ++ } ++ else ++ { ++ struct bfd_elf_section_data *elf_sec = elf_section_data (s); ++ if (s->output_section == discarded ++ && isec->output_section != discarded) ++ { ++ /* Conversely, if the member section is not being ++ output but the SHT_GROUP section is, then adjust ++ its size. */ ++ removed += 4; ++ if (elf_sec->rel.hdr != NULL ++ && (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0) ++ removed += 4; ++ if (elf_sec->rela.hdr != NULL ++ && (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0) ++ removed += 4; ++ } ++ else ++ { ++ /* Also adjust for zero-sized relocation member ++ section. */ ++ if (elf_sec->rel.hdr != NULL ++ && elf_sec->rel.hdr->sh_size == 0) ++ removed += 4; ++ if (elf_sec->rela.hdr != NULL ++ && elf_sec->rela.hdr->sh_size == 0) ++ removed += 4; ++ } ++ } ++ s = elf_next_in_group (s); ++ if (s == first) ++ break; ++ } ++ if (removed != 0) ++ { ++ if (discarded != NULL) ++ { ++ /* If we've been called for ld -r, then we need to ++ adjust the input section size. */ ++ if (isec->rawsize == 0) ++ isec->rawsize = isec->size; ++ isec->size = isec->rawsize - removed; ++ if (isec->size <= 4) ++ { ++ isec->size = 0; ++ isec->flags |= SEC_EXCLUDE; ++ } ++ } ++ else if (isec->output_section != NULL) ++ { ++ /* Adjust the output section size when called from ++ objcopy. */ ++ isec->output_section->size -= removed; ++ if (isec->output_section->size <= 4) ++ { ++ isec->output_section->size = 0; ++ isec->output_section->flags |= SEC_EXCLUDE; ++ } ++ } ++ } ++ } ++ ++ return true; ++} ++ ++/* Copy private header information. */ ++ ++bool ++_bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd) ++{ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour ++ || bfd_get_flavour (obfd) != bfd_target_elf_flavour) ++ return true; ++ ++ /* Copy over private BFD data if it has not already been copied. ++ This must be done here, rather than in the copy_private_bfd_data ++ entry point, because the latter is called after the section ++ contents have been set, which means that the program headers have ++ already been worked out. */ ++ if (elf_seg_map (obfd) == NULL && elf_tdata (ibfd)->phdr != NULL) ++ { ++ if (! copy_private_bfd_data (ibfd, obfd)) ++ return false; ++ } ++ ++ return _bfd_elf_fixup_group_sections (ibfd, NULL); ++} ++ ++/* Copy private symbol information. If this symbol is in a section ++ which we did not map into a BFD section, try to map the section ++ index correctly. We use special macro definitions for the mapped ++ section indices; these definitions are interpreted by the ++ swap_out_syms function. */ ++ ++#define MAP_ONESYMTAB (SHN_HIOS + 1) ++#define MAP_DYNSYMTAB (SHN_HIOS + 2) ++#define MAP_STRTAB (SHN_HIOS + 3) ++#define MAP_SHSTRTAB (SHN_HIOS + 4) ++#define MAP_SYM_SHNDX (SHN_HIOS + 5) ++ ++bool ++_bfd_elf_copy_private_symbol_data (bfd *ibfd, ++ asymbol *isymarg, ++ bfd *obfd, ++ asymbol *osymarg) ++{ ++ elf_symbol_type *isym, *osym; ++ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour ++ || bfd_get_flavour (obfd) != bfd_target_elf_flavour) ++ return true; ++ ++ isym = elf_symbol_from (isymarg); ++ osym = elf_symbol_from (osymarg); ++ ++ if (isym != NULL ++ && isym->internal_elf_sym.st_shndx != 0 ++ && osym != NULL ++ && bfd_is_abs_section (isym->symbol.section)) ++ { ++ unsigned int shndx; ++ ++ shndx = isym->internal_elf_sym.st_shndx; ++ if (shndx == elf_onesymtab (ibfd)) ++ shndx = MAP_ONESYMTAB; ++ else if (shndx == elf_dynsymtab (ibfd)) ++ shndx = MAP_DYNSYMTAB; ++ else if (shndx == elf_strtab_sec (ibfd)) ++ shndx = MAP_STRTAB; ++ else if (shndx == elf_shstrtab_sec (ibfd)) ++ shndx = MAP_SHSTRTAB; ++ else if (find_section_in_list (shndx, elf_symtab_shndx_list (ibfd))) ++ shndx = MAP_SYM_SHNDX; ++ osym->internal_elf_sym.st_shndx = shndx; ++ } ++ ++ return true; ++} ++ ++/* Swap out the symbols. */ ++ ++static bool ++swap_out_syms (bfd *abfd, ++ struct elf_strtab_hash **sttp, ++ int relocatable_p, ++ struct bfd_link_info *info) ++{ ++ const struct elf_backend_data *bed; ++ unsigned int symcount; ++ asymbol **syms; ++ struct elf_strtab_hash *stt; ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Shdr *symtab_shndx_hdr; ++ Elf_Internal_Shdr *symstrtab_hdr; ++ struct elf_sym_strtab *symstrtab; ++ bfd_byte *outbound_syms; ++ bfd_byte *outbound_shndx; ++ unsigned long outbound_syms_index; ++ unsigned int idx; ++ unsigned int num_locals; ++ size_t amt; ++ bool name_local_sections; ++ ++ if (!elf_map_symbols (abfd, &num_locals)) ++ return false; ++ ++ /* Dump out the symtabs. */ ++ stt = _bfd_elf_strtab_init (); ++ if (stt == NULL) ++ return false; ++ ++ bed = get_elf_backend_data (abfd); ++ symcount = bfd_get_symcount (abfd); ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ symtab_hdr->sh_type = SHT_SYMTAB; ++ symtab_hdr->sh_entsize = bed->s->sizeof_sym; ++ symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1); ++ symtab_hdr->sh_info = num_locals + 1; ++ symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; ++ ++ symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; ++ symstrtab_hdr->sh_type = SHT_STRTAB; ++ ++ /* Allocate buffer to swap out the .strtab section. */ ++ if (_bfd_mul_overflow (symcount + 1, sizeof (*symstrtab), &amt) ++ || (symstrtab = (struct elf_sym_strtab *) bfd_malloc (amt)) == NULL) ++ { ++ bfd_set_error (bfd_error_no_memory); ++ _bfd_elf_strtab_free (stt); ++ return false; ++ } ++ ++ if (_bfd_mul_overflow (symcount + 1, bed->s->sizeof_sym, &amt) ++ || (outbound_syms = (bfd_byte *) bfd_alloc (abfd, amt)) == NULL) ++ { ++ error_no_mem: ++ bfd_set_error (bfd_error_no_memory); ++ error_return: ++ free (symstrtab); ++ _bfd_elf_strtab_free (stt); ++ return false; ++ } ++ symtab_hdr->contents = outbound_syms; ++ outbound_syms_index = 0; ++ ++ outbound_shndx = NULL; ++ ++ if (elf_symtab_shndx_list (abfd)) ++ { ++ symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr; ++ if (symtab_shndx_hdr->sh_name != 0) ++ { ++ if (_bfd_mul_overflow (symcount + 1, ++ sizeof (Elf_External_Sym_Shndx), &amt)) ++ goto error_no_mem; ++ outbound_shndx = (bfd_byte *) bfd_zalloc (abfd, amt); ++ if (outbound_shndx == NULL) ++ goto error_return; ++ ++ symtab_shndx_hdr->contents = outbound_shndx; ++ symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; ++ symtab_shndx_hdr->sh_size = amt; ++ symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); ++ symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); ++ } ++ /* FIXME: What about any other headers in the list ? */ ++ } ++ ++ /* Now generate the data (for "contents"). */ ++ { ++ /* Fill in zeroth symbol and swap it out. */ ++ Elf_Internal_Sym sym; ++ sym.st_name = 0; ++ sym.st_value = 0; ++ sym.st_size = 0; ++ sym.st_info = 0; ++ sym.st_other = 0; ++ sym.st_shndx = SHN_UNDEF; ++ sym.st_target_internal = 0; ++ symstrtab[0].sym = sym; ++ symstrtab[0].dest_index = outbound_syms_index; ++ outbound_syms_index++; ++ } ++ ++ name_local_sections ++ = (bed->elf_backend_name_local_section_symbols ++ && bed->elf_backend_name_local_section_symbols (abfd)); ++ ++ syms = bfd_get_outsymbols (abfd); ++ for (idx = 0; idx < symcount;) ++ { ++ Elf_Internal_Sym sym; ++ bfd_vma value = syms[idx]->value; ++ elf_symbol_type *type_ptr; ++ flagword flags = syms[idx]->flags; ++ int type; ++ ++ if (!name_local_sections ++ && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM) ++ { ++ /* Local section symbols have no name. */ ++ sym.st_name = (unsigned long) -1; ++ } ++ else ++ { ++ /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize ++ to get the final offset for st_name. */ ++ sym.st_name ++ = (unsigned long) _bfd_elf_strtab_add (stt, syms[idx]->name, ++ false); ++ if (sym.st_name == (unsigned long) -1) ++ goto error_return; ++ } ++ ++ type_ptr = elf_symbol_from (syms[idx]); ++ ++ if ((flags & BSF_SECTION_SYM) == 0 ++ && bfd_is_com_section (syms[idx]->section)) ++ { ++ /* ELF common symbols put the alignment into the `value' field, ++ and the size into the `size' field. This is backwards from ++ how BFD handles it, so reverse it here. */ ++ sym.st_size = value; ++ if (type_ptr == NULL ++ || type_ptr->internal_elf_sym.st_value == 0) ++ sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value)); ++ else ++ sym.st_value = type_ptr->internal_elf_sym.st_value; ++ sym.st_shndx = _bfd_elf_section_from_bfd_section ++ (abfd, syms[idx]->section); ++ } ++ else ++ { ++ asection *sec = syms[idx]->section; ++ unsigned int shndx; ++ ++ if (sec->output_section) ++ { ++ value += sec->output_offset; ++ sec = sec->output_section; ++ } ++ ++ /* Don't add in the section vma for relocatable output. */ ++ if (! relocatable_p) ++ value += sec->vma; ++ sym.st_value = value; ++ sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0; ++ ++ if (bfd_is_abs_section (sec) ++ && type_ptr != NULL ++ && type_ptr->internal_elf_sym.st_shndx != 0) ++ { ++ /* This symbol is in a real ELF section which we did ++ not create as a BFD section. Undo the mapping done ++ by copy_private_symbol_data. */ ++ shndx = type_ptr->internal_elf_sym.st_shndx; ++ switch (shndx) ++ { ++ case MAP_ONESYMTAB: ++ shndx = elf_onesymtab (abfd); ++ break; ++ case MAP_DYNSYMTAB: ++ shndx = elf_dynsymtab (abfd); ++ break; ++ case MAP_STRTAB: ++ shndx = elf_strtab_sec (abfd); ++ break; ++ case MAP_SHSTRTAB: ++ shndx = elf_shstrtab_sec (abfd); ++ break; ++ case MAP_SYM_SHNDX: ++ if (elf_symtab_shndx_list (abfd)) ++ shndx = elf_symtab_shndx_list (abfd)->ndx; ++ break; ++ case SHN_COMMON: ++ case SHN_ABS: ++ shndx = SHN_ABS; ++ break; ++ default: ++ if (shndx >= SHN_LOPROC && shndx <= SHN_HIOS) ++ { ++ if (bed->symbol_section_index) ++ shndx = bed->symbol_section_index (abfd, type_ptr); ++ /* Otherwise just leave the index alone. */ ++ } ++ else ++ { ++ if (shndx > SHN_HIOS && shndx < SHN_HIRESERVE) ++ _bfd_error_handler (_("%pB: \ ++Unable to handle section index %x in ELF symbol. Using ABS instead."), ++ abfd, shndx); ++ shndx = SHN_ABS; ++ } ++ break; ++ } ++ } ++ else ++ { ++ shndx = _bfd_elf_section_from_bfd_section (abfd, sec); ++ ++ if (shndx == SHN_BAD) ++ { ++ asection *sec2; ++ ++ /* Writing this would be a hell of a lot easier if ++ we had some decent documentation on bfd, and ++ knew what to expect of the library, and what to ++ demand of applications. For example, it ++ appears that `objcopy' might not set the ++ section of a symbol to be a section that is ++ actually in the output file. */ ++ sec2 = bfd_get_section_by_name (abfd, sec->name); ++ if (sec2 != NULL) ++ shndx = _bfd_elf_section_from_bfd_section (abfd, sec2); ++ if (shndx == SHN_BAD) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler ++ (_("unable to find equivalent output section" ++ " for symbol '%s' from section '%s'"), ++ syms[idx]->name ? syms[idx]->name : "", ++ sec->name); ++ bfd_set_error (bfd_error_invalid_operation); ++ goto error_return; ++ } ++ } ++ } ++ ++ sym.st_shndx = shndx; ++ } ++ ++ if ((flags & BSF_THREAD_LOCAL) != 0) ++ type = STT_TLS; ++ else if ((flags & BSF_GNU_INDIRECT_FUNCTION) != 0) ++ type = STT_GNU_IFUNC; ++ else if ((flags & BSF_FUNCTION) != 0) ++ type = STT_FUNC; ++ else if ((flags & BSF_OBJECT) != 0) ++ type = STT_OBJECT; ++ else if ((flags & BSF_RELC) != 0) ++ type = STT_RELC; ++ else if ((flags & BSF_SRELC) != 0) ++ type = STT_SRELC; ++ else ++ type = STT_NOTYPE; ++ ++ if (syms[idx]->section->flags & SEC_THREAD_LOCAL) ++ type = STT_TLS; ++ ++ /* Processor-specific types. */ ++ if (type_ptr != NULL ++ && bed->elf_backend_get_symbol_type) ++ type = ((*bed->elf_backend_get_symbol_type) ++ (&type_ptr->internal_elf_sym, type)); ++ ++ if (flags & BSF_SECTION_SYM) ++ { ++ if (flags & BSF_GLOBAL) ++ sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); ++ else ++ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); ++ } ++ else if (bfd_is_com_section (syms[idx]->section)) ++ { ++ if (type != STT_TLS) ++ { ++ if ((abfd->flags & BFD_CONVERT_ELF_COMMON)) ++ type = ((abfd->flags & BFD_USE_ELF_STT_COMMON) ++ ? STT_COMMON : STT_OBJECT); ++ else ++ type = ((flags & BSF_ELF_COMMON) != 0 ++ ? STT_COMMON : STT_OBJECT); ++ } ++ sym.st_info = ELF_ST_INFO (STB_GLOBAL, type); ++ } ++ else if (bfd_is_und_section (syms[idx]->section)) ++ sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK) ++ ? STB_WEAK ++ : STB_GLOBAL), ++ type); ++ else if (flags & BSF_FILE) ++ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); ++ else ++ { ++ int bind = STB_LOCAL; ++ ++ if (flags & BSF_LOCAL) ++ bind = STB_LOCAL; ++ else if (flags & BSF_GNU_UNIQUE) ++ bind = STB_GNU_UNIQUE; ++ else if (flags & BSF_WEAK) ++ bind = STB_WEAK; ++ else if (flags & BSF_GLOBAL) ++ bind = STB_GLOBAL; ++ ++ sym.st_info = ELF_ST_INFO (bind, type); ++ } ++ ++ if (type_ptr != NULL) ++ { ++ sym.st_other = type_ptr->internal_elf_sym.st_other; ++ sym.st_target_internal ++ = type_ptr->internal_elf_sym.st_target_internal; ++ } ++ else ++ { ++ sym.st_other = 0; ++ sym.st_target_internal = 0; ++ } ++ ++ idx++; ++ symstrtab[idx].sym = sym; ++ symstrtab[idx].dest_index = outbound_syms_index; ++ ++ outbound_syms_index++; ++ } ++ ++ /* Finalize the .strtab section. */ ++ _bfd_elf_strtab_finalize (stt); ++ ++ /* Swap out the .strtab section. */ ++ for (idx = 0; idx <= symcount; idx++) ++ { ++ struct elf_sym_strtab *elfsym = &symstrtab[idx]; ++ if (elfsym->sym.st_name == (unsigned long) -1) ++ elfsym->sym.st_name = 0; ++ else ++ elfsym->sym.st_name = _bfd_elf_strtab_offset (stt, ++ elfsym->sym.st_name); ++ if (info && info->callbacks->ctf_new_symbol) ++ info->callbacks->ctf_new_symbol (elfsym->dest_index, ++ &elfsym->sym); ++ ++ /* Inform the linker of the addition of this symbol. */ ++ ++ bed->s->swap_symbol_out (abfd, &elfsym->sym, ++ (outbound_syms ++ + (elfsym->dest_index ++ * bed->s->sizeof_sym)), ++ NPTR_ADD (outbound_shndx, ++ (elfsym->dest_index ++ * sizeof (Elf_External_Sym_Shndx)))); ++ } ++ free (symstrtab); ++ ++ *sttp = stt; ++ symstrtab_hdr->sh_size = _bfd_elf_strtab_size (stt); ++ symstrtab_hdr->sh_type = SHT_STRTAB; ++ symstrtab_hdr->sh_flags = bed->elf_strtab_flags; ++ symstrtab_hdr->sh_addr = 0; ++ symstrtab_hdr->sh_entsize = 0; ++ symstrtab_hdr->sh_link = 0; ++ symstrtab_hdr->sh_info = 0; ++ symstrtab_hdr->sh_addralign = 1; ++ ++ return true; ++} ++ ++/* Return the number of bytes required to hold the symtab vector. ++ ++ Note that we base it on the count plus 1, since we will null terminate ++ the vector allocated based on this size. However, the ELF symbol table ++ always has a dummy entry as symbol #0, so it ends up even. */ ++ ++long ++_bfd_elf_get_symtab_upper_bound (bfd *abfd) ++{ ++ bfd_size_type symcount; ++ long symtab_size; ++ Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; ++ ++ symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; ++ if (symcount > LONG_MAX / sizeof (asymbol *)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return -1; ++ } ++ symtab_size = symcount * (sizeof (asymbol *)); ++ if (symcount == 0) ++ symtab_size = sizeof (asymbol *); ++ else if (!bfd_write_p (abfd)) ++ { ++ ufile_ptr filesize = bfd_get_file_size (abfd); ++ ++ if (filesize != 0 && (unsigned long) symtab_size > filesize) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return -1; ++ } ++ } ++ ++ return symtab_size; ++} ++ ++long ++_bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) ++{ ++ bfd_size_type symcount; ++ long symtab_size; ++ Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; ++ ++ if (elf_dynsymtab (abfd) == 0) ++ { ++ /* Check if there is dynamic symbol table. */ ++ symcount = elf_tdata (abfd)->dt_symtab_count; ++ if (symcount) ++ goto compute_symtab_size; ++ ++ bfd_set_error (bfd_error_invalid_operation); ++ return -1; ++ } ++ ++ symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; ++ if (symcount > LONG_MAX / sizeof (asymbol *)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return -1; ++ } ++ ++ compute_symtab_size: ++ symtab_size = symcount * (sizeof (asymbol *)); ++ if (symcount == 0) ++ symtab_size = sizeof (asymbol *); ++ else if (!bfd_write_p (abfd)) ++ { ++ ufile_ptr filesize = bfd_get_file_size (abfd); ++ ++ if (filesize != 0 && (unsigned long) symtab_size > filesize) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return -1; ++ } ++ } ++ ++ return symtab_size; ++} ++ ++long ++_bfd_elf_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) ++{ ++ if (asect->reloc_count != 0 && !bfd_write_p (abfd)) ++ { ++ /* Sanity check reloc section size. */ ++ ufile_ptr filesize = bfd_get_file_size (abfd); ++ ++ if (filesize != 0) ++ { ++ struct bfd_elf_section_data *d = elf_section_data (asect); ++ bfd_size_type rel_size = d->rel.hdr ? d->rel.hdr->sh_size : 0; ++ bfd_size_type rela_size = d->rela.hdr ? d->rela.hdr->sh_size : 0; ++ ++ if (rel_size + rela_size > filesize ++ || rel_size + rela_size < rel_size) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return -1; ++ } ++ } ++ } ++ ++#if SIZEOF_LONG == SIZEOF_INT ++ if (asect->reloc_count >= LONG_MAX / sizeof (arelent *)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return -1; ++ } ++#endif ++ return (asect->reloc_count + 1L) * sizeof (arelent *); ++} ++ ++/* Canonicalize the relocs. */ ++ ++long ++_bfd_elf_canonicalize_reloc (bfd *abfd, ++ sec_ptr section, ++ arelent **relptr, ++ asymbol **symbols) ++{ ++ arelent *tblptr; ++ unsigned int i; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ if (! bed->s->slurp_reloc_table (abfd, section, symbols, false)) ++ return -1; ++ ++ tblptr = section->relocation; ++ for (i = 0; i < section->reloc_count; i++) ++ *relptr++ = tblptr++; ++ ++ *relptr = NULL; ++ ++ return section->reloc_count; ++} ++ ++long ++_bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ long symcount = bed->s->slurp_symbol_table (abfd, allocation, false); ++ ++ if (symcount >= 0) ++ abfd->symcount = symcount; ++ return symcount; ++} ++ ++long ++_bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, ++ asymbol **allocation) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ long symcount = bed->s->slurp_symbol_table (abfd, allocation, true); ++ ++ if (symcount >= 0) ++ abfd->dynsymcount = symcount; ++ return symcount; ++} ++ ++/* Return the size required for the dynamic reloc entries. Any loadable ++ section that was actually installed in the BFD, and has type SHT_REL ++ or SHT_RELA, and uses the dynamic symbol table, is considered to be a ++ dynamic reloc section. */ ++ ++long ++_bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) ++{ ++ bfd_size_type count, ext_rel_size; ++ asection *s; ++ ++ if (elf_dynsymtab (abfd) == 0) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ return -1; ++ } ++ ++ count = 1; ++ ext_rel_size = 0; ++ for (s = abfd->sections; s != NULL; s = s->next) ++ if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) ++ && (elf_section_data (s)->this_hdr.sh_type == SHT_REL ++ || elf_section_data (s)->this_hdr.sh_type == SHT_RELA) ++ && (elf_section_data (s)->this_hdr.sh_flags & SHF_COMPRESSED) == 0) ++ { ++ ext_rel_size += elf_section_data (s)->this_hdr.sh_size; ++ if (ext_rel_size < elf_section_data (s)->this_hdr.sh_size) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return -1; ++ } ++ count += NUM_SHDR_ENTRIES (&elf_section_data (s)->this_hdr); ++ if (count > LONG_MAX / sizeof (arelent *)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return -1; ++ } ++ } ++ if (count > 1 && !bfd_write_p (abfd)) ++ { ++ /* Sanity check reloc section sizes. */ ++ ufile_ptr filesize = bfd_get_file_size (abfd); ++ if (filesize != 0 && ext_rel_size > filesize) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ return -1; ++ } ++ } ++ return count * sizeof (arelent *); ++} ++ ++/* Canonicalize the dynamic relocation entries. Note that we return the ++ dynamic relocations as a single block, although they are actually ++ associated with particular sections; the interface, which was ++ designed for SunOS style shared libraries, expects that there is only ++ one set of dynamic relocs. Any loadable section that was actually ++ installed in the BFD, and has type SHT_REL or SHT_RELA, and uses the ++ dynamic symbol table, is considered to be a dynamic reloc section. */ ++ ++long ++_bfd_elf_canonicalize_dynamic_reloc (bfd *abfd, ++ arelent **storage, ++ asymbol **syms) ++{ ++ bool (*slurp_relocs) (bfd *, asection *, asymbol **, bool); ++ asection *s; ++ long ret; ++ ++ if (elf_dynsymtab (abfd) == 0) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ return -1; ++ } ++ ++ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; ++ ret = 0; ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) ++ && (elf_section_data (s)->this_hdr.sh_type == SHT_REL ++ || elf_section_data (s)->this_hdr.sh_type == SHT_RELA) ++ && (elf_section_data (s)->this_hdr.sh_flags & SHF_COMPRESSED) == 0) ++ { ++ arelent *p; ++ long count, i; ++ ++ if (! (*slurp_relocs) (abfd, s, syms, true)) ++ return -1; ++ count = NUM_SHDR_ENTRIES (&elf_section_data (s)->this_hdr); ++ p = s->relocation; ++ for (i = 0; i < count; i++) ++ *storage++ = p++; ++ ret += count; ++ } ++ } ++ ++ *storage = NULL; ++ ++ return ret; ++} ++ ++/* Read in the version information. */ ++ ++bool ++_bfd_elf_slurp_version_tables (bfd *abfd, bool default_imported_symver) ++{ ++ bfd_byte *contents = NULL; ++ unsigned int freeidx = 0; ++ size_t amt; ++ ++ if (elf_dynverref (abfd) != 0 || elf_tdata (abfd)->dt_verneed != NULL) ++ { ++ Elf_Internal_Shdr *hdr; ++ Elf_External_Verneed *everneed; ++ Elf_Internal_Verneed *iverneed; ++ unsigned int i; ++ bfd_byte *contents_end; ++ size_t verneed_count; ++ size_t verneed_size; ++ ++ if (elf_tdata (abfd)->dt_verneed != NULL) ++ { ++ hdr = NULL; ++ contents = elf_tdata (abfd)->dt_verneed; ++ verneed_count = elf_tdata (abfd)->dt_verneed_count; ++ verneed_size = verneed_count * sizeof (Elf_External_Verneed); ++ } ++ else ++ { ++ hdr = &elf_tdata (abfd)->dynverref_hdr; ++ ++ if (hdr->sh_info > hdr->sh_size / sizeof (Elf_External_Verneed)) ++ { ++ error_return_bad_verref: ++ _bfd_error_handler ++ (_("%pB: .gnu.version_r invalid entry"), abfd); ++ bfd_set_error (bfd_error_bad_value); ++ error_return_verref: ++ elf_tdata (abfd)->verref = NULL; ++ elf_tdata (abfd)->cverrefs = 0; ++ goto error_return; ++ } ++ ++ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0) ++ goto error_return_verref; ++ contents = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size); ++ if (contents == NULL) ++ goto error_return_verref; ++ ++ verneed_size = hdr->sh_size; ++ verneed_count = hdr->sh_info; ++ } ++ ++ if (_bfd_mul_overflow (verneed_count, ++ sizeof (Elf_Internal_Verneed), &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto error_return_verref; ++ } ++ if (amt == 0) ++ goto error_return_verref; ++ elf_tdata (abfd)->verref = (Elf_Internal_Verneed *) bfd_zalloc (abfd, amt); ++ if (elf_tdata (abfd)->verref == NULL) ++ goto error_return_verref; ++ ++ BFD_ASSERT (sizeof (Elf_External_Verneed) ++ == sizeof (Elf_External_Vernaux)); ++ contents_end = (contents + verneed_size ++ - sizeof (Elf_External_Verneed)); ++ everneed = (Elf_External_Verneed *) contents; ++ iverneed = elf_tdata (abfd)->verref; ++ for (i = 0; i < verneed_count; i++, iverneed++) ++ { ++ Elf_External_Vernaux *evernaux; ++ Elf_Internal_Vernaux *ivernaux; ++ unsigned int j; ++ ++ _bfd_elf_swap_verneed_in (abfd, everneed, iverneed); ++ ++ iverneed->vn_bfd = abfd; ++ ++ if (elf_use_dt_symtab_p (abfd)) ++ iverneed->vn_filename ++ = elf_tdata (abfd)->dt_strtab + iverneed->vn_file; ++ else if (hdr == NULL) ++ goto error_return_bad_verref; ++ else ++ iverneed->vn_filename ++ = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, ++ iverneed->vn_file); ++ if (iverneed->vn_filename == NULL) ++ goto error_return_bad_verref; ++ ++ if (iverneed->vn_cnt == 0) ++ iverneed->vn_auxptr = NULL; ++ else ++ { ++ if (_bfd_mul_overflow (iverneed->vn_cnt, ++ sizeof (Elf_Internal_Vernaux), &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto error_return_verref; ++ } ++ iverneed->vn_auxptr = (struct elf_internal_vernaux *) ++ bfd_alloc (abfd, amt); ++ if (iverneed->vn_auxptr == NULL) ++ goto error_return_verref; ++ } ++ ++ if (iverneed->vn_aux ++ > (size_t) (contents_end - (bfd_byte *) everneed)) ++ goto error_return_bad_verref; ++ ++ evernaux = ((Elf_External_Vernaux *) ++ ((bfd_byte *) everneed + iverneed->vn_aux)); ++ ivernaux = iverneed->vn_auxptr; ++ for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++) ++ { ++ _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux); ++ ++ if (elf_use_dt_symtab_p (abfd)) ++ ivernaux->vna_nodename ++ = elf_tdata (abfd)->dt_strtab + ivernaux->vna_name; ++ else if (hdr == NULL) ++ goto error_return_bad_verref; ++ else ++ ivernaux->vna_nodename ++ = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, ++ ivernaux->vna_name); ++ if (ivernaux->vna_nodename == NULL) ++ goto error_return_bad_verref; ++ ++ if (ivernaux->vna_other > freeidx) ++ freeidx = ivernaux->vna_other; ++ ++ ivernaux->vna_nextptr = NULL; ++ if (ivernaux->vna_next == 0) ++ { ++ iverneed->vn_cnt = j + 1; ++ break; ++ } ++ if (j + 1 < iverneed->vn_cnt) ++ ivernaux->vna_nextptr = ivernaux + 1; ++ ++ if (ivernaux->vna_next ++ > (size_t) (contents_end - (bfd_byte *) evernaux)) ++ goto error_return_bad_verref; ++ ++ evernaux = ((Elf_External_Vernaux *) ++ ((bfd_byte *) evernaux + ivernaux->vna_next)); ++ } ++ ++ iverneed->vn_nextref = NULL; ++ if (iverneed->vn_next == 0) ++ break; ++ if (hdr != NULL && (i + 1 < hdr->sh_info)) ++ iverneed->vn_nextref = iverneed + 1; ++ ++ if (iverneed->vn_next ++ > (size_t) (contents_end - (bfd_byte *) everneed)) ++ goto error_return_bad_verref; ++ ++ everneed = ((Elf_External_Verneed *) ++ ((bfd_byte *) everneed + iverneed->vn_next)); ++ } ++ elf_tdata (abfd)->cverrefs = i; ++ ++ if (elf_tdata (abfd)->dt_verneed == NULL) ++ free (contents); ++ contents = NULL; ++ } ++ ++ if (elf_dynverdef (abfd) != 0 || elf_tdata (abfd)->dt_verdef != NULL) ++ { ++ Elf_Internal_Shdr *hdr; ++ Elf_External_Verdef *everdef; ++ Elf_Internal_Verdef *iverdef; ++ Elf_Internal_Verdef *iverdefarr; ++ Elf_Internal_Verdef iverdefmem; ++ unsigned int i; ++ unsigned int maxidx; ++ bfd_byte *contents_end_def, *contents_end_aux; ++ size_t verdef_count; ++ size_t verdef_size; ++ ++ if (elf_tdata (abfd)->dt_verdef != NULL) ++ { ++ hdr = NULL; ++ contents = elf_tdata (abfd)->dt_verdef; ++ verdef_count = elf_tdata (abfd)->dt_verdef_count; ++ verdef_size = verdef_count * sizeof (Elf_External_Verdef); ++ } ++ else ++ { ++ hdr = &elf_tdata (abfd)->dynverdef_hdr; ++ ++ if (hdr->sh_size < sizeof (Elf_External_Verdef)) ++ { ++ error_return_bad_verdef: ++ _bfd_error_handler ++ (_("%pB: .gnu.version_d invalid entry"), abfd); ++ bfd_set_error (bfd_error_bad_value); ++ error_return_verdef: ++ elf_tdata (abfd)->verdef = NULL; ++ elf_tdata (abfd)->cverdefs = 0; ++ goto error_return; ++ } ++ ++ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0) ++ goto error_return_verdef; ++ contents = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size); ++ if (contents == NULL) ++ goto error_return_verdef; ++ ++ BFD_ASSERT (sizeof (Elf_External_Verdef) ++ >= sizeof (Elf_External_Verdaux)); ++ ++ verdef_count = hdr->sh_info; ++ verdef_size = hdr->sh_size; ++ } ++ ++ contents_end_def = (contents + verdef_size ++ - sizeof (Elf_External_Verdef)); ++ contents_end_aux = (contents + verdef_size ++ - sizeof (Elf_External_Verdaux)); ++ ++ /* We know the number of entries in the section but not the maximum ++ index. Therefore we have to run through all entries and find ++ the maximum. */ ++ everdef = (Elf_External_Verdef *) contents; ++ maxidx = 0; ++ for (i = 0; i < verdef_count; ++i) ++ { ++ _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem); ++ ++ if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) == 0) ++ goto error_return_bad_verdef; ++ if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx) ++ maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION); ++ ++ if (iverdefmem.vd_next == 0) ++ break; ++ ++ if (iverdefmem.vd_next ++ > (size_t) (contents_end_def - (bfd_byte *) everdef)) ++ goto error_return_bad_verdef; ++ ++ everdef = ((Elf_External_Verdef *) ++ ((bfd_byte *) everdef + iverdefmem.vd_next)); ++ } ++ ++ if (default_imported_symver) ++ { ++ if (freeidx > maxidx) ++ maxidx = ++freeidx; ++ else ++ freeidx = ++maxidx; ++ } ++ if (_bfd_mul_overflow (maxidx, sizeof (Elf_Internal_Verdef), &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto error_return_verdef; ++ } ++ ++ if (amt == 0) ++ goto error_return_verdef; ++ elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt); ++ if (elf_tdata (abfd)->verdef == NULL) ++ goto error_return_verdef; ++ ++ elf_tdata (abfd)->cverdefs = maxidx; ++ ++ everdef = (Elf_External_Verdef *) contents; ++ iverdefarr = elf_tdata (abfd)->verdef; ++ for (i = 0; i < verdef_count; ++i) ++ { ++ Elf_External_Verdaux *everdaux; ++ Elf_Internal_Verdaux *iverdaux; ++ unsigned int j; ++ ++ _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem); ++ ++ if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0) ++ goto error_return_bad_verdef; ++ ++ iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1]; ++ memcpy (iverdef, &iverdefmem, offsetof (Elf_Internal_Verdef, vd_bfd)); ++ ++ iverdef->vd_bfd = abfd; ++ ++ if (iverdef->vd_cnt == 0) ++ iverdef->vd_auxptr = NULL; ++ else ++ { ++ if (_bfd_mul_overflow (iverdef->vd_cnt, ++ sizeof (Elf_Internal_Verdaux), &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto error_return_verdef; ++ } ++ iverdef->vd_auxptr = (struct elf_internal_verdaux *) ++ bfd_alloc (abfd, amt); ++ if (iverdef->vd_auxptr == NULL) ++ goto error_return_verdef; ++ } ++ ++ if (iverdef->vd_aux ++ > (size_t) (contents_end_aux - (bfd_byte *) everdef)) ++ goto error_return_bad_verdef; ++ ++ everdaux = ((Elf_External_Verdaux *) ++ ((bfd_byte *) everdef + iverdef->vd_aux)); ++ iverdaux = iverdef->vd_auxptr; ++ for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++) ++ { ++ _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux); ++ ++ if (elf_use_dt_symtab_p (abfd)) ++ iverdaux->vda_nodename ++ = elf_tdata (abfd)->dt_strtab + iverdaux->vda_name; ++ else ++ iverdaux->vda_nodename ++ = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, ++ iverdaux->vda_name); ++ if (iverdaux->vda_nodename == NULL) ++ goto error_return_bad_verdef; ++ ++ iverdaux->vda_nextptr = NULL; ++ if (iverdaux->vda_next == 0) ++ { ++ iverdef->vd_cnt = j + 1; ++ break; ++ } ++ if (j + 1 < iverdef->vd_cnt) ++ iverdaux->vda_nextptr = iverdaux + 1; ++ ++ if (iverdaux->vda_next ++ > (size_t) (contents_end_aux - (bfd_byte *) everdaux)) ++ goto error_return_bad_verdef; ++ ++ everdaux = ((Elf_External_Verdaux *) ++ ((bfd_byte *) everdaux + iverdaux->vda_next)); ++ } ++ ++ iverdef->vd_nodename = NULL; ++ if (iverdef->vd_cnt) ++ iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename; ++ ++ iverdef->vd_nextdef = NULL; ++ if (iverdef->vd_next == 0) ++ break; ++ if ((size_t) (iverdef - iverdefarr) + 1 < maxidx) ++ iverdef->vd_nextdef = iverdef + 1; ++ ++ everdef = ((Elf_External_Verdef *) ++ ((bfd_byte *) everdef + iverdef->vd_next)); ++ } ++ ++ if (elf_tdata (abfd)->dt_verdef == NULL) ++ free (contents); ++ contents = NULL; ++ } ++ else if (default_imported_symver) ++ { ++ if (freeidx < 3) ++ freeidx = 3; ++ else ++ freeidx++; ++ ++ if (_bfd_mul_overflow (freeidx, sizeof (Elf_Internal_Verdef), &amt)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ goto error_return; ++ } ++ if (amt == 0) ++ goto error_return; ++ elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt); ++ if (elf_tdata (abfd)->verdef == NULL) ++ goto error_return; ++ ++ elf_tdata (abfd)->cverdefs = freeidx; ++ } ++ ++ /* Create a default version based on the soname. */ ++ if (default_imported_symver) ++ { ++ Elf_Internal_Verdef *iverdef; ++ Elf_Internal_Verdaux *iverdaux; ++ ++ iverdef = &elf_tdata (abfd)->verdef[freeidx - 1]; ++ ++ iverdef->vd_version = VER_DEF_CURRENT; ++ iverdef->vd_flags = 0; ++ iverdef->vd_ndx = freeidx; ++ iverdef->vd_cnt = 1; ++ ++ iverdef->vd_bfd = abfd; ++ ++ iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd); ++ if (iverdef->vd_nodename == NULL) ++ goto error_return_verdef; ++ iverdef->vd_nextdef = NULL; ++ iverdef->vd_auxptr = ((struct elf_internal_verdaux *) ++ bfd_zalloc (abfd, sizeof (Elf_Internal_Verdaux))); ++ if (iverdef->vd_auxptr == NULL) ++ goto error_return_verdef; ++ ++ iverdaux = iverdef->vd_auxptr; ++ iverdaux->vda_nodename = iverdef->vd_nodename; ++ } ++ ++ return true; ++ ++ error_return: ++ free (contents); ++ return false; ++} ++ ++asymbol * ++_bfd_elf_make_empty_symbol (bfd *abfd) ++{ ++ elf_symbol_type *newsym; ++ ++ newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (*newsym)); ++ if (!newsym) ++ return NULL; ++ newsym->symbol.the_bfd = abfd; ++ return &newsym->symbol; ++} ++ ++void ++_bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, ++ asymbol *symbol, ++ symbol_info *ret) ++{ ++ bfd_symbol_info (symbol, ret); ++} ++ ++/* Return whether a symbol name implies a local symbol. Most targets ++ use this function for the is_local_label_name entry point, but some ++ override it. */ ++ ++bool ++_bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, ++ const char *name) ++{ ++ /* Normal local symbols start with ``.L''. */ ++ if (name[0] == '.' && name[1] == 'L') ++ return true; ++ ++ /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate ++ DWARF debugging symbols starting with ``..''. */ ++ if (name[0] == '.' && name[1] == '.') ++ return true; ++ ++ /* gcc will sometimes generate symbols beginning with ``_.L_'' when ++ emitting DWARF debugging output. I suspect this is actually a ++ small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call ++ ASM_GENERATE_INTERNAL_LABEL, and this causes the leading ++ underscore to be emitted on some ELF targets). For ease of use, ++ we treat such symbols as local. */ ++ if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_') ++ return true; ++ ++ /* Treat assembler generated fake symbols, dollar local labels and ++ forward-backward labels (aka local labels) as locals. ++ These labels have the form: ++ ++ L0^A.* (fake symbols) ++ ++ [.]?L[0123456789]+{^A|^B}[0123456789]* (local labels) ++ ++ Versions which start with .L will have already been matched above, ++ so we only need to match the rest. */ ++ if (name[0] == 'L' && ISDIGIT (name[1])) ++ { ++ bool ret = false; ++ const char * p; ++ char c; ++ ++ for (p = name + 2; (c = *p); p++) ++ { ++ if (c == 1 || c == 2) ++ { ++ if (c == 1 && p == name + 2) ++ /* A fake symbol. */ ++ return true; ++ ++ /* FIXME: We are being paranoid here and treating symbols like ++ L0^Bfoo as if there were non-local, on the grounds that the ++ assembler will never generate them. But can any symbol ++ containing an ASCII value in the range 1-31 ever be anything ++ other than some kind of local ? */ ++ ret = true; ++ } ++ ++ if (! ISDIGIT (c)) ++ { ++ ret = false; ++ break; ++ } ++ } ++ return ret; ++ } ++ ++ return false; ++} ++ ++alent * ++_bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED, ++ asymbol *symbol ATTRIBUTE_UNUSED) ++{ ++ abort (); ++ return NULL; ++} ++ ++bool ++_bfd_elf_set_arch_mach (bfd *abfd, ++ enum bfd_architecture arch, ++ unsigned long machine) ++{ ++ /* If this isn't the right architecture for this backend, and this ++ isn't the generic backend, fail. */ ++ if (arch != get_elf_backend_data (abfd)->arch ++ && arch != bfd_arch_unknown ++ && get_elf_backend_data (abfd)->arch != bfd_arch_unknown) ++ return false; ++ ++ return bfd_default_set_arch_mach (abfd, arch, machine); ++} ++ ++/* Find the nearest line to a particular section and offset, ++ for error reporting. */ ++ ++bool ++_bfd_elf_find_nearest_line (bfd *abfd, ++ asymbol **symbols, ++ asection *section, ++ bfd_vma offset, ++ const char **filename_ptr, ++ const char **functionname_ptr, ++ unsigned int *line_ptr, ++ unsigned int *discriminator_ptr) ++{ ++ return _bfd_elf_find_nearest_line_with_alt (abfd, NULL, symbols, section, ++ offset, filename_ptr, ++ functionname_ptr, line_ptr, ++ discriminator_ptr); ++} ++ ++/* Find the nearest line to a particular section and offset, ++ for error reporting. ALT_BFD representing a .gnu_debugaltlink file ++ can be optionally specified. */ ++ ++bool ++_bfd_elf_find_nearest_line_with_alt (bfd *abfd, ++ const char *alt_filename, ++ asymbol **symbols, ++ asection *section, ++ bfd_vma offset, ++ const char **filename_ptr, ++ const char **functionname_ptr, ++ unsigned int *line_ptr, ++ unsigned int *discriminator_ptr) ++{ ++ bool found; ++ ++ if (_bfd_dwarf2_find_nearest_line_with_alt (abfd, alt_filename, symbols, NULL, ++ section, offset, filename_ptr, ++ functionname_ptr, line_ptr, ++ discriminator_ptr, ++ dwarf_debug_sections, ++ &elf_tdata (abfd)->dwarf2_find_line_info)) ++ return true; ++ ++ if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset, ++ filename_ptr, functionname_ptr, line_ptr)) ++ { ++ if (!*functionname_ptr) ++ _bfd_elf_find_function (abfd, symbols, section, offset, ++ *filename_ptr ? NULL : filename_ptr, ++ functionname_ptr); ++ return true; ++ } ++ ++ if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, ++ &found, filename_ptr, ++ functionname_ptr, line_ptr, ++ &elf_tdata (abfd)->line_info)) ++ return false; ++ if (found && (*functionname_ptr || *line_ptr)) ++ return true; ++ ++ if (symbols == NULL) ++ return false; ++ ++ if (! _bfd_elf_find_function (abfd, symbols, section, offset, ++ filename_ptr, functionname_ptr)) ++ return false; ++ ++ *line_ptr = 0; ++ return true; ++} ++ ++/* Find the line for a symbol. */ ++ ++bool ++_bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol, ++ const char **filename_ptr, unsigned int *line_ptr) ++{ ++ struct elf_obj_tdata *tdata = elf_tdata (abfd); ++ return _bfd_dwarf2_find_nearest_line (abfd, symbols, symbol, NULL, 0, ++ filename_ptr, NULL, line_ptr, NULL, ++ dwarf_debug_sections, ++ &tdata->dwarf2_find_line_info); ++} ++ ++/* After a call to bfd_find_nearest_line, successive calls to ++ bfd_find_inliner_info can be used to get source information about ++ each level of function inlining that terminated at the address ++ passed to bfd_find_nearest_line. Currently this is only supported ++ for DWARF2 with appropriate DWARF3 extensions. */ ++ ++bool ++_bfd_elf_find_inliner_info (bfd *abfd, ++ const char **filename_ptr, ++ const char **functionname_ptr, ++ unsigned int *line_ptr) ++{ ++ struct elf_obj_tdata *tdata = elf_tdata (abfd); ++ return _bfd_dwarf2_find_inliner_info (abfd, filename_ptr, ++ functionname_ptr, line_ptr, ++ &tdata->dwarf2_find_line_info); ++} ++ ++int ++_bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ int ret = bed->s->sizeof_ehdr; ++ ++ if (!bfd_link_relocatable (info)) ++ { ++ bfd_size_type phdr_size = elf_program_header_size (abfd); ++ ++ if (phdr_size == (bfd_size_type) -1) ++ { ++ struct elf_segment_map *m; ++ ++ phdr_size = 0; ++ for (m = elf_seg_map (abfd); m != NULL; m = m->next) ++ phdr_size += bed->s->sizeof_phdr; ++ ++ if (phdr_size == 0) ++ phdr_size = get_program_header_size (abfd, info); ++ } ++ ++ elf_program_header_size (abfd) = phdr_size; ++ ret += phdr_size; ++ } ++ ++ return ret; ++} ++ ++bool ++_bfd_elf_set_section_contents (bfd *abfd, ++ sec_ptr section, ++ const void *location, ++ file_ptr offset, ++ bfd_size_type count) ++{ ++ Elf_Internal_Shdr *hdr; ++ ++ if (! abfd->output_has_begun ++ && ! _bfd_elf_compute_section_file_positions (abfd, NULL)) ++ return false; ++ ++ if (!count) ++ return true; ++ ++ hdr = &elf_section_data (section)->this_hdr; ++ if (hdr->sh_offset == (file_ptr) -1) ++ { ++ unsigned char *contents; ++ ++ if (bfd_section_is_ctf (section)) ++ /* Nothing to do with this section: the contents are generated ++ later. */ ++ return true; ++ ++ if ((offset + count) > hdr->sh_size) ++ { ++ _bfd_error_handler ++ (_("%pB:%pA: error: attempting to write" ++ " over the end of the section"), ++ abfd, section); ++ ++ bfd_set_error (bfd_error_invalid_operation); ++ return false; ++ } ++ ++ contents = hdr->contents; ++ if (contents == NULL) ++ { ++ _bfd_error_handler ++ (_("%pB:%pA: error: attempting to write" ++ " section into an empty buffer"), ++ abfd, section); ++ ++ bfd_set_error (bfd_error_invalid_operation); ++ return false; ++ } ++ ++ memcpy (contents + offset, location, count); ++ return true; ++ } ++ ++ return _bfd_generic_set_section_contents (abfd, section, ++ location, offset, count); ++} ++ ++bool ++_bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, ++ arelent *cache_ptr ATTRIBUTE_UNUSED, ++ Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) ++{ ++ abort (); ++ return false; ++} ++ ++/* Try to convert a non-ELF reloc into an ELF one. */ ++ ++bool ++_bfd_elf_validate_reloc (bfd *abfd, arelent *areloc) ++{ ++ /* Check whether we really have an ELF howto. */ ++ ++ if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec) ++ { ++ bfd_reloc_code_real_type code; ++ reloc_howto_type *howto; ++ ++ /* Alien reloc: Try to determine its type to replace it with an ++ equivalent ELF reloc. */ ++ ++ if (areloc->howto->pc_relative) ++ { ++ switch (areloc->howto->bitsize) ++ { ++ case 8: ++ code = BFD_RELOC_8_PCREL; ++ break; ++ case 12: ++ code = BFD_RELOC_12_PCREL; ++ break; ++ case 16: ++ code = BFD_RELOC_16_PCREL; ++ break; ++ case 24: ++ code = BFD_RELOC_24_PCREL; ++ break; ++ case 32: ++ code = BFD_RELOC_32_PCREL; ++ break; ++ case 64: ++ code = BFD_RELOC_64_PCREL; ++ break; ++ default: ++ goto fail; ++ } ++ ++ howto = bfd_reloc_type_lookup (abfd, code); ++ ++ if (howto && areloc->howto->pcrel_offset != howto->pcrel_offset) ++ { ++ if (howto->pcrel_offset) ++ areloc->addend += areloc->address; ++ else ++ areloc->addend -= areloc->address; /* addend is unsigned!! */ ++ } ++ } ++ else ++ { ++ switch (areloc->howto->bitsize) ++ { ++ case 8: ++ code = BFD_RELOC_8; ++ break; ++ case 14: ++ code = BFD_RELOC_14; ++ break; ++ case 16: ++ code = BFD_RELOC_16; ++ break; ++ case 26: ++ code = BFD_RELOC_26; ++ break; ++ case 32: ++ code = BFD_RELOC_32; ++ break; ++ case 64: ++ code = BFD_RELOC_64; ++ break; ++ default: ++ goto fail; ++ } ++ ++ howto = bfd_reloc_type_lookup (abfd, code); ++ } ++ ++ if (howto) ++ areloc->howto = howto; ++ else ++ goto fail; ++ } ++ ++ return true; ++ ++ fail: ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: %s unsupported"), ++ abfd, areloc->howto->name); ++ bfd_set_error (bfd_error_sorry); ++ return false; ++} ++ ++bool ++_bfd_elf_free_cached_info (bfd *abfd) ++{ ++ struct elf_obj_tdata *tdata; ++ ++ if ((bfd_get_format (abfd) == bfd_object ++ || bfd_get_format (abfd) == bfd_core) ++ && (tdata = elf_tdata (abfd)) != NULL) ++ { ++ if (tdata->o != NULL && elf_shstrtab (abfd) != NULL) ++ _bfd_elf_strtab_free (elf_shstrtab (abfd)); ++ _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info); ++ _bfd_dwarf1_cleanup_debug_info (abfd, &tdata->dwarf1_find_line_info); ++ _bfd_stab_cleanup (abfd, &tdata->line_info); ++ } ++ ++ return _bfd_generic_bfd_free_cached_info (abfd); ++} ++ ++/* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY ++ in the relocation's offset. Thus we cannot allow any sort of sanity ++ range-checking to interfere. There is nothing else to do in processing ++ this reloc. */ ++ ++bfd_reloc_status_type ++_bfd_elf_rel_vtable_reloc_fn ++ (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED, ++ struct bfd_symbol *symbol ATTRIBUTE_UNUSED, ++ void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED, ++ bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED) ++{ ++ return bfd_reloc_ok; ++} ++ ++/* Elf core file support. Much of this only works on native ++ toolchains, since we rely on knowing the ++ machine-dependent procfs structure in order to pick ++ out details about the corefile. */ ++ ++#ifdef HAVE_SYS_PROCFS_H ++# include ++#endif ++ ++/* Return a PID that identifies a "thread" for threaded cores, or the ++ PID of the main process for non-threaded cores. */ ++ ++static int ++elfcore_make_pid (bfd *abfd) ++{ ++ int pid; ++ ++ pid = elf_tdata (abfd)->core->lwpid; ++ if (pid == 0) ++ pid = elf_tdata (abfd)->core->pid; ++ ++ return pid; ++} ++ ++/* If there isn't a section called NAME, make one, using data from ++ SECT. Note, this function will generate a reference to NAME, so ++ you shouldn't deallocate or overwrite it. */ ++ ++static bool ++elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect) ++{ ++ asection *sect2; ++ ++ if (bfd_get_section_by_name (abfd, name) != NULL) ++ return true; ++ ++ sect2 = bfd_make_section_with_flags (abfd, name, sect->flags); ++ if (sect2 == NULL) ++ return false; ++ ++ sect2->size = sect->size; ++ sect2->filepos = sect->filepos; ++ sect2->alignment_power = sect->alignment_power; ++ return true; ++} ++ ++/* Create a pseudosection containing SIZE bytes at FILEPOS. This ++ actually creates up to two pseudosections: ++ - For the single-threaded case, a section named NAME, unless ++ such a section already exists. ++ - For the multi-threaded case, a section named "NAME/PID", where ++ PID is elfcore_make_pid (abfd). ++ Both pseudosections have identical contents. */ ++bool ++_bfd_elfcore_make_pseudosection (bfd *abfd, ++ char *name, ++ size_t size, ++ ufile_ptr filepos) ++{ ++ char buf[100]; ++ char *threaded_name; ++ size_t len; ++ asection *sect; ++ ++ /* Build the section name. */ ++ ++ sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd)); ++ len = strlen (buf) + 1; ++ threaded_name = (char *) bfd_alloc (abfd, len); ++ if (threaded_name == NULL) ++ return false; ++ memcpy (threaded_name, buf, len); ++ ++ sect = bfd_make_section_anyway_with_flags (abfd, threaded_name, ++ SEC_HAS_CONTENTS); ++ if (sect == NULL) ++ return false; ++ sect->size = size; ++ sect->filepos = filepos; ++ sect->alignment_power = 2; ++ ++ return elfcore_maybe_make_sect (abfd, name, sect); ++} ++ ++static bool ++elfcore_make_auxv_note_section (bfd *abfd, Elf_Internal_Note *note, ++ size_t offs) ++{ ++ asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv", ++ SEC_HAS_CONTENTS); ++ ++ if (sect == NULL) ++ return false; ++ ++ sect->size = note->descsz - offs; ++ sect->filepos = note->descpos + offs; ++ sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32; ++ ++ return true; ++} ++ ++/* prstatus_t exists on: ++ solaris 2.5+ ++ linux 2.[01] + glibc ++ unixware 4.2 ++*/ ++ ++#if defined (HAVE_PRSTATUS_T) ++ ++static bool ++elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) ++{ ++ size_t size; ++ int offset; ++ ++ if (note->descsz == sizeof (prstatus_t)) ++ { ++ prstatus_t prstat; ++ ++ size = sizeof (prstat.pr_reg); ++ offset = offsetof (prstatus_t, pr_reg); ++ memcpy (&prstat, note->descdata, sizeof (prstat)); ++ ++ /* Do not overwrite the core signal if it ++ has already been set by another thread. */ ++ if (elf_tdata (abfd)->core->signal == 0) ++ elf_tdata (abfd)->core->signal = prstat.pr_cursig; ++ if (elf_tdata (abfd)->core->pid == 0) ++ elf_tdata (abfd)->core->pid = prstat.pr_pid; ++ ++ /* pr_who exists on: ++ solaris 2.5+ ++ unixware 4.2 ++ pr_who doesn't exist on: ++ linux 2.[01] ++ */ ++#if defined (HAVE_PRSTATUS_T_PR_WHO) ++ elf_tdata (abfd)->core->lwpid = prstat.pr_who; ++#else ++ elf_tdata (abfd)->core->lwpid = prstat.pr_pid; ++#endif ++ } ++#if defined (HAVE_PRSTATUS32_T) ++ else if (note->descsz == sizeof (prstatus32_t)) ++ { ++ /* 64-bit host, 32-bit corefile */ ++ prstatus32_t prstat; ++ ++ size = sizeof (prstat.pr_reg); ++ offset = offsetof (prstatus32_t, pr_reg); ++ memcpy (&prstat, note->descdata, sizeof (prstat)); ++ ++ /* Do not overwrite the core signal if it ++ has already been set by another thread. */ ++ if (elf_tdata (abfd)->core->signal == 0) ++ elf_tdata (abfd)->core->signal = prstat.pr_cursig; ++ if (elf_tdata (abfd)->core->pid == 0) ++ elf_tdata (abfd)->core->pid = prstat.pr_pid; ++ ++ /* pr_who exists on: ++ solaris 2.5+ ++ unixware 4.2 ++ pr_who doesn't exist on: ++ linux 2.[01] ++ */ ++#if defined (HAVE_PRSTATUS32_T_PR_WHO) ++ elf_tdata (abfd)->core->lwpid = prstat.pr_who; ++#else ++ elf_tdata (abfd)->core->lwpid = prstat.pr_pid; ++#endif ++ } ++#endif /* HAVE_PRSTATUS32_T */ ++ else ++ { ++ /* Fail - we don't know how to handle any other ++ note size (ie. data object type). */ ++ return true; ++ } ++ ++ /* Make a ".reg/999" section and a ".reg" section. */ ++ return _bfd_elfcore_make_pseudosection (abfd, ".reg", ++ size, note->descpos + offset); ++} ++#endif /* defined (HAVE_PRSTATUS_T) */ ++ ++/* Create a pseudosection containing the exact contents of NOTE. */ ++static bool ++elfcore_make_note_pseudosection (bfd *abfd, ++ char *name, ++ Elf_Internal_Note *note) ++{ ++ return _bfd_elfcore_make_pseudosection (abfd, name, ++ note->descsz, note->descpos); ++} ++ ++/* There isn't a consistent prfpregset_t across platforms, ++ but it doesn't matter, because we don't have to pick this ++ data structure apart. */ ++ ++static bool ++elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg2", note); ++} ++ ++/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note ++ type of NT_PRXFPREG. Just include the whole note's contents ++ literally. */ ++ ++static bool ++elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note); ++} ++ ++/* Linux dumps the Intel XSAVE extended state in a note named "LINUX" ++ with a note type of NT_X86_XSTATE. Just include the whole note's ++ contents literally. */ ++ ++static bool ++elfcore_grok_xstatereg (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-xstate", note); ++} ++ ++static bool ++elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note); ++} ++ ++static bool ++elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vsx", note); ++} ++ ++static bool ++elfcore_grok_ppc_tar (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tar", note); ++} ++ ++static bool ++elfcore_grok_ppc_ppr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-ppr", note); ++} ++ ++static bool ++elfcore_grok_ppc_dscr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-dscr", note); ++} ++ ++static bool ++elfcore_grok_ppc_ebb (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-ebb", note); ++} ++ ++static bool ++elfcore_grok_ppc_pmu (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-pmu", note); ++} ++ ++static bool ++elfcore_grok_ppc_tm_cgpr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cgpr", note); ++} ++ ++static bool ++elfcore_grok_ppc_tm_cfpr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cfpr", note); ++} ++ ++static bool ++elfcore_grok_ppc_tm_cvmx (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cvmx", note); ++} ++ ++static bool ++elfcore_grok_ppc_tm_cvsx (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cvsx", note); ++} ++ ++static bool ++elfcore_grok_ppc_tm_spr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-spr", note); ++} ++ ++static bool ++elfcore_grok_ppc_tm_ctar (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-ctar", note); ++} ++ ++static bool ++elfcore_grok_ppc_tm_cppr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cppr", note); ++} ++ ++static bool ++elfcore_grok_ppc_tm_cdscr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cdscr", note); ++} ++ ++static bool ++elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note); ++} ++ ++static bool ++elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-timer", note); ++} ++ ++static bool ++elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-todcmp", note); ++} ++ ++static bool ++elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-todpreg", note); ++} ++ ++static bool ++elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-ctrs", note); ++} ++ ++static bool ++elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note); ++} ++ ++static bool ++elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note); ++} ++ ++static bool ++elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note); ++} ++ ++static bool ++elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note); ++} ++ ++static bool ++elfcore_grok_s390_vxrs_low (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-low", note); ++} ++ ++static bool ++elfcore_grok_s390_vxrs_high (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-high", note); ++} ++ ++static bool ++elfcore_grok_s390_gs_cb (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-cb", note); ++} ++ ++static bool ++elfcore_grok_s390_gs_bc (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-bc", note); ++} ++ ++static bool ++elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note); ++} ++ ++static bool ++elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-tls", note); ++} ++ ++static bool ++elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-break", note); ++} ++ ++static bool ++elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-watch", note); ++} ++ ++static bool ++elfcore_grok_aarch_sve (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-sve", note); ++} ++ ++static bool ++elfcore_grok_aarch_pauth (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-pauth", note); ++} ++ ++static bool ++elfcore_grok_aarch_mte (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-mte", ++ note); ++} ++ ++static bool ++elfcore_grok_arc_v2 (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-arc-v2", note); ++} ++ ++/* Convert NOTE into a bfd_section called ".reg-riscv-csr". Return TRUE if ++ successful otherwise, return FALSE. */ ++ ++static bool ++elfcore_grok_riscv_csr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-riscv-csr", note); ++} ++ ++/* Convert NOTE into a bfd_section called ".gdb-tdesc". Return TRUE if ++ successful otherwise, return FALSE. */ ++ ++static bool ++elfcore_grok_gdb_tdesc (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".gdb-tdesc", note); ++} ++ ++static bool ++elfcore_grok_loongarch_cpucfg (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-cpucfg", note); ++} ++ ++static bool ++elfcore_grok_loongarch_lbt (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-lbt", note); ++} ++ ++static bool ++elfcore_grok_loongarch_lsx (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-lsx", note); ++} ++ ++static bool ++elfcore_grok_loongarch_lasx (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-lasx", note); ++} ++ ++#if defined (HAVE_PRPSINFO_T) ++typedef prpsinfo_t elfcore_psinfo_t; ++#if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */ ++typedef prpsinfo32_t elfcore_psinfo32_t; ++#endif ++#endif ++ ++#if defined (HAVE_PSINFO_T) ++typedef psinfo_t elfcore_psinfo_t; ++#if defined (HAVE_PSINFO32_T) /* Sparc64 cross Sparc32 */ ++typedef psinfo32_t elfcore_psinfo32_t; ++#endif ++#endif ++ ++/* return a malloc'ed copy of a string at START which is at ++ most MAX bytes long, possibly without a terminating '\0'. ++ the copy will always have a terminating '\0'. */ ++ ++char * ++_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max) ++{ ++ char *dups; ++ char *end = (char *) memchr (start, '\0', max); ++ size_t len; ++ ++ if (end == NULL) ++ len = max; ++ else ++ len = end - start; ++ ++ dups = (char *) bfd_alloc (abfd, len + 1); ++ if (dups == NULL) ++ return NULL; ++ ++ memcpy (dups, start, len); ++ dups[len] = '\0'; ++ ++ return dups; ++} ++ ++#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) ++static bool ++elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) ++{ ++ if (note->descsz == sizeof (elfcore_psinfo_t)) ++ { ++ elfcore_psinfo_t psinfo; ++ ++ memcpy (&psinfo, note->descdata, sizeof (psinfo)); ++ ++#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID) ++ elf_tdata (abfd)->core->pid = psinfo.pr_pid; ++#endif ++ elf_tdata (abfd)->core->program ++ = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, ++ sizeof (psinfo.pr_fname)); ++ ++ elf_tdata (abfd)->core->command ++ = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, ++ sizeof (psinfo.pr_psargs)); ++ } ++#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T) ++ else if (note->descsz == sizeof (elfcore_psinfo32_t)) ++ { ++ /* 64-bit host, 32-bit corefile */ ++ elfcore_psinfo32_t psinfo; ++ ++ memcpy (&psinfo, note->descdata, sizeof (psinfo)); ++ ++#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID) ++ elf_tdata (abfd)->core->pid = psinfo.pr_pid; ++#endif ++ elf_tdata (abfd)->core->program ++ = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, ++ sizeof (psinfo.pr_fname)); ++ ++ elf_tdata (abfd)->core->command ++ = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, ++ sizeof (psinfo.pr_psargs)); ++ } ++#endif ++ ++ else ++ { ++ /* Fail - we don't know how to handle any other ++ note size (ie. data object type). */ ++ return true; ++ } ++ ++ /* Note that for some reason, a spurious space is tacked ++ onto the end of the args in some (at least one anyway) ++ implementations, so strip it off if it exists. */ ++ ++ { ++ char *command = elf_tdata (abfd)->core->command; ++ int n = strlen (command); ++ ++ if (0 < n && command[n - 1] == ' ') ++ command[n - 1] = '\0'; ++ } ++ ++ return true; ++} ++#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */ ++ ++#if defined (HAVE_PSTATUS_T) ++static bool ++elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note) ++{ ++ if (note->descsz == sizeof (pstatus_t) ++#if defined (HAVE_PXSTATUS_T) ++ || note->descsz == sizeof (pxstatus_t) ++#endif ++ ) ++ { ++ pstatus_t pstat; ++ ++ memcpy (&pstat, note->descdata, sizeof (pstat)); ++ ++ elf_tdata (abfd)->core->pid = pstat.pr_pid; ++ } ++#if defined (HAVE_PSTATUS32_T) ++ else if (note->descsz == sizeof (pstatus32_t)) ++ { ++ /* 64-bit host, 32-bit corefile */ ++ pstatus32_t pstat; ++ ++ memcpy (&pstat, note->descdata, sizeof (pstat)); ++ ++ elf_tdata (abfd)->core->pid = pstat.pr_pid; ++ } ++#endif ++ /* Could grab some more details from the "representative" ++ lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an ++ NT_LWPSTATUS note, presumably. */ ++ ++ return true; ++} ++#endif /* defined (HAVE_PSTATUS_T) */ ++ ++#if defined (HAVE_LWPSTATUS_T) ++static bool ++elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note) ++{ ++ lwpstatus_t lwpstat; ++ char buf[100]; ++ char *name; ++ size_t len; ++ asection *sect; ++ ++ if (note->descsz != sizeof (lwpstat) ++#if defined (HAVE_LWPXSTATUS_T) ++ && note->descsz != sizeof (lwpxstatus_t) ++#endif ++ ) ++ return true; ++ ++ memcpy (&lwpstat, note->descdata, sizeof (lwpstat)); ++ ++ elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid; ++ /* Do not overwrite the core signal if it has already been set by ++ another thread. */ ++ if (elf_tdata (abfd)->core->signal == 0) ++ elf_tdata (abfd)->core->signal = lwpstat.pr_cursig; ++ ++ /* Make a ".reg/999" section. */ ++ ++ sprintf (buf, ".reg/%d", elfcore_make_pid (abfd)); ++ len = strlen (buf) + 1; ++ name = bfd_alloc (abfd, len); ++ if (name == NULL) ++ return false; ++ memcpy (name, buf, len); ++ ++ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); ++ if (sect == NULL) ++ return false; ++ ++#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT) ++ sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs); ++ sect->filepos = note->descpos ++ + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs); ++#endif ++ ++#if defined (HAVE_LWPSTATUS_T_PR_REG) ++ sect->size = sizeof (lwpstat.pr_reg); ++ sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg); ++#endif ++ ++ sect->alignment_power = 2; ++ ++ if (!elfcore_maybe_make_sect (abfd, ".reg", sect)) ++ return false; ++ ++ /* Make a ".reg2/999" section */ ++ ++ sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd)); ++ len = strlen (buf) + 1; ++ name = bfd_alloc (abfd, len); ++ if (name == NULL) ++ return false; ++ memcpy (name, buf, len); ++ ++ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); ++ if (sect == NULL) ++ return false; ++ ++#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT) ++ sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs); ++ sect->filepos = note->descpos ++ + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs); ++#endif ++ ++#if defined (HAVE_LWPSTATUS_T_PR_FPREG) ++ sect->size = sizeof (lwpstat.pr_fpreg); ++ sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg); ++#endif ++ ++ sect->alignment_power = 2; ++ ++ return elfcore_maybe_make_sect (abfd, ".reg2", sect); ++} ++#endif /* defined (HAVE_LWPSTATUS_T) */ ++ ++/* These constants, and the structure offsets used below, are defined by ++ Cygwin's core_dump.h */ ++#define NOTE_INFO_PROCESS 1 ++#define NOTE_INFO_THREAD 2 ++#define NOTE_INFO_MODULE 3 ++#define NOTE_INFO_MODULE64 4 ++ ++static bool ++elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note) ++{ ++ char buf[30]; ++ char *name; ++ size_t len; ++ unsigned int name_size; ++ asection *sect; ++ unsigned int type; ++ int is_active_thread; ++ bfd_vma base_addr; ++ ++ if (note->descsz < 4) ++ return true; ++ ++ if (! startswith (note->namedata, "win32")) ++ return true; ++ ++ type = bfd_get_32 (abfd, note->descdata); ++ ++ struct ++ { ++ const char *type_name; ++ unsigned long min_size; ++ } size_check[] = ++ { ++ { "NOTE_INFO_PROCESS", 12 }, ++ { "NOTE_INFO_THREAD", 12 }, ++ { "NOTE_INFO_MODULE", 12 }, ++ { "NOTE_INFO_MODULE64", 16 }, ++ }; ++ ++ if (type == 0 || type > (sizeof(size_check)/sizeof(size_check[0]))) ++ return true; ++ ++ if (note->descsz < size_check[type - 1].min_size) ++ { ++ _bfd_error_handler (_("%pB: warning: win32pstatus %s of size %lu bytes" ++ " is too small"), ++ abfd, size_check[type - 1].type_name, note->descsz); ++ return true; ++ } ++ ++ switch (type) ++ { ++ case NOTE_INFO_PROCESS: ++ /* FIXME: need to add ->core->command. */ ++ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 4); ++ elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 8); ++ break; ++ ++ case NOTE_INFO_THREAD: ++ /* Make a ".reg/" section containing the Win32 API thread CONTEXT ++ structure. */ ++ /* thread_info.tid */ ++ sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 4)); ++ ++ len = strlen (buf) + 1; ++ name = (char *) bfd_alloc (abfd, len); ++ if (name == NULL) ++ return false; ++ ++ memcpy (name, buf, len); ++ ++ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); ++ if (sect == NULL) ++ return false; ++ ++ /* sizeof (thread_info.thread_context) */ ++ sect->size = note->descsz - 12; ++ /* offsetof (thread_info.thread_context) */ ++ sect->filepos = note->descpos + 12; ++ sect->alignment_power = 2; ++ ++ /* thread_info.is_active_thread */ ++ is_active_thread = bfd_get_32 (abfd, note->descdata + 8); ++ ++ if (is_active_thread) ++ if (! elfcore_maybe_make_sect (abfd, ".reg", sect)) ++ return false; ++ break; ++ ++ case NOTE_INFO_MODULE: ++ case NOTE_INFO_MODULE64: ++ /* Make a ".module/xxxxxxxx" section. */ ++ if (type == NOTE_INFO_MODULE) ++ { ++ /* module_info.base_address */ ++ base_addr = bfd_get_32 (abfd, note->descdata + 4); ++ sprintf (buf, ".module/%08lx", (unsigned long) base_addr); ++ /* module_info.module_name_size */ ++ name_size = bfd_get_32 (abfd, note->descdata + 8); ++ } ++ else /* NOTE_INFO_MODULE64 */ ++ { ++ /* module_info.base_address */ ++ base_addr = bfd_get_64 (abfd, note->descdata + 4); ++ sprintf (buf, ".module/%016lx", (unsigned long) base_addr); ++ /* module_info.module_name_size */ ++ name_size = bfd_get_32 (abfd, note->descdata + 12); ++ } ++ ++ len = strlen (buf) + 1; ++ name = (char *) bfd_alloc (abfd, len); ++ if (name == NULL) ++ return false; ++ ++ memcpy (name, buf, len); ++ ++ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); ++ ++ if (sect == NULL) ++ return false; ++ ++ if (note->descsz < 12 + name_size) ++ { ++ _bfd_error_handler (_("%pB: win32pstatus NOTE_INFO_MODULE of size %lu" ++ " is too small to contain a name of size %u"), ++ abfd, note->descsz, name_size); ++ return true; ++ } ++ ++ sect->size = note->descsz; ++ sect->filepos = note->descpos; ++ sect->alignment_power = 2; ++ break; ++ ++ default: ++ return true; ++ } ++ ++ return true; ++} ++ ++static bool ++elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ switch (note->type) ++ { ++ default: ++ return true; ++ ++ case NT_PRSTATUS: ++ if (bed->elf_backend_grok_prstatus) ++ if ((*bed->elf_backend_grok_prstatus) (abfd, note)) ++ return true; ++#if defined (HAVE_PRSTATUS_T) ++ return elfcore_grok_prstatus (abfd, note); ++#else ++ return true; ++#endif ++ ++#if defined (HAVE_PSTATUS_T) ++ case NT_PSTATUS: ++ return elfcore_grok_pstatus (abfd, note); ++#endif ++ ++#if defined (HAVE_LWPSTATUS_T) ++ case NT_LWPSTATUS: ++ return elfcore_grok_lwpstatus (abfd, note); ++#endif ++ ++ case NT_FPREGSET: /* FIXME: rename to NT_PRFPREG */ ++ return elfcore_grok_prfpreg (abfd, note); ++ ++ case NT_WIN32PSTATUS: ++ return elfcore_grok_win32pstatus (abfd, note); ++ ++ case NT_PRXFPREG: /* Linux SSE extension */ ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_prxfpreg (abfd, note); ++ else ++ return true; ++ ++ case NT_X86_XSTATE: /* Linux XSAVE extension */ ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_xstatereg (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_VMX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_vmx (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_VSX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_vsx (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TAR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tar (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_PPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_ppr (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_DSCR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_dscr (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_EBB: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_ebb (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_PMU: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_pmu (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TM_CGPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cgpr (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TM_CFPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cfpr (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TM_CVMX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cvmx (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TM_CVSX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cvsx (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TM_SPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_spr (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TM_CTAR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_ctar (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TM_CPPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cppr (abfd, note); ++ else ++ return true; ++ ++ case NT_PPC_TM_CDSCR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cdscr (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_HIGH_GPRS: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_high_gprs (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_TIMER: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_timer (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_TODCMP: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_todcmp (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_TODPREG: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_todpreg (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_CTRS: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_ctrs (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_PREFIX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_prefix (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_LAST_BREAK: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_last_break (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_SYSTEM_CALL: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_system_call (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_TDB: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_tdb (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_VXRS_LOW: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_vxrs_low (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_VXRS_HIGH: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_vxrs_high (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_GS_CB: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_gs_cb (abfd, note); ++ else ++ return true; ++ ++ case NT_S390_GS_BC: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_s390_gs_bc (abfd, note); ++ else ++ return true; ++ ++ case NT_ARC_V2: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_arc_v2 (abfd, note); ++ else ++ return true; ++ ++ case NT_ARM_VFP: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_arm_vfp (abfd, note); ++ else ++ return true; ++ ++ case NT_ARM_TLS: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_aarch_tls (abfd, note); ++ else ++ return true; ++ ++ case NT_ARM_HW_BREAK: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_aarch_hw_break (abfd, note); ++ else ++ return true; ++ ++ case NT_ARM_HW_WATCH: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_aarch_hw_watch (abfd, note); ++ else ++ return true; ++ ++ case NT_ARM_SVE: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_aarch_sve (abfd, note); ++ else ++ return true; ++ ++ case NT_ARM_PAC_MASK: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_aarch_pauth (abfd, note); ++ else ++ return true; ++ ++ case NT_ARM_TAGGED_ADDR_CTRL: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_aarch_mte (abfd, note); ++ else ++ return true; ++ ++ case NT_GDB_TDESC: ++ if (note->namesz == 4 ++ && strcmp (note->namedata, "GDB") == 0) ++ return elfcore_grok_gdb_tdesc (abfd, note); ++ else ++ return true; ++ ++ case NT_RISCV_CSR: ++ if (note->namesz == 4 ++ && strcmp (note->namedata, "GDB") == 0) ++ return elfcore_grok_riscv_csr (abfd, note); ++ else ++ return true; ++ ++ case NT_LARCH_CPUCFG: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_loongarch_cpucfg (abfd, note); ++ else ++ return true; ++ ++ case NT_LARCH_LBT: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_loongarch_lbt (abfd, note); ++ else ++ return true; ++ ++ case NT_LARCH_LSX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_loongarch_lsx (abfd, note); ++ else ++ return true; ++ ++ case NT_LARCH_LASX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_loongarch_lasx (abfd, note); ++ else ++ return true; ++ ++ case NT_PRPSINFO: ++ case NT_PSINFO: ++ if (bed->elf_backend_grok_psinfo) ++ if ((*bed->elf_backend_grok_psinfo) (abfd, note)) ++ return true; ++#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) ++ return elfcore_grok_psinfo (abfd, note); ++#else ++ return true; ++#endif ++ ++ case NT_AUXV: ++ return elfcore_make_auxv_note_section (abfd, note, 0); ++ ++ case NT_FILE: ++ return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file", ++ note); ++ ++ case NT_SIGINFO: ++ return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo", ++ note); ++ ++ } ++} ++ ++static bool ++elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note) ++{ ++ struct bfd_build_id* build_id; ++ ++ if (note->descsz == 0) ++ return false; ++ ++ build_id = bfd_alloc (abfd, sizeof (struct bfd_build_id) - 1 + note->descsz); ++ if (build_id == NULL) ++ return false; ++ ++ build_id->size = note->descsz; ++ memcpy (build_id->data, note->descdata, note->descsz); ++ abfd->build_id = build_id; ++ ++ return true; ++} ++ ++static bool ++elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ switch (note->type) ++ { ++ default: ++ return true; ++ ++ case NT_GNU_PROPERTY_TYPE_0: ++ return _bfd_elf_parse_gnu_properties (abfd, note); ++ ++ case NT_GNU_BUILD_ID: ++ return elfobj_grok_gnu_build_id (abfd, note); ++ } ++} ++ ++static bool ++elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note) ++{ ++ struct sdt_note *cur = ++ (struct sdt_note *) bfd_alloc (abfd, ++ sizeof (struct sdt_note) + note->descsz); ++ ++ cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head; ++ cur->size = (bfd_size_type) note->descsz; ++ memcpy (cur->data, note->descdata, note->descsz); ++ ++ elf_tdata (abfd)->sdt_note_head = cur; ++ ++ return true; ++} ++ ++static bool ++elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ switch (note->type) ++ { ++ case NT_STAPSDT: ++ return elfobj_grok_stapsdt_note_1 (abfd, note); ++ ++ default: ++ return true; ++ } ++} ++ ++static bool ++elfcore_grok_freebsd_psinfo (bfd *abfd, Elf_Internal_Note *note) ++{ ++ size_t offset; ++ ++ switch (elf_elfheader (abfd)->e_ident[EI_CLASS]) ++ { ++ case ELFCLASS32: ++ if (note->descsz < 108) ++ return false; ++ break; ++ ++ case ELFCLASS64: ++ if (note->descsz < 120) ++ return false; ++ break; ++ ++ default: ++ return false; ++ } ++ ++ /* Check for version 1 in pr_version. */ ++ if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1) ++ return false; ++ ++ offset = 4; ++ ++ /* Skip over pr_psinfosz. */ ++ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32) ++ offset += 4; ++ else ++ { ++ offset += 4; /* Padding before pr_psinfosz. */ ++ offset += 8; ++ } ++ ++ /* pr_fname is PRFNAMESZ (16) + 1 bytes in size. */ ++ elf_tdata (abfd)->core->program ++ = _bfd_elfcore_strndup (abfd, note->descdata + offset, 17); ++ offset += 17; ++ ++ /* pr_psargs is PRARGSZ (80) + 1 bytes in size. */ ++ elf_tdata (abfd)->core->command ++ = _bfd_elfcore_strndup (abfd, note->descdata + offset, 81); ++ offset += 81; ++ ++ /* Padding before pr_pid. */ ++ offset += 2; ++ ++ /* The pr_pid field was added in version "1a". */ ++ if (note->descsz < offset + 4) ++ return true; ++ ++ elf_tdata (abfd)->core->pid ++ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); ++ ++ return true; ++} ++ ++static bool ++elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note) ++{ ++ size_t offset; ++ size_t size; ++ size_t min_size; ++ ++ /* Compute offset of pr_getregsz, skipping over pr_statussz. ++ Also compute minimum size of this note. */ ++ switch (elf_elfheader (abfd)->e_ident[EI_CLASS]) ++ { ++ case ELFCLASS32: ++ offset = 4 + 4; ++ min_size = offset + (4 * 2) + 4 + 4 + 4; ++ break; ++ ++ case ELFCLASS64: ++ offset = 4 + 4 + 8; /* Includes padding before pr_statussz. */ ++ min_size = offset + (8 * 2) + 4 + 4 + 4 + 4; ++ break; ++ ++ default: ++ return false; ++ } ++ ++ if (note->descsz < min_size) ++ return false; ++ ++ /* Check for version 1 in pr_version. */ ++ if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1) ++ return false; ++ ++ /* Extract size of pr_reg from pr_gregsetsz. */ ++ /* Skip over pr_gregsetsz and pr_fpregsetsz. */ ++ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32) ++ { ++ size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); ++ offset += 4 * 2; ++ } ++ else ++ { ++ size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset); ++ offset += 8 * 2; ++ } ++ ++ /* Skip over pr_osreldate. */ ++ offset += 4; ++ ++ /* Read signal from pr_cursig. */ ++ if (elf_tdata (abfd)->core->signal == 0) ++ elf_tdata (abfd)->core->signal ++ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); ++ offset += 4; ++ ++ /* Read TID from pr_pid. */ ++ elf_tdata (abfd)->core->lwpid ++ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); ++ offset += 4; ++ ++ /* Padding before pr_reg. */ ++ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) ++ offset += 4; ++ ++ /* Make sure that there is enough data remaining in the note. */ ++ if ((note->descsz - offset) < size) ++ return false; ++ ++ /* Make a ".reg/999" section and a ".reg" section. */ ++ return _bfd_elfcore_make_pseudosection (abfd, ".reg", ++ size, note->descpos + offset); ++} ++ ++static bool ++elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ switch (note->type) ++ { ++ case NT_PRSTATUS: ++ if (bed->elf_backend_grok_freebsd_prstatus) ++ if ((*bed->elf_backend_grok_freebsd_prstatus) (abfd, note)) ++ return true; ++ return elfcore_grok_freebsd_prstatus (abfd, note); ++ ++ case NT_FPREGSET: ++ return elfcore_grok_prfpreg (abfd, note); ++ ++ case NT_PRPSINFO: ++ return elfcore_grok_freebsd_psinfo (abfd, note); ++ ++ case NT_FREEBSD_THRMISC: ++ return elfcore_make_note_pseudosection (abfd, ".thrmisc", note); ++ ++ case NT_FREEBSD_PROCSTAT_PROC: ++ return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.proc", ++ note); ++ ++ case NT_FREEBSD_PROCSTAT_FILES: ++ return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.files", ++ note); ++ ++ case NT_FREEBSD_PROCSTAT_VMMAP: ++ return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.vmmap", ++ note); ++ ++ case NT_FREEBSD_PROCSTAT_AUXV: ++ return elfcore_make_auxv_note_section (abfd, note, 4); ++ ++ case NT_FREEBSD_X86_SEGBASES: ++ return elfcore_make_note_pseudosection (abfd, ".reg-x86-segbases", note); ++ ++ case NT_X86_XSTATE: ++ return elfcore_grok_xstatereg (abfd, note); ++ ++ case NT_FREEBSD_PTLWPINFO: ++ return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo", ++ note); ++ ++ case NT_ARM_TLS: ++ return elfcore_grok_aarch_tls (abfd, note); ++ ++ case NT_ARM_VFP: ++ return elfcore_grok_arm_vfp (abfd, note); ++ ++ default: ++ return true; ++ } ++} ++ ++static bool ++elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp) ++{ ++ char *cp; ++ ++ cp = strchr (note->namedata, '@'); ++ if (cp != NULL) ++ { ++ *lwpidp = atoi(cp + 1); ++ return true; ++ } ++ return false; ++} ++ ++static bool ++elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note) ++{ ++ if (note->descsz <= 0x7c + 31) ++ return false; ++ ++ /* Signal number at offset 0x08. */ ++ elf_tdata (abfd)->core->signal ++ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08); ++ ++ /* Process ID at offset 0x50. */ ++ elf_tdata (abfd)->core->pid ++ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50); ++ ++ /* Command name at 0x7c (max 32 bytes, including nul). */ ++ elf_tdata (abfd)->core->command ++ = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31); ++ ++ return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo", ++ note); ++} ++ ++static bool ++elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ int lwp; ++ ++ if (elfcore_netbsd_get_lwpid (note, &lwp)) ++ elf_tdata (abfd)->core->lwpid = lwp; ++ ++ switch (note->type) ++ { ++ case NT_NETBSDCORE_PROCINFO: ++ /* NetBSD-specific core "procinfo". Note that we expect to ++ find this note before any of the others, which is fine, ++ since the kernel writes this note out first when it ++ creates a core file. */ ++ return elfcore_grok_netbsd_procinfo (abfd, note); ++ case NT_NETBSDCORE_AUXV: ++ /* NetBSD-specific Elf Auxiliary Vector data. */ ++ return elfcore_make_auxv_note_section (abfd, note, 4); ++ case NT_NETBSDCORE_LWPSTATUS: ++ return elfcore_make_note_pseudosection (abfd, ++ ".note.netbsdcore.lwpstatus", ++ note); ++ default: ++ break; ++ } ++ ++ /* As of March 2020 there are no other machine-independent notes ++ defined for NetBSD core files. If the note type is less ++ than the start of the machine-dependent note types, we don't ++ understand it. */ ++ ++ if (note->type < NT_NETBSDCORE_FIRSTMACH) ++ return true; ++ ++ ++ switch (bfd_get_arch (abfd)) ++ { ++ /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and ++ PT_GETFPREGS == mach+2. */ ++ ++ case bfd_arch_aarch64: ++ case bfd_arch_alpha: ++ case bfd_arch_sparc: ++ switch (note->type) ++ { ++ case NT_NETBSDCORE_FIRSTMACH+0: ++ return elfcore_make_note_pseudosection (abfd, ".reg", note); ++ ++ case NT_NETBSDCORE_FIRSTMACH+2: ++ return elfcore_make_note_pseudosection (abfd, ".reg2", note); ++ ++ default: ++ return true; ++ } ++ ++ /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5. ++ There's also old PT___GETREGS40 == mach + 1 for old reg ++ structure which lacks GBR. */ ++ ++ case bfd_arch_sh: ++ switch (note->type) ++ { ++ case NT_NETBSDCORE_FIRSTMACH+3: ++ return elfcore_make_note_pseudosection (abfd, ".reg", note); ++ ++ case NT_NETBSDCORE_FIRSTMACH+5: ++ return elfcore_make_note_pseudosection (abfd, ".reg2", note); ++ ++ default: ++ return true; ++ } ++ ++ /* On all other arch's, PT_GETREGS == mach+1 and ++ PT_GETFPREGS == mach+3. */ ++ ++ default: ++ switch (note->type) ++ { ++ case NT_NETBSDCORE_FIRSTMACH+1: ++ return elfcore_make_note_pseudosection (abfd, ".reg", note); ++ ++ case NT_NETBSDCORE_FIRSTMACH+3: ++ return elfcore_make_note_pseudosection (abfd, ".reg2", note); ++ ++ default: ++ return true; ++ } ++ } ++ /* NOTREACHED */ ++} ++ ++static bool ++elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note) ++{ ++ if (note->descsz <= 0x48 + 31) ++ return false; ++ ++ /* Signal number at offset 0x08. */ ++ elf_tdata (abfd)->core->signal ++ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08); ++ ++ /* Process ID at offset 0x20. */ ++ elf_tdata (abfd)->core->pid ++ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20); ++ ++ /* Command name at 0x48 (max 32 bytes, including nul). */ ++ elf_tdata (abfd)->core->command ++ = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31); ++ ++ return true; ++} ++ ++/* Processes Solaris's process status note. ++ sig_off ~ offsetof(prstatus_t, pr_cursig) ++ pid_off ~ offsetof(prstatus_t, pr_pid) ++ lwpid_off ~ offsetof(prstatus_t, pr_who) ++ gregset_size ~ sizeof(gregset_t) ++ gregset_offset ~ offsetof(prstatus_t, pr_reg) */ ++ ++static bool ++elfcore_grok_solaris_prstatus (bfd *abfd, Elf_Internal_Note* note, int sig_off, ++ int pid_off, int lwpid_off, size_t gregset_size, ++ size_t gregset_offset) ++{ ++ asection *sect = NULL; ++ elf_tdata (abfd)->core->signal ++ = bfd_get_16 (abfd, note->descdata + sig_off); ++ elf_tdata (abfd)->core->pid ++ = bfd_get_32 (abfd, note->descdata + pid_off); ++ elf_tdata (abfd)->core->lwpid ++ = bfd_get_32 (abfd, note->descdata + lwpid_off); ++ ++ sect = bfd_get_section_by_name (abfd, ".reg"); ++ if (sect != NULL) ++ sect->size = gregset_size; ++ ++ return _bfd_elfcore_make_pseudosection (abfd, ".reg", gregset_size, ++ note->descpos + gregset_offset); ++} ++ ++/* Gets program and arguments from a core. ++ prog_off ~ offsetof(prpsinfo | psinfo_t, pr_fname) ++ comm_off ~ offsetof(prpsinfo | psinfo_t, pr_psargs) */ ++ ++static bool ++elfcore_grok_solaris_info(bfd *abfd, Elf_Internal_Note* note, ++ int prog_off, int comm_off) ++{ ++ elf_tdata (abfd)->core->program ++ = _bfd_elfcore_strndup (abfd, note->descdata + prog_off, 16); ++ elf_tdata (abfd)->core->command ++ = _bfd_elfcore_strndup (abfd, note->descdata + comm_off, 80); ++ ++ return true; ++} ++ ++/* Processes Solaris's LWP status note. ++ gregset_size ~ sizeof(gregset_t) ++ gregset_off ~ offsetof(lwpstatus_t, pr_reg) ++ fpregset_size ~ sizeof(fpregset_t) ++ fpregset_off ~ offsetof(lwpstatus_t, pr_fpreg) */ ++ ++static bool ++elfcore_grok_solaris_lwpstatus (bfd *abfd, Elf_Internal_Note* note, ++ size_t gregset_size, int gregset_off, ++ size_t fpregset_size, int fpregset_off) ++{ ++ asection *sect = NULL; ++ char reg2_section_name[16] = { 0 }; ++ ++ (void) snprintf (reg2_section_name, 16, "%s/%i", ".reg2", ++ elf_tdata (abfd)->core->lwpid); ++ ++ /* offsetof(lwpstatus_t, pr_lwpid) */ ++ elf_tdata (abfd)->core->lwpid ++ = bfd_get_32 (abfd, note->descdata + 4); ++ /* offsetof(lwpstatus_t, pr_cursig) */ ++ elf_tdata (abfd)->core->signal ++ = bfd_get_16 (abfd, note->descdata + 12); ++ ++ sect = bfd_get_section_by_name (abfd, ".reg"); ++ if (sect != NULL) ++ sect->size = gregset_size; ++ else if (!_bfd_elfcore_make_pseudosection (abfd, ".reg", gregset_size, ++ note->descpos + gregset_off)) ++ return false; ++ ++ sect = bfd_get_section_by_name (abfd, reg2_section_name); ++ if (sect != NULL) ++ { ++ sect->size = fpregset_size; ++ sect->filepos = note->descpos + fpregset_off; ++ sect->alignment_power = 2; ++ } ++ else if (!_bfd_elfcore_make_pseudosection (abfd, ".reg2", fpregset_size, ++ note->descpos + fpregset_off)) ++ return false; ++ ++ return true; ++} ++ ++static bool ++elfcore_grok_solaris_note_impl (bfd *abfd, Elf_Internal_Note *note) ++{ ++ if (note == NULL) ++ return false; ++ ++ /* core files are identified as 32- or 64-bit, SPARC or x86, ++ by the size of the descsz which matches the sizeof() ++ the type appropriate for that note type (e.g., prstatus_t for ++ SOLARIS_NT_PRSTATUS) for the corresponding architecture ++ on Solaris. The core file bitness may differ from the bitness of ++ gdb itself, so fixed values are used instead of sizeof(). ++ Appropriate fixed offsets are also used to obtain data from ++ the note. */ ++ ++ switch ((int) note->type) ++ { ++ case SOLARIS_NT_PRSTATUS: ++ switch (note->descsz) ++ { ++ case 508: /* sizeof(prstatus_t) SPARC 32-bit */ ++ return elfcore_grok_solaris_prstatus(abfd, note, ++ 136, 216, 308, 152, 356); ++ case 904: /* sizeof(prstatus_t) SPARC 64-bit */ ++ return elfcore_grok_solaris_prstatus(abfd, note, ++ 264, 360, 520, 304, 600); ++ case 432: /* sizeof(prstatus_t) Intel 32-bit */ ++ return elfcore_grok_solaris_prstatus(abfd, note, ++ 136, 216, 308, 76, 356); ++ case 824: /* sizeof(prstatus_t) Intel 64-bit */ ++ return elfcore_grok_solaris_prstatus(abfd, note, ++ 264, 360, 520, 224, 600); ++ default: ++ return true; ++ } ++ ++ case SOLARIS_NT_PSINFO: ++ case SOLARIS_NT_PRPSINFO: ++ switch (note->descsz) ++ { ++ case 260: /* sizeof(prpsinfo_t) SPARC and Intel 32-bit */ ++ return elfcore_grok_solaris_info(abfd, note, 84, 100); ++ case 328: /* sizeof(prpsinfo_t) SPARC and Intel 64-bit */ ++ return elfcore_grok_solaris_info(abfd, note, 120, 136); ++ case 360: /* sizeof(psinfo_t) SPARC and Intel 32-bit */ ++ return elfcore_grok_solaris_info(abfd, note, 88, 104); ++ case 440: /* sizeof(psinfo_t) SPARC and Intel 64-bit */ ++ return elfcore_grok_solaris_info(abfd, note, 136, 152); ++ default: ++ return true; ++ } ++ ++ case SOLARIS_NT_LWPSTATUS: ++ switch (note->descsz) ++ { ++ case 896: /* sizeof(lwpstatus_t) SPARC 32-bit */ ++ return elfcore_grok_solaris_lwpstatus(abfd, note, ++ 152, 344, 400, 496); ++ case 1392: /* sizeof(lwpstatus_t) SPARC 64-bit */ ++ return elfcore_grok_solaris_lwpstatus(abfd, note, ++ 304, 544, 544, 848); ++ case 800: /* sizeof(lwpstatus_t) Intel 32-bit */ ++ return elfcore_grok_solaris_lwpstatus(abfd, note, ++ 76, 344, 380, 420); ++ case 1296: /* sizeof(lwpstatus_t) Intel 64-bit */ ++ return elfcore_grok_solaris_lwpstatus(abfd, note, ++ 224, 544, 528, 768); ++ default: ++ return true; ++ } ++ ++ case SOLARIS_NT_LWPSINFO: ++ /* sizeof(lwpsinfo_t) on 32- and 64-bit, respectively */ ++ if (note->descsz == 128 || note->descsz == 152) ++ elf_tdata (abfd)->core->lwpid = ++ bfd_get_32 (abfd, note->descdata + 4); ++ break; ++ ++ default: ++ break; ++ } ++ ++ return true; ++} ++ ++/* For name starting with "CORE" this may be either a Solaris ++ core file or a gdb-generated core file. Do Solaris-specific ++ processing on selected note types first with ++ elfcore_grok_solaris_note(), then process the note ++ in elfcore_grok_note(). */ ++ ++static bool ++elfcore_grok_solaris_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ if (!elfcore_grok_solaris_note_impl (abfd, note)) ++ return false; ++ ++ return elfcore_grok_note (abfd, note); ++} ++ ++static bool ++elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ if (note->type == NT_OPENBSD_PROCINFO) ++ return elfcore_grok_openbsd_procinfo (abfd, note); ++ ++ if (note->type == NT_OPENBSD_REGS) ++ return elfcore_make_note_pseudosection (abfd, ".reg", note); ++ ++ if (note->type == NT_OPENBSD_FPREGS) ++ return elfcore_make_note_pseudosection (abfd, ".reg2", note); ++ ++ if (note->type == NT_OPENBSD_XFPREGS) ++ return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note); ++ ++ if (note->type == NT_OPENBSD_AUXV) ++ return elfcore_make_auxv_note_section (abfd, note, 0); ++ ++ if (note->type == NT_OPENBSD_WCOOKIE) ++ { ++ asection *sect = bfd_make_section_anyway_with_flags (abfd, ".wcookie", ++ SEC_HAS_CONTENTS); ++ ++ if (sect == NULL) ++ return false; ++ sect->size = note->descsz; ++ sect->filepos = note->descpos; ++ sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32; ++ ++ return true; ++ } ++ ++ return true; ++} ++ ++static bool ++elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid) ++{ ++ void *ddata = note->descdata; ++ char buf[100]; ++ char *name; ++ asection *sect; ++ short sig; ++ unsigned flags; ++ ++ if (note->descsz < 16) ++ return false; ++ ++ /* nto_procfs_status 'pid' field is at offset 0. */ ++ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata); ++ ++ /* nto_procfs_status 'tid' field is at offset 4. Pass it back. */ ++ *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4); ++ ++ /* nto_procfs_status 'flags' field is at offset 8. */ ++ flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8); ++ ++ /* nto_procfs_status 'what' field is at offset 14. */ ++ if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0) ++ { ++ elf_tdata (abfd)->core->signal = sig; ++ elf_tdata (abfd)->core->lwpid = *tid; ++ } ++ ++ /* _DEBUG_FLAG_CURTID (current thread) is 0x80. Some cores ++ do not come from signals so we make sure we set the current ++ thread just in case. */ ++ if (flags & 0x00000080) ++ elf_tdata (abfd)->core->lwpid = *tid; ++ ++ /* Make a ".qnx_core_status/%d" section. */ ++ sprintf (buf, ".qnx_core_status/%ld", *tid); ++ ++ name = (char *) bfd_alloc (abfd, strlen (buf) + 1); ++ if (name == NULL) ++ return false; ++ strcpy (name, buf); ++ ++ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); ++ if (sect == NULL) ++ return false; ++ ++ sect->size = note->descsz; ++ sect->filepos = note->descpos; ++ sect->alignment_power = 2; ++ ++ return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect)); ++} ++ ++static bool ++elfcore_grok_nto_regs (bfd *abfd, ++ Elf_Internal_Note *note, ++ long tid, ++ char *base) ++{ ++ char buf[100]; ++ char *name; ++ asection *sect; ++ ++ /* Make a "(base)/%d" section. */ ++ sprintf (buf, "%s/%ld", base, tid); ++ ++ name = (char *) bfd_alloc (abfd, strlen (buf) + 1); ++ if (name == NULL) ++ return false; ++ strcpy (name, buf); ++ ++ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); ++ if (sect == NULL) ++ return false; ++ ++ sect->size = note->descsz; ++ sect->filepos = note->descpos; ++ sect->alignment_power = 2; ++ ++ /* This is the current thread. */ ++ if (elf_tdata (abfd)->core->lwpid == tid) ++ return elfcore_maybe_make_sect (abfd, base, sect); ++ ++ return true; ++} ++ ++static bool ++elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ /* Every GREG section has a STATUS section before it. Store the ++ tid from the previous call to pass down to the next gregs ++ function. */ ++ static long tid = 1; ++ ++ switch (note->type) ++ { ++ case QNT_CORE_INFO: ++ return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note); ++ case QNT_CORE_STATUS: ++ return elfcore_grok_nto_status (abfd, note, &tid); ++ case QNT_CORE_GREG: ++ return elfcore_grok_nto_regs (abfd, note, tid, ".reg"); ++ case QNT_CORE_FPREG: ++ return elfcore_grok_nto_regs (abfd, note, tid, ".reg2"); ++ default: ++ return true; ++ } ++} ++ ++static bool ++elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ char *name; ++ asection *sect; ++ size_t len; ++ ++ /* Use note name as section name. */ ++ len = note->namesz; ++ name = (char *) bfd_alloc (abfd, len); ++ if (name == NULL) ++ return false; ++ memcpy (name, note->namedata, len); ++ name[len - 1] = '\0'; ++ ++ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); ++ if (sect == NULL) ++ return false; ++ ++ sect->size = note->descsz; ++ sect->filepos = note->descpos; ++ sect->alignment_power = 1; ++ ++ return true; ++} ++ ++/* Function: elfcore_write_note ++ ++ Inputs: ++ buffer to hold note, and current size of buffer ++ name of note ++ type of note ++ data for note ++ size of data for note ++ ++ Writes note to end of buffer. ELF64 notes are written exactly as ++ for ELF32, despite the current (as of 2006) ELF gabi specifying ++ that they ought to have 8-byte namesz and descsz field, and have ++ 8-byte alignment. Other writers, eg. Linux kernel, do the same. ++ ++ Return: ++ Pointer to realloc'd buffer, *BUFSIZ updated. */ ++ ++char * ++elfcore_write_note (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const char *name, ++ int type, ++ const void *input, ++ int size) ++{ ++ Elf_External_Note *xnp; ++ size_t namesz; ++ size_t newspace; ++ char *dest; ++ ++ namesz = 0; ++ if (name != NULL) ++ namesz = strlen (name) + 1; ++ ++ newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4); ++ ++ buf = (char *) realloc (buf, *bufsiz + newspace); ++ if (buf == NULL) ++ return buf; ++ dest = buf + *bufsiz; ++ *bufsiz += newspace; ++ xnp = (Elf_External_Note *) dest; ++ H_PUT_32 (abfd, namesz, xnp->namesz); ++ H_PUT_32 (abfd, size, xnp->descsz); ++ H_PUT_32 (abfd, type, xnp->type); ++ dest = xnp->name; ++ if (name != NULL) ++ { ++ memcpy (dest, name, namesz); ++ dest += namesz; ++ while (namesz & 3) ++ { ++ *dest++ = '\0'; ++ ++namesz; ++ } ++ } ++ memcpy (dest, input, size); ++ dest += size; ++ while (size & 3) ++ { ++ *dest++ = '\0'; ++ ++size; ++ } ++ return buf; ++} ++ ++/* gcc-8 warns (*) on all the strncpy calls in this function about ++ possible string truncation. The "truncation" is not a bug. We ++ have an external representation of structs with fields that are not ++ necessarily NULL terminated and corresponding internal ++ representation fields that are one larger so that they can always ++ be NULL terminated. ++ gcc versions between 4.2 and 4.6 do not allow pragma control of ++ diagnostics inside functions, giving a hard error if you try to use ++ the finer control available with later versions. ++ gcc prior to 4.2 warns about diagnostic push and pop. ++ gcc-5, gcc-6 and gcc-7 warn that -Wstringop-truncation is unknown, ++ unless you also add #pragma GCC diagnostic ignored "-Wpragma". ++ (*) Depending on your system header files! */ ++#if GCC_VERSION >= 8000 ++# pragma GCC diagnostic push ++# pragma GCC diagnostic ignored "-Wstringop-truncation" ++#endif ++char * ++elfcore_write_prpsinfo (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const char *fname, ++ const char *psargs) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ if (bed->elf_backend_write_core_note != NULL) ++ { ++ char *ret; ++ ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, ++ NT_PRPSINFO, fname, psargs); ++ if (ret != NULL) ++ return ret; ++ } ++ ++#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) ++# if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T) ++ if (bed->s->elfclass == ELFCLASS32) ++ { ++# if defined (HAVE_PSINFO32_T) ++ psinfo32_t data; ++ int note_type = NT_PSINFO; ++# else ++ prpsinfo32_t data; ++ int note_type = NT_PRPSINFO; ++# endif ++ ++ memset (&data, 0, sizeof (data)); ++ strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); ++ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); ++ return elfcore_write_note (abfd, buf, bufsiz, ++ "CORE", note_type, &data, sizeof (data)); ++ } ++ else ++# endif ++ { ++# if defined (HAVE_PSINFO_T) ++ psinfo_t data; ++ int note_type = NT_PSINFO; ++# else ++ prpsinfo_t data; ++ int note_type = NT_PRPSINFO; ++# endif ++ ++ memset (&data, 0, sizeof (data)); ++ strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); ++ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); ++ return elfcore_write_note (abfd, buf, bufsiz, ++ "CORE", note_type, &data, sizeof (data)); ++ } ++#endif /* PSINFO_T or PRPSINFO_T */ ++ ++ free (buf); ++ return NULL; ++} ++#if GCC_VERSION >= 8000 ++# pragma GCC diagnostic pop ++#endif ++ ++char * ++elfcore_write_linux_prpsinfo32 ++ (bfd *abfd, char *buf, int *bufsiz, ++ const struct elf_internal_linux_prpsinfo *prpsinfo) ++{ ++ if (get_elf_backend_data (abfd)->linux_prpsinfo32_ugid16) ++ { ++ struct elf_external_linux_prpsinfo32_ugid16 data; ++ ++ swap_linux_prpsinfo32_ugid16_out (abfd, prpsinfo, &data); ++ return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO, ++ &data, sizeof (data)); ++ } ++ else ++ { ++ struct elf_external_linux_prpsinfo32_ugid32 data; ++ ++ swap_linux_prpsinfo32_ugid32_out (abfd, prpsinfo, &data); ++ return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO, ++ &data, sizeof (data)); ++ } ++} ++ ++char * ++elfcore_write_linux_prpsinfo64 ++ (bfd *abfd, char *buf, int *bufsiz, ++ const struct elf_internal_linux_prpsinfo *prpsinfo) ++{ ++ if (get_elf_backend_data (abfd)->linux_prpsinfo64_ugid16) ++ { ++ struct elf_external_linux_prpsinfo64_ugid16 data; ++ ++ swap_linux_prpsinfo64_ugid16_out (abfd, prpsinfo, &data); ++ return elfcore_write_note (abfd, buf, bufsiz, ++ "CORE", NT_PRPSINFO, &data, sizeof (data)); ++ } ++ else ++ { ++ struct elf_external_linux_prpsinfo64_ugid32 data; ++ ++ swap_linux_prpsinfo64_ugid32_out (abfd, prpsinfo, &data); ++ return elfcore_write_note (abfd, buf, bufsiz, ++ "CORE", NT_PRPSINFO, &data, sizeof (data)); ++ } ++} ++ ++char * ++elfcore_write_prstatus (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ long pid, ++ int cursig, ++ const void *gregs) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ if (bed->elf_backend_write_core_note != NULL) ++ { ++ char *ret; ++ ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, ++ NT_PRSTATUS, ++ pid, cursig, gregs); ++ if (ret != NULL) ++ return ret; ++ } ++ ++#if defined (HAVE_PRSTATUS_T) ++#if defined (HAVE_PRSTATUS32_T) ++ if (bed->s->elfclass == ELFCLASS32) ++ { ++ prstatus32_t prstat; ++ ++ memset (&prstat, 0, sizeof (prstat)); ++ prstat.pr_pid = pid; ++ prstat.pr_cursig = cursig; ++ memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); ++ return elfcore_write_note (abfd, buf, bufsiz, "CORE", ++ NT_PRSTATUS, &prstat, sizeof (prstat)); ++ } ++ else ++#endif ++ { ++ prstatus_t prstat; ++ ++ memset (&prstat, 0, sizeof (prstat)); ++ prstat.pr_pid = pid; ++ prstat.pr_cursig = cursig; ++ memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); ++ return elfcore_write_note (abfd, buf, bufsiz, "CORE", ++ NT_PRSTATUS, &prstat, sizeof (prstat)); ++ } ++#endif /* HAVE_PRSTATUS_T */ ++ ++ free (buf); ++ return NULL; ++} ++ ++#if defined (HAVE_LWPSTATUS_T) ++char * ++elfcore_write_lwpstatus (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ long pid, ++ int cursig, ++ const void *gregs) ++{ ++ lwpstatus_t lwpstat; ++ const char *note_name = "CORE"; ++ ++ memset (&lwpstat, 0, sizeof (lwpstat)); ++ lwpstat.pr_lwpid = pid >> 16; ++ lwpstat.pr_cursig = cursig; ++#if defined (HAVE_LWPSTATUS_T_PR_REG) ++ memcpy (&lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg)); ++#elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT) ++#if !defined(gregs) ++ memcpy (lwpstat.pr_context.uc_mcontext.gregs, ++ gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs)); ++#else ++ memcpy (lwpstat.pr_context.uc_mcontext.__gregs, ++ gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs)); ++#endif ++#endif ++ return elfcore_write_note (abfd, buf, bufsiz, note_name, ++ NT_LWPSTATUS, &lwpstat, sizeof (lwpstat)); ++} ++#endif /* HAVE_LWPSTATUS_T */ ++ ++#if defined (HAVE_PSTATUS_T) ++char * ++elfcore_write_pstatus (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ long pid, ++ int cursig ATTRIBUTE_UNUSED, ++ const void *gregs ATTRIBUTE_UNUSED) ++{ ++ const char *note_name = "CORE"; ++#if defined (HAVE_PSTATUS32_T) ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ if (bed->s->elfclass == ELFCLASS32) ++ { ++ pstatus32_t pstat; ++ ++ memset (&pstat, 0, sizeof (pstat)); ++ pstat.pr_pid = pid & 0xffff; ++ buf = elfcore_write_note (abfd, buf, bufsiz, note_name, ++ NT_PSTATUS, &pstat, sizeof (pstat)); ++ return buf; ++ } ++ else ++#endif ++ { ++ pstatus_t pstat; ++ ++ memset (&pstat, 0, sizeof (pstat)); ++ pstat.pr_pid = pid & 0xffff; ++ buf = elfcore_write_note (abfd, buf, bufsiz, note_name, ++ NT_PSTATUS, &pstat, sizeof (pstat)); ++ return buf; ++ } ++} ++#endif /* HAVE_PSTATUS_T */ ++ ++char * ++elfcore_write_prfpreg (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *fpregs, ++ int size) ++{ ++ const char *note_name = "CORE"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_FPREGSET, fpregs, size); ++} ++ ++char * ++elfcore_write_prxfpreg (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *xfpregs, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PRXFPREG, xfpregs, size); ++} ++ ++char * ++elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz, ++ const void *xfpregs, int size) ++{ ++ char *note_name; ++ if (get_elf_backend_data (abfd)->elf_osabi == ELFOSABI_FREEBSD) ++ note_name = "FreeBSD"; ++ else ++ note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_X86_XSTATE, xfpregs, size); ++} ++ ++char * ++elfcore_write_x86_segbases (bfd *abfd, char *buf, int *bufsiz, ++ const void *regs, int size) ++{ ++ char *note_name = "FreeBSD"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_FREEBSD_X86_SEGBASES, regs, size); ++} ++ ++char * ++elfcore_write_ppc_vmx (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_vmx, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_VMX, ppc_vmx, size); ++} ++ ++char * ++elfcore_write_ppc_vsx (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_vsx, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_VSX, ppc_vsx, size); ++} ++ ++char * ++elfcore_write_ppc_tar (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tar, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TAR, ppc_tar, size); ++} ++ ++char * ++elfcore_write_ppc_ppr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_ppr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_PPR, ppc_ppr, size); ++} ++ ++char * ++elfcore_write_ppc_dscr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_dscr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_DSCR, ppc_dscr, size); ++} ++ ++char * ++elfcore_write_ppc_ebb (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_ebb, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_EBB, ppc_ebb, size); ++} ++ ++char * ++elfcore_write_ppc_pmu (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_pmu, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_PMU, ppc_pmu, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cgpr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cgpr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CGPR, ppc_tm_cgpr, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cfpr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cfpr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CFPR, ppc_tm_cfpr, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cvmx (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cvmx, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CVMX, ppc_tm_cvmx, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cvsx (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cvsx, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CVSX, ppc_tm_cvsx, size); ++} ++ ++char * ++elfcore_write_ppc_tm_spr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_spr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_SPR, ppc_tm_spr, size); ++} ++ ++char * ++elfcore_write_ppc_tm_ctar (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_ctar, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CTAR, ppc_tm_ctar, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cppr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cppr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CPPR, ppc_tm_cppr, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cdscr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cdscr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CDSCR, ppc_tm_cdscr, size); ++} ++ ++static char * ++elfcore_write_s390_high_gprs (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_high_gprs, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_HIGH_GPRS, ++ s390_high_gprs, size); ++} ++ ++char * ++elfcore_write_s390_timer (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_timer, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_TIMER, s390_timer, size); ++} ++ ++char * ++elfcore_write_s390_todcmp (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_todcmp, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_TODCMP, s390_todcmp, size); ++} ++ ++char * ++elfcore_write_s390_todpreg (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_todpreg, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_TODPREG, s390_todpreg, size); ++} ++ ++char * ++elfcore_write_s390_ctrs (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_ctrs, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_CTRS, s390_ctrs, size); ++} ++ ++char * ++elfcore_write_s390_prefix (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_prefix, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_PREFIX, s390_prefix, size); ++} ++ ++char * ++elfcore_write_s390_last_break (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_last_break, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_LAST_BREAK, ++ s390_last_break, size); ++} ++ ++char * ++elfcore_write_s390_system_call (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_system_call, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_SYSTEM_CALL, ++ s390_system_call, size); ++} ++ ++char * ++elfcore_write_s390_tdb (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_tdb, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_TDB, s390_tdb, size); ++} ++ ++char * ++elfcore_write_s390_vxrs_low (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_vxrs_low, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_VXRS_LOW, s390_vxrs_low, size); ++} ++ ++char * ++elfcore_write_s390_vxrs_high (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_vxrs_high, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_VXRS_HIGH, ++ s390_vxrs_high, size); ++} ++ ++char * ++elfcore_write_s390_gs_cb (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_gs_cb, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_GS_CB, ++ s390_gs_cb, size); ++} ++ ++char * ++elfcore_write_s390_gs_bc (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *s390_gs_bc, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_S390_GS_BC, ++ s390_gs_bc, size); ++} ++ ++char * ++elfcore_write_arm_vfp (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *arm_vfp, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_ARM_VFP, arm_vfp, size); ++} ++ ++char * ++elfcore_write_aarch_tls (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *aarch_tls, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_ARM_TLS, aarch_tls, size); ++} ++ ++char * ++elfcore_write_aarch_hw_break (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *aarch_hw_break, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_ARM_HW_BREAK, aarch_hw_break, size); ++} ++ ++char * ++elfcore_write_aarch_hw_watch (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *aarch_hw_watch, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_ARM_HW_WATCH, aarch_hw_watch, size); ++} ++ ++char * ++elfcore_write_aarch_sve (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *aarch_sve, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_ARM_SVE, aarch_sve, size); ++} ++ ++char * ++elfcore_write_aarch_pauth (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *aarch_pauth, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_ARM_PAC_MASK, aarch_pauth, size); ++} ++ ++char * ++elfcore_write_aarch_mte (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *aarch_mte, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_ARM_TAGGED_ADDR_CTRL, ++ aarch_mte, ++ size); ++} ++ ++char * ++elfcore_write_arc_v2 (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *arc_v2, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_ARC_V2, arc_v2, size); ++} ++ ++char * ++elfcore_write_loongarch_cpucfg (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *loongarch_cpucfg, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_LARCH_CPUCFG, ++ loongarch_cpucfg, size); ++} ++ ++char * ++elfcore_write_loongarch_lbt (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *loongarch_lbt, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_LARCH_LBT, loongarch_lbt, size); ++} ++ ++char * ++elfcore_write_loongarch_lsx (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *loongarch_lsx, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_LARCH_LSX, loongarch_lsx, size); ++} ++ ++char * ++elfcore_write_loongarch_lasx (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *loongarch_lasx, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_LARCH_LASX, loongarch_lasx, size); ++} ++ ++/* Write the buffer of csr values in CSRS (length SIZE) into the note ++ buffer BUF and update *BUFSIZ. ABFD is the bfd the note is being ++ written into. Return a pointer to the new start of the note buffer, to ++ replace BUF which may no longer be valid. */ ++ ++char * ++elfcore_write_riscv_csr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *csrs, ++ int size) ++{ ++ const char *note_name = "GDB"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_RISCV_CSR, csrs, size); ++} ++ ++/* Write the target description (a string) pointed to by TDESC, length ++ SIZE, into the note buffer BUF, and update *BUFSIZ. ABFD is the bfd the ++ note is being written into. Return a pointer to the new start of the ++ note buffer, to replace BUF which may no longer be valid. */ ++ ++char * ++elfcore_write_gdb_tdesc (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *tdesc, ++ int size) ++{ ++ const char *note_name = "GDB"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_GDB_TDESC, tdesc, size); ++} ++ ++char * ++elfcore_write_register_note (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const char *section, ++ const void *data, ++ int size) ++{ ++ if (strcmp (section, ".reg2") == 0) ++ return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-xfp") == 0) ++ return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-xstate") == 0) ++ return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-x86-segbases") == 0) ++ return elfcore_write_x86_segbases (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-vmx") == 0) ++ return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-vsx") == 0) ++ return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tar") == 0) ++ return elfcore_write_ppc_tar (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-ppr") == 0) ++ return elfcore_write_ppc_ppr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-dscr") == 0) ++ return elfcore_write_ppc_dscr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-ebb") == 0) ++ return elfcore_write_ppc_ebb (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-pmu") == 0) ++ return elfcore_write_ppc_pmu (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cgpr") == 0) ++ return elfcore_write_ppc_tm_cgpr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cfpr") == 0) ++ return elfcore_write_ppc_tm_cfpr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cvmx") == 0) ++ return elfcore_write_ppc_tm_cvmx (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cvsx") == 0) ++ return elfcore_write_ppc_tm_cvsx (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-spr") == 0) ++ return elfcore_write_ppc_tm_spr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-ctar") == 0) ++ return elfcore_write_ppc_tm_ctar (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cppr") == 0) ++ return elfcore_write_ppc_tm_cppr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cdscr") == 0) ++ return elfcore_write_ppc_tm_cdscr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-high-gprs") == 0) ++ return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-timer") == 0) ++ return elfcore_write_s390_timer (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-todcmp") == 0) ++ return elfcore_write_s390_todcmp (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-todpreg") == 0) ++ return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-ctrs") == 0) ++ return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-prefix") == 0) ++ return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-last-break") == 0) ++ return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-system-call") == 0) ++ return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-tdb") == 0) ++ return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-vxrs-low") == 0) ++ return elfcore_write_s390_vxrs_low (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-vxrs-high") == 0) ++ return elfcore_write_s390_vxrs_high (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-gs-cb") == 0) ++ return elfcore_write_s390_gs_cb (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-s390-gs-bc") == 0) ++ return elfcore_write_s390_gs_bc (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-arm-vfp") == 0) ++ return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-aarch-tls") == 0) ++ return elfcore_write_aarch_tls (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-aarch-hw-break") == 0) ++ return elfcore_write_aarch_hw_break (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-aarch-hw-watch") == 0) ++ return elfcore_write_aarch_hw_watch (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-aarch-sve") == 0) ++ return elfcore_write_aarch_sve (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-aarch-pauth") == 0) ++ return elfcore_write_aarch_pauth (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-aarch-mte") == 0) ++ return elfcore_write_aarch_mte (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-arc-v2") == 0) ++ return elfcore_write_arc_v2 (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".gdb-tdesc") == 0) ++ return elfcore_write_gdb_tdesc (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-riscv-csr") == 0) ++ return elfcore_write_riscv_csr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-loongarch-cpucfg") == 0) ++ return elfcore_write_loongarch_cpucfg (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-loongarch-lbt") == 0) ++ return elfcore_write_loongarch_lbt (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-loongarch-lsx") == 0) ++ return elfcore_write_loongarch_lsx (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-loongarch-lasx") == 0) ++ return elfcore_write_loongarch_lasx (abfd, buf, bufsiz, data, size); ++ return NULL; ++} ++ ++char * ++elfcore_write_file_note (bfd *obfd, char *note_data, int *note_size, ++ const void *buf, int bufsiz) ++{ ++ return elfcore_write_note (obfd, note_data, note_size, ++ "CORE", NT_FILE, buf, bufsiz); ++} ++ ++static bool ++elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset, ++ size_t align) ++{ ++ char *p; ++ ++ /* NB: CORE PT_NOTE segments may have p_align values of 0 or 1. ++ gABI specifies that PT_NOTE alignment should be aligned to 4 ++ bytes for 32-bit objects and to 8 bytes for 64-bit objects. If ++ align is less than 4, we use 4 byte alignment. */ ++ if (align < 4) ++ align = 4; ++ if (align != 4 && align != 8) ++ return false; ++ ++ p = buf; ++ while (p < buf + size) ++ { ++ Elf_External_Note *xnp = (Elf_External_Note *) p; ++ Elf_Internal_Note in; ++ ++ if (offsetof (Elf_External_Note, name) > buf - p + size) ++ return false; ++ ++ in.type = H_GET_32 (abfd, xnp->type); ++ ++ in.namesz = H_GET_32 (abfd, xnp->namesz); ++ in.namedata = xnp->name; ++ if (in.namesz > buf - in.namedata + size) ++ return false; ++ ++ in.descsz = H_GET_32 (abfd, xnp->descsz); ++ in.descdata = p + ELF_NOTE_DESC_OFFSET (in.namesz, align); ++ in.descpos = offset + (in.descdata - buf); ++ if (in.descsz != 0 ++ && (in.descdata >= buf + size ++ || in.descsz > buf - in.descdata + size)) ++ return false; ++ ++ switch (bfd_get_format (abfd)) ++ { ++ default: ++ return true; ++ ++ case bfd_core: ++ { ++#define GROKER_ELEMENT(S,F) {S, sizeof (S) - 1, F} ++ struct ++ { ++ const char * string; ++ size_t len; ++ bool (*func) (bfd *, Elf_Internal_Note *); ++ } ++ grokers[] = ++ { ++ GROKER_ELEMENT ("", elfcore_grok_note), ++ GROKER_ELEMENT ("FreeBSD", elfcore_grok_freebsd_note), ++ GROKER_ELEMENT ("NetBSD-CORE", elfcore_grok_netbsd_note), ++ GROKER_ELEMENT ("OpenBSD", elfcore_grok_openbsd_note), ++ GROKER_ELEMENT ("QNX", elfcore_grok_nto_note), ++ GROKER_ELEMENT ("SPU/", elfcore_grok_spu_note), ++ GROKER_ELEMENT ("GNU", elfobj_grok_gnu_note), ++ GROKER_ELEMENT ("CORE", elfcore_grok_solaris_note) ++ }; ++#undef GROKER_ELEMENT ++ int i; ++ ++ for (i = ARRAY_SIZE (grokers); i--;) ++ { ++ if (in.namesz >= grokers[i].len ++ && strncmp (in.namedata, grokers[i].string, ++ grokers[i].len) == 0) ++ { ++ if (! grokers[i].func (abfd, & in)) ++ return false; ++ break; ++ } ++ } ++ break; ++ } ++ ++ case bfd_object: ++ if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0) ++ { ++ if (! elfobj_grok_gnu_note (abfd, &in)) ++ return false; ++ } ++ else if (in.namesz == sizeof "stapsdt" ++ && strcmp (in.namedata, "stapsdt") == 0) ++ { ++ if (! elfobj_grok_stapsdt_note (abfd, &in)) ++ return false; ++ } ++ break; ++ } ++ ++ p += ELF_NOTE_NEXT_OFFSET (in.namesz, in.descsz, align); ++ } ++ ++ return true; ++} ++ ++bool ++elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size, ++ size_t align) ++{ ++ char *buf; ++ ++ if (size == 0 || (size + 1) == 0) ++ return true; ++ ++ if (bfd_seek (abfd, offset, SEEK_SET) != 0) ++ return false; ++ ++ buf = (char *) _bfd_malloc_and_read (abfd, size + 1, size); ++ if (buf == NULL) ++ return false; ++ ++ /* PR 17512: file: ec08f814 ++ 0-termintate the buffer so that string searches will not overflow. */ ++ buf[size] = 0; ++ ++ if (!elf_parse_notes (abfd, buf, size, offset, align)) ++ { ++ free (buf); ++ return false; ++ } ++ ++ free (buf); ++ return true; ++} ++ ++/* Providing external access to the ELF program header table. */ ++ ++/* Return an upper bound on the number of bytes required to store a ++ copy of ABFD's program header table entries. Return -1 if an error ++ occurs; bfd_get_error will return an appropriate code. */ ++ ++long ++bfd_get_elf_phdr_upper_bound (bfd *abfd) ++{ ++ if (abfd->xvec->flavour != bfd_target_elf_flavour) ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ return -1; ++ } ++ ++ return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr); ++} ++ ++/* Copy ABFD's program header table entries to *PHDRS. The entries ++ will be stored as an array of Elf_Internal_Phdr structures, as ++ defined in include/elf/internal.h. To find out how large the ++ buffer needs to be, call bfd_get_elf_phdr_upper_bound. ++ ++ Return the number of program header table entries read, or -1 if an ++ error occurs; bfd_get_error will return an appropriate code. */ ++ ++int ++bfd_get_elf_phdrs (bfd *abfd, void *phdrs) ++{ ++ int num_phdrs; ++ ++ if (abfd->xvec->flavour != bfd_target_elf_flavour) ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ return -1; ++ } ++ ++ num_phdrs = elf_elfheader (abfd)->e_phnum; ++ if (num_phdrs != 0) ++ memcpy (phdrs, elf_tdata (abfd)->phdr, ++ num_phdrs * sizeof (Elf_Internal_Phdr)); ++ ++ return num_phdrs; ++} ++ ++enum elf_reloc_type_class ++_bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ const asection *rel_sec ATTRIBUTE_UNUSED, ++ const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED) ++{ ++ return reloc_class_normal; ++} ++ ++/* For RELA architectures, return the relocation value for a ++ relocation against a local symbol. */ ++ ++bfd_vma ++_bfd_elf_rela_local_sym (bfd *abfd, ++ Elf_Internal_Sym *sym, ++ asection **psec, ++ Elf_Internal_Rela *rel) ++{ ++ asection *sec = *psec; ++ bfd_vma relocation; ++ ++ relocation = (sec->output_section->vma ++ + sec->output_offset ++ + sym->st_value); ++ if ((sec->flags & SEC_MERGE) ++ && ELF_ST_TYPE (sym->st_info) == STT_SECTION ++ && sec->sec_info_type == SEC_INFO_TYPE_MERGE) ++ { ++ rel->r_addend = ++ _bfd_merged_section_offset (abfd, psec, ++ elf_section_data (sec)->sec_info, ++ sym->st_value + rel->r_addend); ++ if (sec != *psec) ++ { ++ /* If we have changed the section, and our original section is ++ marked with SEC_EXCLUDE, it means that the original ++ SEC_MERGE section has been completely subsumed in some ++ other SEC_MERGE section. In this case, we need to leave ++ some info around for --emit-relocs. */ ++ if ((sec->flags & SEC_EXCLUDE) != 0) ++ sec->kept_section = *psec; ++ sec = *psec; ++ } ++ rel->r_addend -= relocation; ++ rel->r_addend += sec->output_section->vma + sec->output_offset; ++ } ++ return relocation; ++} ++ ++bfd_vma ++_bfd_elf_rel_local_sym (bfd *abfd, ++ Elf_Internal_Sym *sym, ++ asection **psec, ++ bfd_vma addend) ++{ ++ asection *sec = *psec; ++ ++ if (sec->sec_info_type != SEC_INFO_TYPE_MERGE) ++ return sym->st_value + addend; ++ ++ return _bfd_merged_section_offset (abfd, psec, ++ elf_section_data (sec)->sec_info, ++ sym->st_value + addend); ++} ++ ++/* Adjust an address within a section. Given OFFSET within SEC, return ++ the new offset within the section, based upon changes made to the ++ section. Returns -1 if the offset is now invalid. ++ The offset (in abnd out) is in target sized bytes, however big a ++ byte may be. */ ++ ++bfd_vma ++_bfd_elf_section_offset (bfd *abfd, ++ struct bfd_link_info *info, ++ asection *sec, ++ bfd_vma offset) ++{ ++ switch (sec->sec_info_type) ++ { ++ case SEC_INFO_TYPE_STABS: ++ return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info, ++ offset); ++ case SEC_INFO_TYPE_EH_FRAME: ++ return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset); ++ ++ default: ++ if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0) ++ { ++ /* Reverse the offset. */ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ bfd_size_type address_size = bed->s->arch_size / 8; ++ ++ /* address_size and sec->size are in octets. Convert ++ to bytes before subtracting the original offset. */ ++ offset = ((sec->size - address_size) ++ / bfd_octets_per_byte (abfd, sec) - offset); ++ } ++ return offset; ++ } ++} ++ ++long ++_bfd_elf_get_synthetic_symtab (bfd *abfd, ++ long symcount ATTRIBUTE_UNUSED, ++ asymbol **syms ATTRIBUTE_UNUSED, ++ long dynsymcount, ++ asymbol **dynsyms, ++ asymbol **ret) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ asection *relplt; ++ asymbol *s; ++ const char *relplt_name; ++ bool (*slurp_relocs) (bfd *, asection *, asymbol **, bool); ++ arelent *p; ++ long count, i, n; ++ size_t size; ++ Elf_Internal_Shdr *hdr; ++ char *names; ++ asection *plt; ++ ++ *ret = NULL; ++ ++ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0) ++ return 0; ++ ++ if (dynsymcount <= 0) ++ return 0; ++ ++ if (!bed->plt_sym_val) ++ return 0; ++ ++ relplt_name = bed->relplt_name; ++ if (relplt_name == NULL) ++ relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt"; ++ relplt = bfd_get_section_by_name (abfd, relplt_name); ++ if (relplt == NULL) ++ return 0; ++ ++ hdr = &elf_section_data (relplt)->this_hdr; ++ if (hdr->sh_link != elf_dynsymtab (abfd) ++ || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA)) ++ return 0; ++ ++ plt = bfd_get_section_by_name (abfd, ".plt"); ++ if (plt == NULL) ++ return 0; ++ ++ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; ++ if (! (*slurp_relocs) (abfd, relplt, dynsyms, true)) ++ return -1; ++ ++ count = NUM_SHDR_ENTRIES (hdr); ++ size = count * sizeof (asymbol); ++ p = relplt->relocation; ++ for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel) ++ { ++ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt"); ++ if (p->addend != 0) ++ { ++#ifdef BFD64 ++ size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64); ++#else ++ size += sizeof ("+0x") - 1 + 8; ++#endif ++ } ++ } ++ ++ s = *ret = (asymbol *) bfd_malloc (size); ++ if (s == NULL) ++ return -1; ++ ++ names = (char *) (s + count); ++ p = relplt->relocation; ++ n = 0; ++ for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel) ++ { ++ size_t len; ++ bfd_vma addr; ++ ++ addr = bed->plt_sym_val (i, plt, p); ++ if (addr == (bfd_vma) -1) ++ continue; ++ ++ *s = **p->sym_ptr_ptr; ++ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since ++ we are defining a symbol, ensure one of them is set. */ ++ if ((s->flags & BSF_LOCAL) == 0) ++ s->flags |= BSF_GLOBAL; ++ s->flags |= BSF_SYNTHETIC; ++ s->section = plt; ++ s->value = addr - plt->vma; ++ s->name = names; ++ s->udata.p = NULL; ++ len = strlen ((*p->sym_ptr_ptr)->name); ++ memcpy (names, (*p->sym_ptr_ptr)->name, len); ++ names += len; ++ if (p->addend != 0) ++ { ++ char buf[30], *a; ++ ++ memcpy (names, "+0x", sizeof ("+0x") - 1); ++ names += sizeof ("+0x") - 1; ++ bfd_sprintf_vma (abfd, buf, p->addend); ++ for (a = buf; *a == '0'; ++a) ++ ; ++ len = strlen (a); ++ memcpy (names, a, len); ++ names += len; ++ } ++ memcpy (names, "@plt", sizeof ("@plt")); ++ names += sizeof ("@plt"); ++ ++s, ++n; ++ } ++ ++ return n; ++} ++ ++/* It is only used by x86-64 so far. ++ ??? This repeats *COM* id of zero. sec->id is supposed to be unique, ++ but current usage would allow all of _bfd_std_section to be zero. */ ++static const asymbol lcomm_sym ++ = GLOBAL_SYM_INIT ("LARGE_COMMON", &_bfd_elf_large_com_section); ++asection _bfd_elf_large_com_section ++ = BFD_FAKE_SECTION (_bfd_elf_large_com_section, &lcomm_sym, ++ "LARGE_COMMON", 0, SEC_IS_COMMON); ++ ++bool ++_bfd_elf_final_write_processing (bfd *abfd) ++{ ++ Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */ ++ ++ i_ehdrp = elf_elfheader (abfd); ++ ++ if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE) ++ i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi; ++ ++ /* Set the osabi field to ELFOSABI_GNU if the binary contains ++ SHF_GNU_MBIND or SHF_GNU_RETAIN sections or symbols of STT_GNU_IFUNC type ++ or STB_GNU_UNIQUE binding. */ ++ if (elf_tdata (abfd)->has_gnu_osabi != 0) ++ { ++ if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE) ++ i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU; ++ else if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU ++ && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_FREEBSD) ++ { ++ if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) ++ _bfd_error_handler (_("GNU_MBIND section is supported only by GNU " ++ "and FreeBSD targets")); ++ if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_ifunc) ++ _bfd_error_handler (_("symbol type STT_GNU_IFUNC is supported " ++ "only by GNU and FreeBSD targets")); ++ if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_unique) ++ _bfd_error_handler (_("symbol binding STB_GNU_UNIQUE is supported " ++ "only by GNU and FreeBSD targets")); ++ if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_retain) ++ _bfd_error_handler (_("GNU_RETAIN section is supported " ++ "only by GNU and FreeBSD targets")); ++ bfd_set_error (bfd_error_sorry); ++ return false; ++ } ++ } ++ return true; ++} ++ ++ ++/* Return TRUE for ELF symbol types that represent functions. ++ This is the default version of this function, which is sufficient for ++ most targets. It returns true if TYPE is STT_FUNC or STT_GNU_IFUNC. */ ++ ++bool ++_bfd_elf_is_function_type (unsigned int type) ++{ ++ return (type == STT_FUNC ++ || type == STT_GNU_IFUNC); ++} ++ ++/* If the ELF symbol SYM might be a function in SEC, return the ++ function size and set *CODE_OFF to the function's entry point, ++ otherwise return zero. */ ++ ++bfd_size_type ++_bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec, ++ bfd_vma *code_off) ++{ ++ bfd_size_type size; ++ elf_symbol_type * elf_sym = (elf_symbol_type *) sym; ++ ++ if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT ++ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0 ++ || sym->section != sec) ++ return 0; ++ ++ size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size; ++ ++ /* In theory we should check that the symbol's type satisfies ++ _bfd_elf_is_function_type(), but there are some function-like ++ symbols which would fail this test. (eg _start). Instead ++ we check for hidden, local, notype symbols with zero size. ++ This type of symbol is generated by the annobin plugin for gcc ++ and clang, and should not be considered to be a function symbol. */ ++ if (size == 0 ++ && ((sym->flags & (BSF_SYNTHETIC | BSF_LOCAL)) == BSF_LOCAL) ++ && ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info) == STT_NOTYPE ++ && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN) ++ return 0; ++ ++ *code_off = sym->value; ++ /* Do not return 0 for the function's size. */ ++ return size ? size : 1; ++} ++ ++/* Set to non-zero to enable some debug messages. */ ++#define DEBUG_SECONDARY_RELOCS 0 ++ ++/* An internal-to-the-bfd-library only section type ++ used to indicate a cached secondary reloc section. */ ++#define SHT_SECONDARY_RELOC (SHT_LOOS + SHT_RELA) ++ ++/* Create a BFD section to hold a secondary reloc section. */ ++ ++bool ++_bfd_elf_init_secondary_reloc_section (bfd * abfd, ++ Elf_Internal_Shdr *hdr, ++ const char * name, ++ unsigned int shindex) ++{ ++ /* We only support RELA secondary relocs. */ ++ if (hdr->sh_type != SHT_RELA) ++ return false; ++ ++#if DEBUG_SECONDARY_RELOCS ++ fprintf (stderr, "secondary reloc section %s encountered\n", name); ++#endif ++ hdr->sh_type = SHT_SECONDARY_RELOC; ++ return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); ++} ++ ++/* Read in any secondary relocs associated with SEC. */ ++ ++bool ++_bfd_elf_slurp_secondary_reloc_section (bfd * abfd, ++ asection * sec, ++ asymbol ** symbols, ++ bool dynamic) ++{ ++ const struct elf_backend_data * const ebd = get_elf_backend_data (abfd); ++ asection * relsec; ++ bool result = true; ++ bfd_vma (*r_sym) (bfd_vma); ++ ufile_ptr filesize; ++ ++#if BFD_DEFAULT_TARGET_SIZE > 32 ++ if (bfd_arch_bits_per_address (abfd) != 32) ++ r_sym = elf64_r_sym; ++ else ++#endif ++ r_sym = elf32_r_sym; ++ ++ if (!elf_section_data (sec)->has_secondary_relocs) ++ return true; ++ ++ /* Discover if there are any secondary reloc sections ++ associated with SEC. */ ++ filesize = bfd_get_file_size (abfd); ++ for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next) ++ { ++ Elf_Internal_Shdr * hdr = & elf_section_data (relsec)->this_hdr; ++ ++ if (hdr->sh_type == SHT_SECONDARY_RELOC ++ && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx ++ && (hdr->sh_entsize == ebd->s->sizeof_rel ++ || hdr->sh_entsize == ebd->s->sizeof_rela)) ++ { ++ bfd_byte * native_relocs; ++ bfd_byte * native_reloc; ++ arelent * internal_relocs; ++ arelent * internal_reloc; ++ size_t i; ++ unsigned int entsize; ++ unsigned int symcount; ++ bfd_size_type reloc_count; ++ size_t amt; ++ ++ if (ebd->elf_info_to_howto == NULL) ++ return false; ++ ++#if DEBUG_SECONDARY_RELOCS ++ fprintf (stderr, "read secondary relocs for %s from %s\n", ++ sec->name, relsec->name); ++#endif ++ entsize = hdr->sh_entsize; ++ ++ if (filesize != 0 ++ && ((ufile_ptr) hdr->sh_offset > filesize ++ || hdr->sh_size > filesize - hdr->sh_offset)) ++ { ++ bfd_set_error (bfd_error_file_truncated); ++ result = false; ++ continue; ++ } ++ ++ native_relocs = bfd_malloc (hdr->sh_size); ++ if (native_relocs == NULL) ++ { ++ result = false; ++ continue; ++ } ++ ++ reloc_count = NUM_SHDR_ENTRIES (hdr); ++ if (_bfd_mul_overflow (reloc_count, sizeof (arelent), & amt)) ++ { ++ free (native_relocs); ++ bfd_set_error (bfd_error_file_too_big); ++ result = false; ++ continue; ++ } ++ ++ internal_relocs = (arelent *) bfd_alloc (abfd, amt); ++ if (internal_relocs == NULL) ++ { ++ free (native_relocs); ++ result = false; ++ continue; ++ } ++ ++ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 ++ || (bfd_bread (native_relocs, hdr->sh_size, abfd) ++ != hdr->sh_size)) ++ { ++ free (native_relocs); ++ /* The internal_relocs will be freed when ++ the memory for the bfd is released. */ ++ result = false; ++ continue; ++ } ++ ++ if (dynamic) ++ symcount = bfd_get_dynamic_symcount (abfd); ++ else ++ symcount = bfd_get_symcount (abfd); ++ ++ for (i = 0, internal_reloc = internal_relocs, ++ native_reloc = native_relocs; ++ i < reloc_count; ++ i++, internal_reloc++, native_reloc += entsize) ++ { ++ bool res; ++ Elf_Internal_Rela rela; ++ ++ if (entsize == ebd->s->sizeof_rel) ++ ebd->s->swap_reloc_in (abfd, native_reloc, & rela); ++ else /* entsize == ebd->s->sizeof_rela */ ++ ebd->s->swap_reloca_in (abfd, native_reloc, & rela); ++ ++ /* The address of an ELF reloc is section relative for an object ++ file, and absolute for an executable file or shared library. ++ The address of a normal BFD reloc is always section relative, ++ and the address of a dynamic reloc is absolute.. */ ++ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) ++ internal_reloc->address = rela.r_offset; ++ else ++ internal_reloc->address = rela.r_offset - sec->vma; ++ ++ if (r_sym (rela.r_info) == STN_UNDEF) ++ { ++ /* FIXME: This and the error case below mean that we ++ have a symbol on relocs that is not elf_symbol_type. */ ++ internal_reloc->sym_ptr_ptr = ++ bfd_abs_section_ptr->symbol_ptr_ptr; ++ } ++ else if (r_sym (rela.r_info) > symcount) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): relocation %zu has invalid symbol index %lu"), ++ abfd, sec, i, (long) r_sym (rela.r_info)); ++ bfd_set_error (bfd_error_bad_value); ++ internal_reloc->sym_ptr_ptr = ++ bfd_abs_section_ptr->symbol_ptr_ptr; ++ result = false; ++ } ++ else ++ { ++ asymbol **ps; ++ ++ ps = symbols + r_sym (rela.r_info) - 1; ++ internal_reloc->sym_ptr_ptr = ps; ++ /* Make sure that this symbol is not removed by strip. */ ++ (*ps)->flags |= BSF_KEEP; ++ } ++ ++ internal_reloc->addend = rela.r_addend; ++ ++ res = ebd->elf_info_to_howto (abfd, internal_reloc, & rela); ++ if (! res || internal_reloc->howto == NULL) ++ { ++#if DEBUG_SECONDARY_RELOCS ++ fprintf (stderr, ++ "there is no howto associated with reloc %lx\n", ++ rela.r_info); ++#endif ++ result = false; ++ } ++ } ++ ++ free (native_relocs); ++ /* Store the internal relocs. */ ++ elf_section_data (relsec)->sec_info = internal_relocs; ++ } ++ } ++ ++ return result; ++} ++ ++/* Set the ELF section header fields of an output secondary reloc section. */ ++ ++bool ++_bfd_elf_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED, ++ bfd *obfd ATTRIBUTE_UNUSED, ++ const Elf_Internal_Shdr *isection, ++ Elf_Internal_Shdr *osection) ++{ ++ asection * isec; ++ asection * osec; ++ struct bfd_elf_section_data * esd; ++ ++ if (isection == NULL) ++ return false; ++ ++ if (isection->sh_type != SHT_SECONDARY_RELOC) ++ return true; ++ ++ isec = isection->bfd_section; ++ if (isec == NULL) ++ return false; ++ ++ osec = osection->bfd_section; ++ if (osec == NULL) ++ return false; ++ ++ esd = elf_section_data (osec); ++ BFD_ASSERT (esd->sec_info == NULL); ++ esd->sec_info = elf_section_data (isec)->sec_info; ++ osection->sh_type = SHT_RELA; ++ osection->sh_link = elf_onesymtab (obfd); ++ if (osection->sh_link == 0) ++ { ++ /* There is no symbol table - we are hosed... */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): link section cannot be set" ++ " because the output file does not have a symbol table"), ++ obfd, osec); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ ++ /* Find the output section that corresponds to the isection's ++ sh_info link. */ ++ if (isection->sh_info == 0 ++ || isection->sh_info >= elf_numsections (ibfd)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): info section index is invalid"), ++ obfd, osec); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ ++ isection = elf_elfsections (ibfd)[isection->sh_info]; ++ ++ if (isection == NULL ++ || isection->bfd_section == NULL ++ || isection->bfd_section->output_section == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): info section index cannot be set" ++ " because the section is not in the output"), ++ obfd, osec); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ ++ esd = elf_section_data (isection->bfd_section->output_section); ++ BFD_ASSERT (esd != NULL); ++ osection->sh_info = esd->this_idx; ++ esd->has_secondary_relocs = true; ++#if DEBUG_SECONDARY_RELOCS ++ fprintf (stderr, "update header of %s, sh_link = %u, sh_info = %u\n", ++ osec->name, osection->sh_link, osection->sh_info); ++ fprintf (stderr, "mark section %s as having secondary relocs\n", ++ bfd_section_name (isection->bfd_section->output_section)); ++#endif ++ ++ return true; ++} ++ ++/* Write out a secondary reloc section. ++ ++ FIXME: Currently this function can result in a serious performance penalty ++ for files with secondary relocs and lots of sections. The proper way to ++ fix this is for _bfd_elf_copy_special_section_fields() to chain secondary ++ relocs together and then to have this function just walk that chain. */ ++ ++bool ++_bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec) ++{ ++ const struct elf_backend_data * const ebd = get_elf_backend_data (abfd); ++ bfd_vma addr_offset; ++ asection * relsec; ++ bfd_vma (*r_info) (bfd_vma, bfd_vma); ++ bool result = true; ++ ++ if (sec == NULL) ++ return false; ++ ++#if BFD_DEFAULT_TARGET_SIZE > 32 ++ if (bfd_arch_bits_per_address (abfd) != 32) ++ r_info = elf64_r_info; ++ else ++#endif ++ r_info = elf32_r_info; ++ ++ /* The address of an ELF reloc is section relative for an object ++ file, and absolute for an executable file or shared library. ++ The address of a BFD reloc is always section relative. */ ++ addr_offset = 0; ++ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) ++ addr_offset = sec->vma; ++ ++ /* Discover if there are any secondary reloc sections ++ associated with SEC. */ ++ for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next) ++ { ++ const struct bfd_elf_section_data * const esd = elf_section_data (relsec); ++ Elf_Internal_Shdr * const hdr = (Elf_Internal_Shdr *) & esd->this_hdr; ++ ++ if (hdr->sh_type == SHT_RELA ++ && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx) ++ { ++ asymbol * last_sym; ++ int last_sym_idx; ++ size_t reloc_count; ++ size_t idx; ++ bfd_size_type entsize; ++ arelent * src_irel; ++ bfd_byte * dst_rela; ++ ++ if (hdr->contents != NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: secondary reloc section processed twice"), ++ abfd, relsec); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ continue; ++ } ++ ++ entsize = hdr->sh_entsize; ++ if (entsize == 0) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: secondary reloc section" ++ " has zero sized entries"), ++ abfd, relsec); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ continue; ++ } ++ else if (entsize != ebd->s->sizeof_rel ++ && entsize != ebd->s->sizeof_rela) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: secondary reloc section" ++ " has non-standard sized entries"), ++ abfd, relsec); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ continue; ++ } ++ ++ reloc_count = hdr->sh_size / entsize; ++ hdr->sh_size = entsize * reloc_count; ++ if (reloc_count == 0) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: secondary reloc section is empty!"), ++ abfd, relsec); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ continue; ++ } ++ ++ hdr->contents = bfd_alloc (abfd, hdr->sh_size); ++ if (hdr->contents == NULL) ++ continue; ++ ++#if DEBUG_SECONDARY_RELOCS ++ fprintf (stderr, "write %u secondary relocs for %s from %s\n", ++ reloc_count, sec->name, relsec->name); ++#endif ++ last_sym = NULL; ++ last_sym_idx = 0; ++ dst_rela = hdr->contents; ++ src_irel = (arelent *) esd->sec_info; ++ if (src_irel == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: internal relocs missing" ++ " for secondary reloc section"), ++ abfd, relsec); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ continue; ++ } ++ ++ for (idx = 0; idx < reloc_count; idx++, dst_rela += entsize) ++ { ++ Elf_Internal_Rela src_rela; ++ arelent *ptr; ++ asymbol *sym; ++ int n; ++ ++ ptr = src_irel + idx; ++ if (ptr == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: reloc table entry %zu is empty"), ++ abfd, relsec, idx); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ break; ++ } ++ ++ if (ptr->sym_ptr_ptr == NULL) ++ { ++ /* FIXME: Is this an error ? */ ++ n = 0; ++ } ++ else ++ { ++ sym = *ptr->sym_ptr_ptr; ++ ++ if (sym == last_sym) ++ n = last_sym_idx; ++ else ++ { ++ n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym); ++ if (n < 0) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: secondary reloc %zu" ++ " references a missing symbol"), ++ abfd, relsec, idx); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ n = 0; ++ } ++ ++ last_sym = sym; ++ last_sym_idx = n; ++ } ++ ++ if (sym->the_bfd != NULL ++ && sym->the_bfd->xvec != abfd->xvec ++ && ! _bfd_elf_validate_reloc (abfd, ptr)) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: secondary reloc %zu" ++ " references a deleted symbol"), ++ abfd, relsec, idx); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ n = 0; ++ } ++ } ++ ++ src_rela.r_offset = ptr->address + addr_offset; ++ if (ptr->howto == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB(%pA): error: secondary reloc %zu" ++ " is of an unknown type"), ++ abfd, relsec, idx); ++ bfd_set_error (bfd_error_bad_value); ++ result = false; ++ src_rela.r_info = r_info (0, 0); ++ } ++ else ++ src_rela.r_info = r_info (n, ptr->howto->type); ++ src_rela.r_addend = ptr->addend; ++ ++ if (entsize == ebd->s->sizeof_rel) ++ ebd->s->swap_reloc_out (abfd, &src_rela, dst_rela); ++ else /* entsize == ebd->s->sizeof_rela */ ++ ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela); ++ } ++ } ++ } ++ ++ return result; ++} +diff -rupN binutils.orig/bfd/elflink.c binutils-2.41/bfd/elflink.c +--- binutils.orig/bfd/elflink.c 2023-10-19 12:11:46.523939791 +0100 ++++ binutils-2.41/bfd/elflink.c 2023-10-19 12:11:56.515949625 +0100 +@@ -7149,9 +7149,20 @@ bfd_elf_size_dynamic_sections (bfd *outp + /* If the user has explicitly requested warnings, then generate one even + though the choice is the result of another command line option. */ + if (info->warn_execstack == 1) +- _bfd_error_handler +- (_("\ ++ { ++ if (info->error_execstack) ++ { ++ _bfd_error_handler ++ (_("\ ++error: creating an executable stack because of -z execstack command line option")); ++ return false; ++ } ++ ++ _bfd_error_handler ++ (_("\ + warning: enabling an executable stack because of -z execstack command line option")); ++ } ++ + elf_stack_flags (output_bfd) = PF_R | PF_W | PF_X; + } + else if (info->noexecstack) +@@ -7207,11 +7218,29 @@ warning: enabling an executable stack be + being enabled despite the fact that it was not requested + on the command line. */ + if (noteobj) +- _bfd_error_handler (_("\ ++ { ++ if (info->error_execstack) ++ { ++ _bfd_error_handler (_("\ ++error: %s: is triggering the generation of an executable stack (because it has an executable .note.GNU-stack section)"), ++ bfd_get_filename (noteobj)); ++ return false; ++ } ++ ++ _bfd_error_handler (_("\ + warning: %s: requires executable stack (because the .note.GNU-stack section is executable)"), + bfd_get_filename (noteobj)); ++ } + else if (emptyobj) + { ++ if (info->error_execstack) ++ { ++ _bfd_error_handler (_("\ ++error: %s: is triggering the generation of an executable stack because it does not have a .note.GNU-stack section"), ++ bfd_get_filename (emptyobj)); ++ return false; ++ } ++ + _bfd_error_handler (_("\ + warning: %s: missing .note.GNU-stack section implies executable stack"), + bfd_get_filename (emptyobj)); +diff -rupN binutils.orig/bfd/elflink.c.orig binutils-2.41/bfd/elflink.c.orig +--- binutils.orig/bfd/elflink.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/bfd/elflink.c.orig 2023-07-03 00:00:00.000000000 +0100 +@@ -0,0 +1,15534 @@ ++/* ELF linking support for BFD. ++ Copyright (C) 1995-2023 Free Software Foundation, Inc. ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "bfdlink.h" ++#include "libbfd.h" ++#define ARCH_SIZE 0 ++#include "elf-bfd.h" ++#include "safe-ctype.h" ++#include "libiberty.h" ++#include "objalloc.h" ++#if BFD_SUPPORTS_PLUGINS ++#include "plugin-api.h" ++#include "plugin.h" ++#endif ++ ++#include ++#ifndef CHAR_BIT ++#define CHAR_BIT 8 ++#endif ++ ++/* This struct is used to pass information to routines called via ++ elf_link_hash_traverse which must return failure. */ ++ ++struct elf_info_failed ++{ ++ struct bfd_link_info *info; ++ bool failed; ++}; ++ ++/* This structure is used to pass information to ++ _bfd_elf_link_find_version_dependencies. */ ++ ++struct elf_find_verdep_info ++{ ++ /* General link information. */ ++ struct bfd_link_info *info; ++ /* The number of dependencies. */ ++ unsigned int vers; ++ /* Whether we had a failure. */ ++ bool failed; ++}; ++ ++static bool _bfd_elf_fix_symbol_flags ++ (struct elf_link_hash_entry *, struct elf_info_failed *); ++ ++asection * ++_bfd_elf_section_for_symbol (struct elf_reloc_cookie *cookie, ++ unsigned long r_symndx, ++ bool discard) ++{ ++ if (r_symndx >= cookie->locsymcount ++ || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL) ++ { ++ struct elf_link_hash_entry *h; ++ ++ h = cookie->sym_hashes[r_symndx - cookie->extsymoff]; ++ ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && discarded_section (h->root.u.def.section)) ++ return h->root.u.def.section; ++ else ++ return NULL; ++ } ++ else ++ { ++ /* It's not a relocation against a global symbol, ++ but it could be a relocation against a local ++ symbol for a discarded section. */ ++ asection *isec; ++ Elf_Internal_Sym *isym; ++ ++ /* Need to: get the symbol; get the section. */ ++ isym = &cookie->locsyms[r_symndx]; ++ isec = bfd_section_from_elf_index (cookie->abfd, isym->st_shndx); ++ if (isec != NULL ++ && discard ? discarded_section (isec) : 1) ++ return isec; ++ } ++ return NULL; ++} ++ ++/* Define a symbol in a dynamic linkage section. */ ++ ++struct elf_link_hash_entry * ++_bfd_elf_define_linkage_sym (bfd *abfd, ++ struct bfd_link_info *info, ++ asection *sec, ++ const char *name) ++{ ++ struct elf_link_hash_entry *h; ++ struct bfd_link_hash_entry *bh; ++ const struct elf_backend_data *bed; ++ ++ h = elf_link_hash_lookup (elf_hash_table (info), name, false, false, false); ++ if (h != NULL) ++ { ++ /* Zap symbol defined in an as-needed lib that wasn't linked. ++ This is a symptom of a larger problem: Absolute symbols ++ defined in shared libraries can't be overridden, because we ++ lose the link to the bfd which is via the symbol section. */ ++ h->root.type = bfd_link_hash_new; ++ bh = &h->root; ++ } ++ else ++ bh = NULL; ++ ++ bed = get_elf_backend_data (abfd); ++ if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL, ++ sec, 0, NULL, false, bed->collect, ++ &bh)) ++ return NULL; ++ h = (struct elf_link_hash_entry *) bh; ++ BFD_ASSERT (h != NULL); ++ h->def_regular = 1; ++ h->non_elf = 0; ++ h->root.linker_def = 1; ++ h->type = STT_OBJECT; ++ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL) ++ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; ++ ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ return h; ++} ++ ++bool ++_bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) ++{ ++ flagword flags; ++ asection *s; ++ struct elf_link_hash_entry *h; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct elf_link_hash_table *htab = elf_hash_table (info); ++ ++ /* This function may be called more than once. */ ++ if (htab->sgot != NULL) ++ return true; ++ ++ flags = bed->dynamic_sec_flags; ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ++ (bed->rela_plts_and_copies_p ++ ? ".rela.got" : ".rel.got"), ++ (bed->dynamic_sec_flags ++ | SEC_READONLY)); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ htab->srelgot = s; ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ htab->sgot = s; ++ ++ if (bed->want_got_plt) ++ { ++ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ htab->sgotplt = s; ++ } ++ ++ /* The first bit of the global offset table is the header. */ ++ s->size += bed->got_header_size; ++ ++ if (bed->want_got_sym) ++ { ++ /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got ++ (or .got.plt) section. We don't do this in the linker script ++ because we don't want to define the symbol if we are not creating ++ a global offset table. */ ++ h = _bfd_elf_define_linkage_sym (abfd, info, s, ++ "_GLOBAL_OFFSET_TABLE_"); ++ elf_hash_table (info)->hgot = h; ++ if (h == NULL) ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Create a strtab to hold the dynamic symbol names. */ ++static bool ++_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info) ++{ ++ struct elf_link_hash_table *hash_table; ++ ++ hash_table = elf_hash_table (info); ++ if (hash_table->dynobj == NULL) ++ { ++ /* We may not set dynobj, an input file holding linker created ++ dynamic sections to abfd, which may be a dynamic object with ++ its own dynamic sections. We need to find a normal input file ++ to hold linker created sections if possible. */ ++ if ((abfd->flags & (DYNAMIC | BFD_PLUGIN)) != 0) ++ { ++ bfd *ibfd; ++ asection *s; ++ for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next) ++ if ((ibfd->flags ++ & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0 ++ && bfd_get_flavour (ibfd) == bfd_target_elf_flavour ++ && elf_object_id (ibfd) == elf_hash_table_id (hash_table) ++ && !((s = ibfd->sections) != NULL ++ && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)) ++ { ++ abfd = ibfd; ++ break; ++ } ++ } ++ hash_table->dynobj = abfd; ++ } ++ ++ if (hash_table->dynstr == NULL) ++ { ++ hash_table->dynstr = _bfd_elf_strtab_init (); ++ if (hash_table->dynstr == NULL) ++ return false; ++ } ++ return true; ++} ++ ++/* Create some sections which will be filled in with dynamic linking ++ information. ABFD is an input file which requires dynamic sections ++ to be created. The dynamic sections take up virtual memory space ++ when the final executable is run, so we need to create them before ++ addresses are assigned to the output sections. We work out the ++ actual contents and size of these sections later. */ ++ ++bool ++_bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) ++{ ++ flagword flags; ++ asection *s; ++ const struct elf_backend_data *bed; ++ struct elf_link_hash_entry *h; ++ ++ if (! is_elf_hash_table (info->hash)) ++ return false; ++ ++ if (elf_hash_table (info)->dynamic_sections_created) ++ return true; ++ ++ if (!_bfd_elf_link_create_dynstrtab (abfd, info)) ++ return false; ++ ++ abfd = elf_hash_table (info)->dynobj; ++ bed = get_elf_backend_data (abfd); ++ ++ flags = bed->dynamic_sec_flags; ++ ++ /* A dynamically linked executable has a .interp section, but a ++ shared library does not. */ ++ if (bfd_link_executable (info) && !info->nointerp) ++ { ++ s = bfd_make_section_anyway_with_flags (abfd, ".interp", ++ flags | SEC_READONLY); ++ if (s == NULL) ++ return false; ++ } ++ ++ /* Create sections to hold version informations. These are removed ++ if they are not needed. */ ++ s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_d", ++ flags | SEC_READONLY); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version", ++ flags | SEC_READONLY); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, 1)) ++ return false; ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_r", ++ flags | SEC_READONLY); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ".dynsym", ++ flags | SEC_READONLY); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ elf_hash_table (info)->dynsym = s; ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ".dynstr", ++ flags | SEC_READONLY); ++ if (s == NULL) ++ return false; ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ".dynamic", flags); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ ++ /* The special symbol _DYNAMIC is always set to the start of the ++ .dynamic section. We could set _DYNAMIC in a linker script, but we ++ only want to define it if we are, in fact, creating a .dynamic ++ section. We don't want to define it if there is no .dynamic ++ section, since on some ELF platforms the start up code examines it ++ to decide how to initialize the process. */ ++ h = _bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC"); ++ elf_hash_table (info)->hdynamic = h; ++ if (h == NULL) ++ return false; ++ ++ if (info->emit_hash) ++ { ++ s = bfd_make_section_anyway_with_flags (abfd, ".hash", ++ flags | SEC_READONLY); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry; ++ } ++ ++ if (info->emit_gnu_hash && bed->record_xhash_symbol == NULL) ++ { ++ s = bfd_make_section_anyway_with_flags (abfd, ".gnu.hash", ++ flags | SEC_READONLY); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ /* For 64-bit ELF, .gnu.hash is a non-uniform entity size section: ++ 4 32-bit words followed by variable count of 64-bit words, then ++ variable count of 32-bit words. */ ++ if (bed->s->arch_size == 64) ++ elf_section_data (s)->this_hdr.sh_entsize = 0; ++ else ++ elf_section_data (s)->this_hdr.sh_entsize = 4; ++ } ++ ++ if (info->enable_dt_relr) ++ { ++ s = bfd_make_section_anyway_with_flags (abfd, ".relr.dyn", ++ (bed->dynamic_sec_flags ++ | SEC_READONLY)); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ elf_hash_table (info)->srelrdyn = s; ++ } ++ ++ /* Let the backend create the rest of the sections. This lets the ++ backend set the right flags. The backend will normally create ++ the .got and .plt sections. */ ++ if (bed->elf_backend_create_dynamic_sections == NULL ++ || ! (*bed->elf_backend_create_dynamic_sections) (abfd, info)) ++ return false; ++ ++ elf_hash_table (info)->dynamic_sections_created = true; ++ ++ return true; ++} ++ ++/* Create dynamic sections when linking against a dynamic object. */ ++ ++bool ++_bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) ++{ ++ flagword flags, pltflags; ++ struct elf_link_hash_entry *h; ++ asection *s; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct elf_link_hash_table *htab = elf_hash_table (info); ++ ++ /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and ++ .rel[a].bss sections. */ ++ flags = bed->dynamic_sec_flags; ++ ++ pltflags = flags; ++ if (bed->plt_not_loaded) ++ /* We do not clear SEC_ALLOC here because we still want the OS to ++ allocate space for the section; it's just that there's nothing ++ to read in from the object file. */ ++ pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS); ++ else ++ pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD; ++ if (bed->plt_readonly) ++ pltflags |= SEC_READONLY; ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->plt_alignment)) ++ return false; ++ htab->splt = s; ++ ++ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the ++ .plt section. */ ++ if (bed->want_plt_sym) ++ { ++ h = _bfd_elf_define_linkage_sym (abfd, info, s, ++ "_PROCEDURE_LINKAGE_TABLE_"); ++ elf_hash_table (info)->hplt = h; ++ if (h == NULL) ++ return false; ++ } ++ ++ s = bfd_make_section_anyway_with_flags (abfd, ++ (bed->rela_plts_and_copies_p ++ ? ".rela.plt" : ".rel.plt"), ++ flags | SEC_READONLY); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ htab->srelplt = s; ++ ++ if (! _bfd_elf_create_got_section (abfd, info)) ++ return false; ++ ++ if (bed->want_dynbss) ++ { ++ /* The .dynbss section is a place to put symbols which are defined ++ by dynamic objects, are referenced by regular objects, and are ++ not functions. We must allocate space for them in the process ++ image and use a R_*_COPY reloc to tell the dynamic linker to ++ initialize them at run time. The linker script puts the .dynbss ++ section into the .bss section of the final image. */ ++ s = bfd_make_section_anyway_with_flags (abfd, ".dynbss", ++ SEC_ALLOC | SEC_LINKER_CREATED); ++ if (s == NULL) ++ return false; ++ htab->sdynbss = s; ++ ++ if (bed->want_dynrelro) ++ { ++ /* Similarly, but for symbols that were originally in read-only ++ sections. This section doesn't really need to have contents, ++ but make it like other .data.rel.ro sections. */ ++ s = bfd_make_section_anyway_with_flags (abfd, ".data.rel.ro", ++ flags); ++ if (s == NULL) ++ return false; ++ htab->sdynrelro = s; ++ } ++ ++ /* The .rel[a].bss section holds copy relocs. This section is not ++ normally needed. We need to create it here, though, so that the ++ linker will map it to an output section. We can't just create it ++ only if we need it, because we will not know whether we need it ++ until we have seen all the input files, and the first time the ++ main linker code calls BFD after examining all the input files ++ (size_dynamic_sections) the input sections have already been ++ mapped to the output sections. If the section turns out not to ++ be needed, we can discard it later. We will never need this ++ section when generating a shared object, since they do not use ++ copy relocs. */ ++ if (bfd_link_executable (info)) ++ { ++ s = bfd_make_section_anyway_with_flags (abfd, ++ (bed->rela_plts_and_copies_p ++ ? ".rela.bss" : ".rel.bss"), ++ flags | SEC_READONLY); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ htab->srelbss = s; ++ ++ if (bed->want_dynrelro) ++ { ++ s = (bfd_make_section_anyway_with_flags ++ (abfd, (bed->rela_plts_and_copies_p ++ ? ".rela.data.rel.ro" : ".rel.data.rel.ro"), ++ flags | SEC_READONLY)); ++ if (s == NULL ++ || !bfd_set_section_alignment (s, bed->s->log_file_align)) ++ return false; ++ htab->sreldynrelro = s; ++ } ++ } ++ } ++ ++ return true; ++} ++ ++/* Record a new dynamic symbol. We record the dynamic symbols as we ++ read the input files, since we need to have a list of all of them ++ before we can determine the final sizes of the output sections. ++ Note that we may actually call this function even though we are not ++ going to output any dynamic symbols; in some cases we know that a ++ symbol should be in the dynamic symbol table, but only if there is ++ one. */ ++ ++bool ++bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h) ++{ ++ if (h->dynindx == -1) ++ { ++ struct elf_strtab_hash *dynstr; ++ char *p; ++ const char *name; ++ size_t indx; ++ ++ if (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ { ++ /* An IR symbol should not be made dynamic. */ ++ if (h->root.u.def.section != NULL ++ && h->root.u.def.section->owner != NULL ++ && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0) ++ return true; ++ } ++ ++ /* XXX: The ABI draft says the linker must turn hidden and ++ internal symbols into STB_LOCAL symbols when producing the ++ DSO. However, if ld.so honors st_other in the dynamic table, ++ this would not be necessary. */ ++ switch (ELF_ST_VISIBILITY (h->other)) ++ { ++ case STV_INTERNAL: ++ case STV_HIDDEN: ++ if (h->root.type != bfd_link_hash_undefined ++ && h->root.type != bfd_link_hash_undefweak) ++ { ++ h->forced_local = 1; ++ if (!elf_hash_table (info)->is_relocatable_executable ++ || ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && h->root.u.def.section->owner != NULL ++ && h->root.u.def.section->owner->no_export) ++ || (h->root.type == bfd_link_hash_common ++ && h->root.u.c.p->section->owner != NULL ++ && h->root.u.c.p->section->owner->no_export)) ++ return true; ++ } ++ ++ default: ++ break; ++ } ++ ++ h->dynindx = elf_hash_table (info)->dynsymcount; ++ ++elf_hash_table (info)->dynsymcount; ++ ++ dynstr = elf_hash_table (info)->dynstr; ++ if (dynstr == NULL) ++ { ++ /* Create a strtab to hold the dynamic symbol names. */ ++ elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init (); ++ if (dynstr == NULL) ++ return false; ++ } ++ ++ /* We don't put any version information in the dynamic string ++ table. */ ++ name = h->root.root.string; ++ p = strchr (name, ELF_VER_CHR); ++ if (p != NULL) ++ /* We know that the p points into writable memory. In fact, ++ there are only a few symbols that have read-only names, being ++ those like _GLOBAL_OFFSET_TABLE_ that are created specially ++ by the backends. Most symbols will have names pointing into ++ an ELF string table read from a file, or to objalloc memory. */ ++ *p = 0; ++ ++ indx = _bfd_elf_strtab_add (dynstr, name, p != NULL); ++ ++ if (p != NULL) ++ *p = ELF_VER_CHR; ++ ++ if (indx == (size_t) -1) ++ return false; ++ h->dynstr_index = indx; ++ } ++ ++ return true; ++} ++ ++/* Mark a symbol dynamic. */ ++ ++static void ++bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, ++ Elf_Internal_Sym *sym) ++{ ++ struct bfd_elf_dynamic_list *d = info->dynamic_list; ++ ++ /* It may be called more than once on the same H. */ ++ if(h->dynamic || bfd_link_relocatable (info)) ++ return; ++ ++ if ((info->dynamic_data ++ && (h->type == STT_OBJECT ++ || h->type == STT_COMMON ++ || (sym != NULL ++ && (ELF_ST_TYPE (sym->st_info) == STT_OBJECT ++ || ELF_ST_TYPE (sym->st_info) == STT_COMMON)))) ++ || (d != NULL ++ && h->non_elf ++ && (*d->match) (&d->head, NULL, h->root.root.string))) ++ { ++ h->dynamic = 1; ++ /* NB: If a symbol is made dynamic by --dynamic-list, it has ++ non-IR reference. */ ++ h->root.non_ir_ref_dynamic = 1; ++ } ++} ++ ++/* Record an assignment to a symbol made by a linker script. We need ++ this in case some dynamic object refers to this symbol. */ ++ ++bool ++bfd_elf_record_link_assignment (bfd *output_bfd, ++ struct bfd_link_info *info, ++ const char *name, ++ bool provide, ++ bool hidden) ++{ ++ struct elf_link_hash_entry *h, *hv; ++ struct elf_link_hash_table *htab; ++ const struct elf_backend_data *bed; ++ ++ if (!is_elf_hash_table (info->hash)) ++ return true; ++ ++ htab = elf_hash_table (info); ++ h = elf_link_hash_lookup (htab, name, !provide, true, false); ++ if (h == NULL) ++ return provide; ++ ++ if (h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if (h->versioned == unknown) ++ { ++ /* Set versioned if symbol version is unknown. */ ++ char *version = strrchr (name, ELF_VER_CHR); ++ if (version) ++ { ++ if (version > name && version[-1] != ELF_VER_CHR) ++ h->versioned = versioned_hidden; ++ else ++ h->versioned = versioned; ++ } ++ } ++ ++ /* Symbols defined in a linker script but not referenced anywhere ++ else will have non_elf set. */ ++ if (h->non_elf) ++ { ++ bfd_elf_link_mark_dynamic_symbol (info, h, NULL); ++ h->non_elf = 0; ++ } ++ ++ switch (h->root.type) ++ { ++ case bfd_link_hash_defined: ++ case bfd_link_hash_defweak: ++ case bfd_link_hash_common: ++ break; ++ case bfd_link_hash_undefweak: ++ case bfd_link_hash_undefined: ++ /* Since we're defining the symbol, don't let it seem to have not ++ been defined. record_dynamic_symbol and size_dynamic_sections ++ may depend on this. */ ++ h->root.type = bfd_link_hash_new; ++ if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root) ++ bfd_link_repair_undef_list (&htab->root); ++ break; ++ case bfd_link_hash_new: ++ break; ++ case bfd_link_hash_indirect: ++ /* We had a versioned symbol in a dynamic library. We make the ++ the versioned symbol point to this one. */ ++ bed = get_elf_backend_data (output_bfd); ++ hv = h; ++ while (hv->root.type == bfd_link_hash_indirect ++ || hv->root.type == bfd_link_hash_warning) ++ hv = (struct elf_link_hash_entry *) hv->root.u.i.link; ++ /* We don't need to update h->root.u since linker will set them ++ later. */ ++ h->root.type = bfd_link_hash_undefined; ++ hv->root.type = bfd_link_hash_indirect; ++ hv->root.u.i.link = (struct bfd_link_hash_entry *) h; ++ (*bed->elf_backend_copy_indirect_symbol) (info, h, hv); ++ break; ++ default: ++ BFD_FAIL (); ++ return false; ++ } ++ ++ /* If this symbol is being provided by the linker script, and it is ++ currently defined by a dynamic object, but not by a regular ++ object, then mark it as undefined so that the generic linker will ++ force the correct value. */ ++ if (provide ++ && h->def_dynamic ++ && !h->def_regular) ++ h->root.type = bfd_link_hash_undefined; ++ ++ /* If this symbol is currently defined by a dynamic object, but not ++ by a regular object, then clear out any version information because ++ the symbol will not be associated with the dynamic object any ++ more. */ ++ if (h->def_dynamic && !h->def_regular) ++ h->verinfo.verdef = NULL; ++ ++ /* Make sure this symbol is not garbage collected. */ ++ h->mark = 1; ++ ++ h->def_regular = 1; ++ ++ if (hidden) ++ { ++ bed = get_elf_backend_data (output_bfd); ++ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL) ++ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ } ++ ++ /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects ++ and executables. */ ++ if (!bfd_link_relocatable (info) ++ && h->dynindx != -1 ++ && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN ++ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)) ++ h->forced_local = 1; ++ ++ if ((h->def_dynamic ++ || h->ref_dynamic ++ || bfd_link_dll (info) ++ || elf_hash_table (info)->is_relocatable_executable) ++ && !h->forced_local ++ && h->dynindx == -1) ++ { ++ if (! bfd_elf_link_record_dynamic_symbol (info, h)) ++ return false; ++ ++ /* If this is a weak defined symbol, and we know a corresponding ++ real symbol from the same dynamic object, make sure the real ++ symbol is also made into a dynamic symbol. */ ++ if (h->is_weakalias) ++ { ++ struct elf_link_hash_entry *def = weakdef (h); ++ ++ if (def->dynindx == -1 ++ && !bfd_elf_link_record_dynamic_symbol (info, def)) ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++/* Record a new local dynamic symbol. Returns 0 on failure, 1 on ++ success, and 2 on a failure caused by attempting to record a symbol ++ in a discarded section, eg. a discarded link-once section symbol. */ ++ ++int ++bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, ++ bfd *input_bfd, ++ long input_indx) ++{ ++ size_t amt; ++ struct elf_link_local_dynamic_entry *entry; ++ struct elf_link_hash_table *eht; ++ struct elf_strtab_hash *dynstr; ++ size_t dynstr_index; ++ char *name; ++ Elf_External_Sym_Shndx eshndx; ++ char esym[sizeof (Elf64_External_Sym)]; ++ ++ if (! is_elf_hash_table (info->hash)) ++ return 0; ++ ++ /* See if the entry exists already. */ ++ for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next) ++ if (entry->input_bfd == input_bfd && entry->input_indx == input_indx) ++ return 1; ++ ++ amt = sizeof (*entry); ++ entry = (struct elf_link_local_dynamic_entry *) bfd_alloc (input_bfd, amt); ++ if (entry == NULL) ++ return 0; ++ ++ /* Go find the symbol, so that we can find it's name. */ ++ if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr, ++ 1, input_indx, &entry->isym, esym, &eshndx)) ++ { ++ bfd_release (input_bfd, entry); ++ return 0; ++ } ++ ++ if (entry->isym.st_shndx != SHN_UNDEF ++ && entry->isym.st_shndx < SHN_LORESERVE) ++ { ++ asection *s; ++ ++ s = bfd_section_from_elf_index (input_bfd, entry->isym.st_shndx); ++ if (s == NULL || bfd_is_abs_section (s->output_section)) ++ { ++ /* We can still bfd_release here as nothing has done another ++ bfd_alloc. We can't do this later in this function. */ ++ bfd_release (input_bfd, entry); ++ return 2; ++ } ++ } ++ ++ name = (bfd_elf_string_from_elf_section ++ (input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link, ++ entry->isym.st_name)); ++ ++ dynstr = elf_hash_table (info)->dynstr; ++ if (dynstr == NULL) ++ { ++ /* Create a strtab to hold the dynamic symbol names. */ ++ elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init (); ++ if (dynstr == NULL) ++ return 0; ++ } ++ ++ dynstr_index = _bfd_elf_strtab_add (dynstr, name, false); ++ if (dynstr_index == (size_t) -1) ++ return 0; ++ entry->isym.st_name = dynstr_index; ++ ++ eht = elf_hash_table (info); ++ ++ entry->next = eht->dynlocal; ++ eht->dynlocal = entry; ++ entry->input_bfd = input_bfd; ++ entry->input_indx = input_indx; ++ eht->dynsymcount++; ++ ++ /* Whatever binding the symbol had before, it's now local. */ ++ entry->isym.st_info ++ = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info)); ++ ++ /* The dynindx will be set at the end of size_dynamic_sections. */ ++ ++ return 1; ++} ++ ++/* Return the dynindex of a local dynamic symbol. */ ++ ++long ++_bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *info, ++ bfd *input_bfd, ++ long input_indx) ++{ ++ struct elf_link_local_dynamic_entry *e; ++ ++ for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) ++ if (e->input_bfd == input_bfd && e->input_indx == input_indx) ++ return e->dynindx; ++ return -1; ++} ++ ++/* This function is used to renumber the dynamic symbols, if some of ++ them are removed because they are marked as local. This is called ++ via elf_link_hash_traverse. */ ++ ++static bool ++elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h, ++ void *data) ++{ ++ size_t *count = (size_t *) data; ++ ++ if (h->forced_local) ++ return true; ++ ++ if (h->dynindx != -1) ++ h->dynindx = ++(*count); ++ ++ return true; ++} ++ ++ ++/* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with ++ STB_LOCAL binding. */ ++ ++static bool ++elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h, ++ void *data) ++{ ++ size_t *count = (size_t *) data; ++ ++ if (!h->forced_local) ++ return true; ++ ++ if (h->dynindx != -1) ++ h->dynindx = ++(*count); ++ ++ return true; ++} ++ ++/* Return true if the dynamic symbol for a given section should be ++ omitted when creating a shared library. */ ++bool ++_bfd_elf_omit_section_dynsym_default (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info, ++ asection *p) ++{ ++ struct elf_link_hash_table *htab; ++ asection *ip; ++ ++ switch (elf_section_data (p)->this_hdr.sh_type) ++ { ++ case SHT_PROGBITS: ++ case SHT_NOBITS: ++ /* If sh_type is yet undecided, assume it could be ++ SHT_PROGBITS/SHT_NOBITS. */ ++ case SHT_NULL: ++ htab = elf_hash_table (info); ++ if (htab->text_index_section != NULL) ++ return p != htab->text_index_section && p != htab->data_index_section; ++ ++ return (htab->dynobj != NULL ++ && (ip = bfd_get_linker_section (htab->dynobj, p->name)) != NULL ++ && ip->output_section == p); ++ ++ /* There shouldn't be section relative relocations ++ against any other section. */ ++ default: ++ return true; ++ } ++} ++ ++bool ++_bfd_elf_omit_section_dynsym_all ++ (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ asection *p ATTRIBUTE_UNUSED) ++{ ++ return true; ++} ++ ++/* Assign dynsym indices. In a shared library we generate a section ++ symbol for each output section, which come first. Next come symbols ++ which have been forced to local binding. Then all of the back-end ++ allocated local dynamic syms, followed by the rest of the global ++ symbols. If SECTION_SYM_COUNT is NULL, section dynindx is not set. ++ (This prevents the early call before elf_backend_init_index_section ++ and strip_excluded_output_sections setting dynindx for sections ++ that are stripped.) */ ++ ++static unsigned long ++_bfd_elf_link_renumber_dynsyms (bfd *output_bfd, ++ struct bfd_link_info *info, ++ unsigned long *section_sym_count) ++{ ++ unsigned long dynsymcount = 0; ++ bool do_sec = section_sym_count != NULL; ++ ++ if (bfd_link_pic (info) ++ || elf_hash_table (info)->is_relocatable_executable) ++ { ++ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); ++ asection *p; ++ for (p = output_bfd->sections; p ; p = p->next) ++ if ((p->flags & SEC_EXCLUDE) == 0 ++ && (p->flags & SEC_ALLOC) != 0 ++ && elf_hash_table (info)->dynamic_relocs ++ && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p)) ++ { ++ ++dynsymcount; ++ if (do_sec) ++ elf_section_data (p)->dynindx = dynsymcount; ++ } ++ else if (do_sec) ++ elf_section_data (p)->dynindx = 0; ++ } ++ if (do_sec) ++ *section_sym_count = dynsymcount; ++ ++ elf_link_hash_traverse (elf_hash_table (info), ++ elf_link_renumber_local_hash_table_dynsyms, ++ &dynsymcount); ++ ++ if (elf_hash_table (info)->dynlocal) ++ { ++ struct elf_link_local_dynamic_entry *p; ++ for (p = elf_hash_table (info)->dynlocal; p ; p = p->next) ++ p->dynindx = ++dynsymcount; ++ } ++ elf_hash_table (info)->local_dynsymcount = dynsymcount; ++ ++ elf_link_hash_traverse (elf_hash_table (info), ++ elf_link_renumber_hash_table_dynsyms, ++ &dynsymcount); ++ ++ /* There is an unused NULL entry at the head of the table which we ++ must account for in our count even if the table is empty since it ++ is intended for the mandatory DT_SYMTAB tag (.dynsym section) in ++ .dynamic section. */ ++ dynsymcount++; ++ ++ elf_hash_table (info)->dynsymcount = dynsymcount; ++ return dynsymcount; ++} ++ ++/* Merge st_other field. */ ++ ++static void ++elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, ++ unsigned int st_other, asection *sec, ++ bool definition, bool dynamic) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ /* If st_other has a processor-specific meaning, specific ++ code might be needed here. */ ++ if (bed->elf_backend_merge_symbol_attribute) ++ (*bed->elf_backend_merge_symbol_attribute) (h, st_other, definition, ++ dynamic); ++ ++ if (!dynamic) ++ { ++ unsigned symvis = ELF_ST_VISIBILITY (st_other); ++ unsigned hvis = ELF_ST_VISIBILITY (h->other); ++ ++ /* Keep the most constraining visibility. Leave the remainder ++ of the st_other field to elf_backend_merge_symbol_attribute. */ ++ if (symvis - 1 < hvis - 1) ++ h->other = symvis | (h->other & ~ELF_ST_VISIBILITY (-1)); ++ } ++ else if (definition ++ && ELF_ST_VISIBILITY (st_other) != STV_DEFAULT ++ && (sec->flags & SEC_READONLY) == 0) ++ h->protected_def = 1; ++} ++ ++/* This function is called when we want to merge a new symbol with an ++ existing symbol. It handles the various cases which arise when we ++ find a definition in a dynamic object, or when there is already a ++ definition in a dynamic object. The new symbol is described by ++ NAME, SYM, PSEC, and PVALUE. We set SYM_HASH to the hash table ++ entry. We set POLDBFD to the old symbol's BFD. We set POLD_WEAK ++ if the old symbol was weak. We set POLD_ALIGNMENT to the alignment ++ of an old common symbol. We set OVERRIDE if the old symbol is ++ overriding a new definition. We set TYPE_CHANGE_OK if it is OK for ++ the type to change. We set SIZE_CHANGE_OK if it is OK for the size ++ to change. By OK to change, we mean that we shouldn't warn if the ++ type or size does change. */ ++ ++static bool ++_bfd_elf_merge_symbol (bfd *abfd, ++ struct bfd_link_info *info, ++ const char *name, ++ Elf_Internal_Sym *sym, ++ asection **psec, ++ bfd_vma *pvalue, ++ struct elf_link_hash_entry **sym_hash, ++ bfd **poldbfd, ++ bool *pold_weak, ++ unsigned int *pold_alignment, ++ bool *skip, ++ bfd **override, ++ bool *type_change_ok, ++ bool *size_change_ok, ++ bool *matched) ++{ ++ asection *sec, *oldsec; ++ struct elf_link_hash_entry *h; ++ struct elf_link_hash_entry *hi; ++ struct elf_link_hash_entry *flip; ++ int bind; ++ bfd *oldbfd; ++ bool newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; ++ bool newweak, oldweak, newfunc, oldfunc; ++ const struct elf_backend_data *bed; ++ char *new_version; ++ bool default_sym = *matched; ++ struct elf_link_hash_table *htab; ++ ++ *skip = false; ++ *override = NULL; ++ ++ sec = *psec; ++ bind = ELF_ST_BIND (sym->st_info); ++ ++ if (! bfd_is_und_section (sec)) ++ h = elf_link_hash_lookup (elf_hash_table (info), name, true, false, false); ++ else ++ h = ((struct elf_link_hash_entry *) ++ bfd_wrapped_link_hash_lookup (abfd, info, name, true, false, false)); ++ if (h == NULL) ++ return false; ++ *sym_hash = h; ++ ++ bed = get_elf_backend_data (abfd); ++ ++ /* NEW_VERSION is the symbol version of the new symbol. */ ++ if (h->versioned != unversioned) ++ { ++ /* Symbol version is unknown or versioned. */ ++ new_version = strrchr (name, ELF_VER_CHR); ++ if (new_version) ++ { ++ if (h->versioned == unknown) ++ { ++ if (new_version > name && new_version[-1] != ELF_VER_CHR) ++ h->versioned = versioned_hidden; ++ else ++ h->versioned = versioned; ++ } ++ new_version += 1; ++ if (new_version[0] == '\0') ++ new_version = NULL; ++ } ++ else ++ h->versioned = unversioned; ++ } ++ else ++ new_version = NULL; ++ ++ /* For merging, we only care about real symbols. But we need to make ++ sure that indirect symbol dynamic flags are updated. */ ++ hi = h; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if (!*matched) ++ { ++ if (hi == h || h->root.type == bfd_link_hash_new) ++ *matched = true; ++ else ++ { ++ /* OLD_HIDDEN is true if the existing symbol is only visible ++ to the symbol with the same symbol version. NEW_HIDDEN is ++ true if the new symbol is only visible to the symbol with ++ the same symbol version. */ ++ bool old_hidden = h->versioned == versioned_hidden; ++ bool new_hidden = hi->versioned == versioned_hidden; ++ if (!old_hidden && !new_hidden) ++ /* The new symbol matches the existing symbol if both ++ aren't hidden. */ ++ *matched = true; ++ else ++ { ++ /* OLD_VERSION is the symbol version of the existing ++ symbol. */ ++ char *old_version; ++ ++ if (h->versioned >= versioned) ++ old_version = strrchr (h->root.root.string, ++ ELF_VER_CHR) + 1; ++ else ++ old_version = NULL; ++ ++ /* The new symbol matches the existing symbol if they ++ have the same symbol version. */ ++ *matched = (old_version == new_version ++ || (old_version != NULL ++ && new_version != NULL ++ && strcmp (old_version, new_version) == 0)); ++ } ++ } ++ } ++ ++ /* OLDBFD and OLDSEC are a BFD and an ASECTION associated with the ++ existing symbol. */ ++ ++ oldbfd = NULL; ++ oldsec = NULL; ++ switch (h->root.type) ++ { ++ default: ++ break; ++ ++ case bfd_link_hash_undefined: ++ case bfd_link_hash_undefweak: ++ oldbfd = h->root.u.undef.abfd; ++ break; ++ ++ case bfd_link_hash_defined: ++ case bfd_link_hash_defweak: ++ oldbfd = h->root.u.def.section->owner; ++ oldsec = h->root.u.def.section; ++ break; ++ ++ case bfd_link_hash_common: ++ oldbfd = h->root.u.c.p->section->owner; ++ oldsec = h->root.u.c.p->section; ++ if (pold_alignment) ++ *pold_alignment = h->root.u.c.p->alignment_power; ++ break; ++ } ++ if (poldbfd && *poldbfd == NULL) ++ *poldbfd = oldbfd; ++ ++ /* Differentiate strong and weak symbols. */ ++ newweak = bind == STB_WEAK; ++ oldweak = (h->root.type == bfd_link_hash_defweak ++ || h->root.type == bfd_link_hash_undefweak); ++ if (pold_weak) ++ *pold_weak = oldweak; ++ ++ /* We have to check it for every instance since the first few may be ++ references and not all compilers emit symbol type for undefined ++ symbols. */ ++ bfd_elf_link_mark_dynamic_symbol (info, h, sym); ++ ++ htab = elf_hash_table (info); ++ ++ /* NEWDYN and OLDDYN indicate whether the new or old symbol, ++ respectively, is from a dynamic object. */ ++ ++ newdyn = (abfd->flags & DYNAMIC) != 0; ++ ++ /* ref_dynamic_nonweak and dynamic_def flags track actual undefined ++ syms and defined syms in dynamic libraries respectively. ++ ref_dynamic on the other hand can be set for a symbol defined in ++ a dynamic library, and def_dynamic may not be set; When the ++ definition in a dynamic lib is overridden by a definition in the ++ executable use of the symbol in the dynamic lib becomes a ++ reference to the executable symbol. */ ++ if (newdyn) ++ { ++ if (bfd_is_und_section (sec)) ++ { ++ if (bind != STB_WEAK) ++ { ++ h->ref_dynamic_nonweak = 1; ++ hi->ref_dynamic_nonweak = 1; ++ } ++ } ++ else ++ { ++ /* Update the existing symbol only if they match. */ ++ if (*matched) ++ h->dynamic_def = 1; ++ hi->dynamic_def = 1; ++ } ++ } ++ ++ /* If we just created the symbol, mark it as being an ELF symbol. ++ Other than that, there is nothing to do--there is no merge issue ++ with a newly defined symbol--so we just return. */ ++ ++ if (h->root.type == bfd_link_hash_new) ++ { ++ h->non_elf = 0; ++ return true; ++ } ++ ++ /* In cases involving weak versioned symbols, we may wind up trying ++ to merge a symbol with itself. Catch that here, to avoid the ++ confusion that results if we try to override a symbol with ++ itself. The additional tests catch cases like ++ _GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a ++ dynamic object, which we do want to handle here. */ ++ if (abfd == oldbfd ++ && (newweak || oldweak) ++ && ((abfd->flags & DYNAMIC) == 0 ++ || !h->def_regular)) ++ return true; ++ ++ olddyn = false; ++ if (oldbfd != NULL) ++ olddyn = (oldbfd->flags & DYNAMIC) != 0; ++ else if (oldsec != NULL) ++ { ++ /* This handles the special SHN_MIPS_{TEXT,DATA} section ++ indices used by MIPS ELF. */ ++ olddyn = (oldsec->symbol->flags & BSF_DYNAMIC) != 0; ++ } ++ ++ /* Set non_ir_ref_dynamic only when not handling DT_NEEDED entries. */ ++ if (!htab->handling_dt_needed ++ && oldbfd != NULL ++ && (oldbfd->flags & BFD_PLUGIN) != (abfd->flags & BFD_PLUGIN)) ++ { ++ if (newdyn != olddyn) ++ { ++ /* Handle a case where plugin_notice won't be called and thus ++ won't set the non_ir_ref flags on the first pass over ++ symbols. */ ++ h->root.non_ir_ref_dynamic = true; ++ hi->root.non_ir_ref_dynamic = true; ++ } ++ else if ((oldbfd->flags & BFD_PLUGIN) != 0 ++ && hi->root.type == bfd_link_hash_indirect) ++ { ++ /* Change indirect symbol from IR to undefined. */ ++ hi->root.type = bfd_link_hash_undefined; ++ hi->root.u.undef.abfd = oldbfd; ++ } ++ } ++ ++ /* NEWDEF and OLDDEF indicate whether the new or old symbol, ++ respectively, appear to be a definition rather than reference. */ ++ ++ newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec); ++ ++ olddef = (h->root.type != bfd_link_hash_undefined ++ && h->root.type != bfd_link_hash_undefweak ++ && h->root.type != bfd_link_hash_common); ++ ++ /* NEWFUNC and OLDFUNC indicate whether the new or old symbol, ++ respectively, appear to be a function. */ ++ ++ newfunc = (ELF_ST_TYPE (sym->st_info) != STT_NOTYPE ++ && bed->is_function_type (ELF_ST_TYPE (sym->st_info))); ++ ++ oldfunc = (h->type != STT_NOTYPE ++ && bed->is_function_type (h->type)); ++ ++ if (!(newfunc && oldfunc) ++ && ELF_ST_TYPE (sym->st_info) != h->type ++ && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE ++ && h->type != STT_NOTYPE ++ && (newdef || bfd_is_com_section (sec)) ++ && (olddef || h->root.type == bfd_link_hash_common)) ++ { ++ /* If creating a default indirect symbol ("foo" or "foo@") from ++ a dynamic versioned definition ("foo@@") skip doing so if ++ there is an existing regular definition with a different ++ type. We don't want, for example, a "time" variable in the ++ executable overriding a "time" function in a shared library. */ ++ if (newdyn ++ && !olddyn) ++ { ++ *skip = true; ++ return true; ++ } ++ ++ /* When adding a symbol from a regular object file after we have ++ created indirect symbols, undo the indirection and any ++ dynamic state. */ ++ if (hi != h ++ && !newdyn ++ && olddyn) ++ { ++ h = hi; ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ h->forced_local = 0; ++ h->ref_dynamic = 0; ++ h->def_dynamic = 0; ++ h->dynamic_def = 0; ++ if (h->root.u.undef.next || info->hash->undefs_tail == &h->root) ++ { ++ h->root.type = bfd_link_hash_undefined; ++ h->root.u.undef.abfd = abfd; ++ } ++ else ++ { ++ h->root.type = bfd_link_hash_new; ++ h->root.u.undef.abfd = NULL; ++ } ++ return true; ++ } ++ } ++ ++ /* Check TLS symbols. We don't check undefined symbols introduced ++ by "ld -u" which have no type (and oldbfd NULL), and we don't ++ check symbols from plugins because they also have no type. */ ++ if (oldbfd != NULL ++ && (oldbfd->flags & BFD_PLUGIN) == 0 ++ && (abfd->flags & BFD_PLUGIN) == 0 ++ && ELF_ST_TYPE (sym->st_info) != h->type ++ && (ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)) ++ { ++ bfd *ntbfd, *tbfd; ++ bool ntdef, tdef; ++ asection *ntsec, *tsec; ++ ++ if (h->type == STT_TLS) ++ { ++ ntbfd = abfd; ++ ntsec = sec; ++ ntdef = newdef; ++ tbfd = oldbfd; ++ tsec = oldsec; ++ tdef = olddef; ++ } ++ else ++ { ++ ntbfd = oldbfd; ++ ntsec = oldsec; ++ ntdef = olddef; ++ tbfd = abfd; ++ tsec = sec; ++ tdef = newdef; ++ } ++ ++ if (tdef && ntdef) ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%s: TLS definition in %pB section %pA " ++ "mismatches non-TLS definition in %pB section %pA"), ++ h->root.root.string, tbfd, tsec, ntbfd, ntsec); ++ else if (!tdef && !ntdef) ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%s: TLS reference in %pB " ++ "mismatches non-TLS reference in %pB"), ++ h->root.root.string, tbfd, ntbfd); ++ else if (tdef) ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%s: TLS definition in %pB section %pA " ++ "mismatches non-TLS reference in %pB"), ++ h->root.root.string, tbfd, tsec, ntbfd); ++ else ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%s: TLS reference in %pB " ++ "mismatches non-TLS definition in %pB section %pA"), ++ h->root.root.string, tbfd, ntbfd, ntsec); ++ ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ ++ /* If the old symbol has non-default visibility, we ignore the new ++ definition from a dynamic object. */ ++ if (newdyn ++ && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT ++ && !bfd_is_und_section (sec)) ++ { ++ *skip = true; ++ /* Make sure this symbol is dynamic. */ ++ h->ref_dynamic = 1; ++ hi->ref_dynamic = 1; ++ /* A protected symbol has external availability. Make sure it is ++ recorded as dynamic. ++ ++ FIXME: Should we check type and size for protected symbol? */ ++ if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) ++ return bfd_elf_link_record_dynamic_symbol (info, h); ++ else ++ return true; ++ } ++ else if (!newdyn ++ && ELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT ++ && h->def_dynamic) ++ { ++ /* If the new symbol with non-default visibility comes from a ++ relocatable file and the old definition comes from a dynamic ++ object, we remove the old definition. */ ++ if (hi->root.type == bfd_link_hash_indirect) ++ { ++ /* Handle the case where the old dynamic definition is ++ default versioned. We need to copy the symbol info from ++ the symbol with default version to the normal one if it ++ was referenced before. */ ++ if (h->ref_regular) ++ { ++ hi->root.type = h->root.type; ++ h->root.type = bfd_link_hash_indirect; ++ (*bed->elf_backend_copy_indirect_symbol) (info, hi, h); ++ ++ h->root.u.i.link = (struct bfd_link_hash_entry *) hi; ++ if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED) ++ { ++ /* If the new symbol is hidden or internal, completely undo ++ any dynamic link state. */ ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ h->forced_local = 0; ++ h->ref_dynamic = 0; ++ } ++ else ++ h->ref_dynamic = 1; ++ ++ h->def_dynamic = 0; ++ /* FIXME: Should we check type and size for protected symbol? */ ++ h->size = 0; ++ h->type = 0; ++ ++ h = hi; ++ } ++ else ++ h = hi; ++ } ++ ++ /* If the old symbol was undefined before, then it will still be ++ on the undefs list. If the new symbol is undefined or ++ common, we can't make it bfd_link_hash_new here, because new ++ undefined or common symbols will be added to the undefs list ++ by _bfd_generic_link_add_one_symbol. Symbols may not be ++ added twice to the undefs list. Also, if the new symbol is ++ undefweak then we don't want to lose the strong undef. */ ++ if (h->root.u.undef.next || info->hash->undefs_tail == &h->root) ++ { ++ h->root.type = bfd_link_hash_undefined; ++ h->root.u.undef.abfd = abfd; ++ } ++ else ++ { ++ h->root.type = bfd_link_hash_new; ++ h->root.u.undef.abfd = NULL; ++ } ++ ++ if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED) ++ { ++ /* If the new symbol is hidden or internal, completely undo ++ any dynamic link state. */ ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ h->forced_local = 0; ++ h->ref_dynamic = 0; ++ } ++ else ++ h->ref_dynamic = 1; ++ h->def_dynamic = 0; ++ /* FIXME: Should we check type and size for protected symbol? */ ++ h->size = 0; ++ h->type = 0; ++ return true; ++ } ++ ++ /* If a new weak symbol definition comes from a regular file and the ++ old symbol comes from a dynamic library, we treat the new one as ++ strong. Similarly, an old weak symbol definition from a regular ++ file is treated as strong when the new symbol comes from a dynamic ++ library. Further, an old weak symbol from a dynamic library is ++ treated as strong if the new symbol is from a dynamic library. ++ This reflects the way glibc's ld.so works. ++ ++ Also allow a weak symbol to override a linker script symbol ++ defined by an early pass over the script. This is done so the ++ linker knows the symbol is defined in an object file, for the ++ DEFINED script function. ++ ++ Do this before setting *type_change_ok or *size_change_ok so that ++ we warn properly when dynamic library symbols are overridden. */ ++ ++ if (newdef && !newdyn && (olddyn || h->root.ldscript_def)) ++ newweak = false; ++ if (olddef && newdyn) ++ oldweak = false; ++ ++ /* Allow changes between different types of function symbol. */ ++ if (newfunc && oldfunc) ++ *type_change_ok = true; ++ ++ /* It's OK to change the type if either the existing symbol or the ++ new symbol is weak. A type change is also OK if the old symbol ++ is undefined and the new symbol is defined. */ ++ ++ if (oldweak ++ || newweak ++ || (newdef ++ && h->root.type == bfd_link_hash_undefined)) ++ *type_change_ok = true; ++ ++ /* It's OK to change the size if either the existing symbol or the ++ new symbol is weak, or if the old symbol is undefined. */ ++ ++ if (*type_change_ok ++ || h->root.type == bfd_link_hash_undefined) ++ *size_change_ok = true; ++ ++ /* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old ++ symbol, respectively, appears to be a common symbol in a dynamic ++ object. If a symbol appears in an uninitialized section, and is ++ not weak, and is not a function, then it may be a common symbol ++ which was resolved when the dynamic object was created. We want ++ to treat such symbols specially, because they raise special ++ considerations when setting the symbol size: if the symbol ++ appears as a common symbol in a regular object, and the size in ++ the regular object is larger, we must make sure that we use the ++ larger size. This problematic case can always be avoided in C, ++ but it must be handled correctly when using Fortran shared ++ libraries. ++ ++ Note that if NEWDYNCOMMON is set, NEWDEF will be set, and ++ likewise for OLDDYNCOMMON and OLDDEF. ++ ++ Note that this test is just a heuristic, and that it is quite ++ possible to have an uninitialized symbol in a shared object which ++ is really a definition, rather than a common symbol. This could ++ lead to some minor confusion when the symbol really is a common ++ symbol in some regular object. However, I think it will be ++ harmless. */ ++ ++ if (newdyn ++ && newdef ++ && !newweak ++ && (sec->flags & SEC_ALLOC) != 0 ++ && (sec->flags & SEC_LOAD) == 0 ++ && sym->st_size > 0 ++ && !newfunc) ++ newdyncommon = true; ++ else ++ newdyncommon = false; ++ ++ if (olddyn ++ && olddef ++ && h->root.type == bfd_link_hash_defined ++ && h->def_dynamic ++ && (h->root.u.def.section->flags & SEC_ALLOC) != 0 ++ && (h->root.u.def.section->flags & SEC_LOAD) == 0 ++ && h->size > 0 ++ && !oldfunc) ++ olddyncommon = true; ++ else ++ olddyncommon = false; ++ ++ /* We now know everything about the old and new symbols. We ask the ++ backend to check if we can merge them. */ ++ if (bed->merge_symbol != NULL) ++ { ++ if (!bed->merge_symbol (h, sym, psec, newdef, olddef, oldbfd, oldsec)) ++ return false; ++ sec = *psec; ++ } ++ ++ /* There are multiple definitions of a normal symbol. Skip the ++ default symbol as well as definition from an IR object. */ ++ if (olddef && !olddyn && !oldweak && newdef && !newdyn && !newweak ++ && !default_sym && h->def_regular ++ && !(oldbfd != NULL ++ && (oldbfd->flags & BFD_PLUGIN) != 0 ++ && (abfd->flags & BFD_PLUGIN) == 0)) ++ { ++ /* Handle a multiple definition. */ ++ (*info->callbacks->multiple_definition) (info, &h->root, ++ abfd, sec, *pvalue); ++ *skip = true; ++ return true; ++ } ++ ++ /* If both the old and the new symbols look like common symbols in a ++ dynamic object, set the size of the symbol to the larger of the ++ two. */ ++ ++ if (olddyncommon ++ && newdyncommon ++ && sym->st_size != h->size) ++ { ++ /* Since we think we have two common symbols, issue a multiple ++ common warning if desired. Note that we only warn if the ++ size is different. If the size is the same, we simply let ++ the old symbol override the new one as normally happens with ++ symbols defined in dynamic objects. */ ++ ++ (*info->callbacks->multiple_common) (info, &h->root, abfd, ++ bfd_link_hash_common, sym->st_size); ++ if (sym->st_size > h->size) ++ h->size = sym->st_size; ++ ++ *size_change_ok = true; ++ } ++ ++ /* If we are looking at a dynamic object, and we have found a ++ definition, we need to see if the symbol was already defined by ++ some other object. If so, we want to use the existing ++ definition, and we do not want to report a multiple symbol ++ definition error; we do this by clobbering *PSEC to be ++ bfd_und_section_ptr. ++ ++ We treat a common symbol as a definition if the symbol in the ++ shared library is a function, since common symbols always ++ represent variables; this can cause confusion in principle, but ++ any such confusion would seem to indicate an erroneous program or ++ shared library. We also permit a common symbol in a regular ++ object to override a weak symbol in a shared object. */ ++ ++ if (newdyn ++ && newdef ++ && (olddef ++ || (h->root.type == bfd_link_hash_common ++ && (newweak || newfunc)))) ++ { ++ *override = abfd; ++ newdef = false; ++ newdyncommon = false; ++ ++ *psec = sec = bfd_und_section_ptr; ++ *size_change_ok = true; ++ ++ /* If we get here when the old symbol is a common symbol, then ++ we are explicitly letting it override a weak symbol or ++ function in a dynamic object, and we don't want to warn about ++ a type change. If the old symbol is a defined symbol, a type ++ change warning may still be appropriate. */ ++ ++ if (h->root.type == bfd_link_hash_common) ++ *type_change_ok = true; ++ } ++ ++ /* Handle the special case of an old common symbol merging with a ++ new symbol which looks like a common symbol in a shared object. ++ We change *PSEC and *PVALUE to make the new symbol look like a ++ common symbol, and let _bfd_generic_link_add_one_symbol do the ++ right thing. */ ++ ++ if (newdyncommon ++ && h->root.type == bfd_link_hash_common) ++ { ++ *override = oldbfd; ++ newdef = false; ++ newdyncommon = false; ++ *pvalue = sym->st_size; ++ *psec = sec = bed->common_section (oldsec); ++ *size_change_ok = true; ++ } ++ ++ /* Skip weak definitions of symbols that are already defined. */ ++ if (newdef && olddef && newweak) ++ { ++ /* Don't skip new non-IR weak syms. */ ++ if (!(oldbfd != NULL ++ && (oldbfd->flags & BFD_PLUGIN) != 0 ++ && (abfd->flags & BFD_PLUGIN) == 0)) ++ { ++ newdef = false; ++ *skip = true; ++ } ++ ++ /* Merge st_other. If the symbol already has a dynamic index, ++ but visibility says it should not be visible, turn it into a ++ local symbol. */ ++ elf_merge_st_other (abfd, h, sym->st_other, sec, newdef, newdyn); ++ if (h->dynindx != -1) ++ switch (ELF_ST_VISIBILITY (h->other)) ++ { ++ case STV_INTERNAL: ++ case STV_HIDDEN: ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ break; ++ } ++ } ++ ++ /* If the old symbol is from a dynamic object, and the new symbol is ++ a definition which is not from a dynamic object, then the new ++ symbol overrides the old symbol. Symbols from regular files ++ always take precedence over symbols from dynamic objects, even if ++ they are defined after the dynamic object in the link. ++ ++ As above, we again permit a common symbol in a regular object to ++ override a definition in a shared object if the shared object ++ symbol is a function or is weak. */ ++ ++ flip = NULL; ++ if (!newdyn ++ && (newdef ++ || (bfd_is_com_section (sec) ++ && (oldweak || oldfunc))) ++ && olddyn ++ && olddef ++ && h->def_dynamic) ++ { ++ /* Change the hash table entry to undefined, and let ++ _bfd_generic_link_add_one_symbol do the right thing with the ++ new definition. */ ++ ++ h->root.type = bfd_link_hash_undefined; ++ h->root.u.undef.abfd = h->root.u.def.section->owner; ++ *size_change_ok = true; ++ ++ olddef = false; ++ olddyncommon = false; ++ ++ /* We again permit a type change when a common symbol may be ++ overriding a function. */ ++ ++ if (bfd_is_com_section (sec)) ++ { ++ if (oldfunc) ++ { ++ /* If a common symbol overrides a function, make sure ++ that it isn't defined dynamically nor has type ++ function. */ ++ h->def_dynamic = 0; ++ h->type = STT_NOTYPE; ++ } ++ *type_change_ok = true; ++ } ++ ++ if (hi->root.type == bfd_link_hash_indirect) ++ flip = hi; ++ else ++ /* This union may have been set to be non-NULL when this symbol ++ was seen in a dynamic object. We must force the union to be ++ NULL, so that it is correct for a regular symbol. */ ++ h->verinfo.vertree = NULL; ++ } ++ ++ /* Handle the special case of a new common symbol merging with an ++ old symbol that looks like it might be a common symbol defined in ++ a shared object. Note that we have already handled the case in ++ which a new common symbol should simply override the definition ++ in the shared library. */ ++ ++ if (! newdyn ++ && bfd_is_com_section (sec) ++ && olddyncommon) ++ { ++ /* It would be best if we could set the hash table entry to a ++ common symbol, but we don't know what to use for the section ++ or the alignment. */ ++ (*info->callbacks->multiple_common) (info, &h->root, abfd, ++ bfd_link_hash_common, sym->st_size); ++ ++ /* If the presumed common symbol in the dynamic object is ++ larger, pretend that the new symbol has its size. */ ++ ++ if (h->size > *pvalue) ++ *pvalue = h->size; ++ ++ /* We need to remember the alignment required by the symbol ++ in the dynamic object. */ ++ BFD_ASSERT (pold_alignment); ++ *pold_alignment = h->root.u.def.section->alignment_power; ++ ++ olddef = false; ++ olddyncommon = false; ++ ++ h->root.type = bfd_link_hash_undefined; ++ h->root.u.undef.abfd = h->root.u.def.section->owner; ++ ++ *size_change_ok = true; ++ *type_change_ok = true; ++ ++ if (hi->root.type == bfd_link_hash_indirect) ++ flip = hi; ++ else ++ h->verinfo.vertree = NULL; ++ } ++ ++ if (flip != NULL) ++ { ++ /* Handle the case where we had a versioned symbol in a dynamic ++ library and now find a definition in a normal object. In this ++ case, we make the versioned symbol point to the normal one. */ ++ flip->root.type = h->root.type; ++ flip->root.u.undef.abfd = h->root.u.undef.abfd; ++ h->root.type = bfd_link_hash_indirect; ++ h->root.u.i.link = (struct bfd_link_hash_entry *) flip; ++ (*bed->elf_backend_copy_indirect_symbol) (info, flip, h); ++ if (h->def_dynamic) ++ { ++ h->def_dynamic = 0; ++ flip->ref_dynamic = 1; ++ } ++ } ++ ++ return true; ++} ++ ++/* This function is called to create an indirect symbol from the ++ default for the symbol with the default version if needed. The ++ symbol is described by H, NAME, SYM, SEC, and VALUE. We ++ set DYNSYM if the new indirect symbol is dynamic. */ ++ ++static bool ++_bfd_elf_add_default_symbol (bfd *abfd, ++ struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, ++ const char *name, ++ Elf_Internal_Sym *sym, ++ asection *sec, ++ bfd_vma value, ++ bfd **poldbfd, ++ bool *dynsym) ++{ ++ bool type_change_ok; ++ bool size_change_ok; ++ bool skip; ++ char *shortname; ++ struct elf_link_hash_entry *hi; ++ struct bfd_link_hash_entry *bh; ++ const struct elf_backend_data *bed; ++ bool collect; ++ bool dynamic; ++ bfd *override; ++ char *p; ++ size_t len, shortlen; ++ asection *tmp_sec; ++ bool matched; ++ ++ if (h->versioned == unversioned || h->versioned == versioned_hidden) ++ return true; ++ ++ /* If this symbol has a version, and it is the default version, we ++ create an indirect symbol from the default name to the fully ++ decorated name. This will cause external references which do not ++ specify a version to be bound to this version of the symbol. */ ++ p = strchr (name, ELF_VER_CHR); ++ if (h->versioned == unknown) ++ { ++ if (p == NULL) ++ { ++ h->versioned = unversioned; ++ return true; ++ } ++ else ++ { ++ if (p[1] != ELF_VER_CHR) ++ { ++ h->versioned = versioned_hidden; ++ return true; ++ } ++ else ++ h->versioned = versioned; ++ } ++ } ++ else ++ { ++ /* PR ld/19073: We may see an unversioned definition after the ++ default version. */ ++ if (p == NULL) ++ return true; ++ } ++ ++ bed = get_elf_backend_data (abfd); ++ collect = bed->collect; ++ dynamic = (abfd->flags & DYNAMIC) != 0; ++ ++ shortlen = p - name; ++ shortname = (char *) bfd_hash_allocate (&info->hash->table, shortlen + 1); ++ if (shortname == NULL) ++ return false; ++ memcpy (shortname, name, shortlen); ++ shortname[shortlen] = '\0'; ++ ++ /* We are going to create a new symbol. Merge it with any existing ++ symbol with this name. For the purposes of the merge, act as ++ though we were defining the symbol we just defined, although we ++ actually going to define an indirect symbol. */ ++ type_change_ok = false; ++ size_change_ok = false; ++ matched = true; ++ tmp_sec = sec; ++ if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value, ++ &hi, poldbfd, NULL, NULL, &skip, &override, ++ &type_change_ok, &size_change_ok, &matched)) ++ return false; ++ ++ if (skip) ++ goto nondefault; ++ ++ if (hi->def_regular || ELF_COMMON_DEF_P (hi)) ++ { ++ /* If the undecorated symbol will have a version added by a ++ script different to H, then don't indirect to/from the ++ undecorated symbol. This isn't ideal because we may not yet ++ have seen symbol versions, if given by a script on the ++ command line rather than via --version-script. */ ++ if (hi->verinfo.vertree == NULL && info->version_info != NULL) ++ { ++ bool hide; ++ ++ hi->verinfo.vertree ++ = bfd_find_version_for_sym (info->version_info, ++ hi->root.root.string, &hide); ++ if (hi->verinfo.vertree != NULL && hide) ++ { ++ (*bed->elf_backend_hide_symbol) (info, hi, true); ++ goto nondefault; ++ } ++ } ++ if (hi->verinfo.vertree != NULL ++ && strcmp (p + 1 + (p[1] == '@'), hi->verinfo.vertree->name) != 0) ++ goto nondefault; ++ } ++ ++ if (! override) ++ { ++ /* Add the default symbol if not performing a relocatable link. */ ++ if (! bfd_link_relocatable (info)) ++ { ++ bh = &hi->root; ++ if (bh->type == bfd_link_hash_defined ++ && bh->u.def.section->owner != NULL ++ && (bh->u.def.section->owner->flags & BFD_PLUGIN) != 0) ++ { ++ /* Mark the previous definition from IR object as ++ undefined so that the generic linker will override ++ it. */ ++ bh->type = bfd_link_hash_undefined; ++ bh->u.undef.abfd = bh->u.def.section->owner; ++ } ++ if (! (_bfd_generic_link_add_one_symbol ++ (info, abfd, shortname, BSF_INDIRECT, ++ bfd_ind_section_ptr, ++ 0, name, false, collect, &bh))) ++ return false; ++ hi = (struct elf_link_hash_entry *) bh; ++ } ++ } ++ else ++ { ++ /* In this case the symbol named SHORTNAME is overriding the ++ indirect symbol we want to add. We were planning on making ++ SHORTNAME an indirect symbol referring to NAME. SHORTNAME ++ is the name without a version. NAME is the fully versioned ++ name, and it is the default version. ++ ++ Overriding means that we already saw a definition for the ++ symbol SHORTNAME in a regular object, and it is overriding ++ the symbol defined in the dynamic object. ++ ++ When this happens, we actually want to change NAME, the ++ symbol we just added, to refer to SHORTNAME. This will cause ++ references to NAME in the shared object to become references ++ to SHORTNAME in the regular object. This is what we expect ++ when we override a function in a shared object: that the ++ references in the shared object will be mapped to the ++ definition in the regular object. */ ++ ++ while (hi->root.type == bfd_link_hash_indirect ++ || hi->root.type == bfd_link_hash_warning) ++ hi = (struct elf_link_hash_entry *) hi->root.u.i.link; ++ ++ h->root.type = bfd_link_hash_indirect; ++ h->root.u.i.link = (struct bfd_link_hash_entry *) hi; ++ if (h->def_dynamic) ++ { ++ h->def_dynamic = 0; ++ hi->ref_dynamic = 1; ++ if (hi->ref_regular ++ || hi->def_regular) ++ { ++ if (! bfd_elf_link_record_dynamic_symbol (info, hi)) ++ return false; ++ } ++ } ++ ++ /* Now set HI to H, so that the following code will set the ++ other fields correctly. */ ++ hi = h; ++ } ++ ++ /* Check if HI is a warning symbol. */ ++ if (hi->root.type == bfd_link_hash_warning) ++ hi = (struct elf_link_hash_entry *) hi->root.u.i.link; ++ ++ /* If there is a duplicate definition somewhere, then HI may not ++ point to an indirect symbol. We will have reported an error to ++ the user in that case. */ ++ ++ if (hi->root.type == bfd_link_hash_indirect) ++ { ++ struct elf_link_hash_entry *ht; ++ ++ ht = (struct elf_link_hash_entry *) hi->root.u.i.link; ++ (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi); ++ ++ /* If we first saw a reference to SHORTNAME with non-default ++ visibility, merge that visibility to the @@VER symbol. */ ++ elf_merge_st_other (abfd, ht, hi->other, sec, true, dynamic); ++ ++ /* A reference to the SHORTNAME symbol from a dynamic library ++ will be satisfied by the versioned symbol at runtime. In ++ effect, we have a reference to the versioned symbol. */ ++ ht->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak; ++ hi->dynamic_def |= ht->dynamic_def; ++ ++ /* See if the new flags lead us to realize that the symbol must ++ be dynamic. */ ++ if (! *dynsym) ++ { ++ if (! dynamic) ++ { ++ if (! bfd_link_executable (info) ++ || hi->def_dynamic ++ || hi->ref_dynamic) ++ *dynsym = true; ++ } ++ else ++ { ++ if (hi->ref_regular) ++ *dynsym = true; ++ } ++ } ++ } ++ ++ /* We also need to define an indirection from the nondefault version ++ of the symbol. */ ++ ++ nondefault: ++ len = strlen (name); ++ shortname = (char *) bfd_hash_allocate (&info->hash->table, len); ++ if (shortname == NULL) ++ return false; ++ memcpy (shortname, name, shortlen); ++ memcpy (shortname + shortlen, p + 1, len - shortlen); ++ ++ /* Once again, merge with any existing symbol. */ ++ type_change_ok = false; ++ size_change_ok = false; ++ tmp_sec = sec; ++ if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value, ++ &hi, poldbfd, NULL, NULL, &skip, &override, ++ &type_change_ok, &size_change_ok, &matched)) ++ return false; ++ ++ if (skip) ++ { ++ if (!dynamic ++ && h->root.type == bfd_link_hash_defweak ++ && hi->root.type == bfd_link_hash_defined) ++ { ++ /* We are handling a weak sym@@ver and attempting to define ++ a weak sym@ver, but _bfd_elf_merge_symbol said to skip the ++ new weak sym@ver because there is already a strong sym@ver. ++ However, sym@ver and sym@@ver are really the same symbol. ++ The existing strong sym@ver ought to override sym@@ver. */ ++ h->root.type = bfd_link_hash_defined; ++ h->root.u.def.section = hi->root.u.def.section; ++ h->root.u.def.value = hi->root.u.def.value; ++ hi->root.type = bfd_link_hash_indirect; ++ hi->root.u.i.link = &h->root; ++ } ++ else ++ return true; ++ } ++ else if (override) ++ { ++ /* Here SHORTNAME is a versioned name, so we don't expect to see ++ the type of override we do in the case above unless it is ++ overridden by a versioned definition. */ ++ if (hi->root.type != bfd_link_hash_defined ++ && hi->root.type != bfd_link_hash_defweak) ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: unexpected redefinition of indirect versioned symbol `%s'"), ++ abfd, shortname); ++ return true; ++ } ++ else ++ { ++ bh = &hi->root; ++ if (! (_bfd_generic_link_add_one_symbol ++ (info, abfd, shortname, BSF_INDIRECT, ++ bfd_ind_section_ptr, 0, name, false, collect, &bh))) ++ return false; ++ hi = (struct elf_link_hash_entry *) bh; ++ } ++ ++ /* If there is a duplicate definition somewhere, then HI may not ++ point to an indirect symbol. We will have reported an error ++ to the user in that case. */ ++ if (hi->root.type == bfd_link_hash_indirect) ++ { ++ (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); ++ h->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak; ++ hi->dynamic_def |= h->dynamic_def; ++ ++ /* If we first saw a reference to @VER symbol with ++ non-default visibility, merge that visibility to the ++ @@VER symbol. */ ++ elf_merge_st_other (abfd, h, hi->other, sec, true, dynamic); ++ ++ /* See if the new flags lead us to realize that the symbol ++ must be dynamic. */ ++ if (! *dynsym) ++ { ++ if (! dynamic) ++ { ++ if (! bfd_link_executable (info) ++ || hi->ref_dynamic) ++ *dynsym = true; ++ } ++ else ++ { ++ if (hi->ref_regular) ++ *dynsym = true; ++ } ++ } ++ } ++ ++ return true; ++} ++ ++/* This routine is used to export all defined symbols into the dynamic ++ symbol table. It is called via elf_link_hash_traverse. */ ++ ++static bool ++_bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) ++{ ++ struct elf_info_failed *eif = (struct elf_info_failed *) data; ++ ++ /* Ignore indirect symbols. These are added by the versioning code. */ ++ if (h->root.type == bfd_link_hash_indirect) ++ return true; ++ ++ /* Ignore this if we won't export it. */ ++ if (!eif->info->export_dynamic && !h->dynamic) ++ return true; ++ ++ if (h->dynindx == -1 ++ && (h->def_regular || h->ref_regular) ++ && ! bfd_hide_sym_by_version (eif->info->version_info, ++ h->root.root.string)) ++ { ++ if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) ++ { ++ eif->failed = true; ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++/* Return true if GLIBC_ABI_DT_RELR is added to the list of version ++ dependencies successfully. GLIBC_ABI_DT_RELR will be put into the ++ .gnu.version_r section. */ ++ ++static bool ++elf_link_add_dt_relr_dependency (struct elf_find_verdep_info *rinfo) ++{ ++ bfd *glibc_bfd = NULL; ++ Elf_Internal_Verneed *t; ++ Elf_Internal_Vernaux *a; ++ size_t amt; ++ const char *relr = "GLIBC_ABI_DT_RELR"; ++ ++ /* See if we already know about GLIBC_PRIVATE_DT_RELR. */ ++ for (t = elf_tdata (rinfo->info->output_bfd)->verref; ++ t != NULL; ++ t = t->vn_nextref) ++ { ++ const char *soname = bfd_elf_get_dt_soname (t->vn_bfd); ++ /* Skip the shared library if it isn't libc.so. */ ++ if (!soname || !startswith (soname, "libc.so.")) ++ continue; ++ ++ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) ++ { ++ /* Return if GLIBC_PRIVATE_DT_RELR dependency has been ++ added. */ ++ if (a->vna_nodename == relr ++ || strcmp (a->vna_nodename, relr) == 0) ++ return true; ++ ++ /* Check if libc.so provides GLIBC_2.XX version. */ ++ if (!glibc_bfd && startswith (a->vna_nodename, "GLIBC_2.")) ++ glibc_bfd = t->vn_bfd; ++ } ++ ++ break; ++ } ++ ++ /* Skip if it isn't linked against glibc. */ ++ if (glibc_bfd == NULL) ++ return true; ++ ++ /* This is a new version. Add it to tree we are building. */ ++ if (t == NULL) ++ { ++ amt = sizeof *t; ++ t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->info->output_bfd, ++ amt); ++ if (t == NULL) ++ { ++ rinfo->failed = true; ++ return false; ++ } ++ ++ t->vn_bfd = glibc_bfd; ++ t->vn_nextref = elf_tdata (rinfo->info->output_bfd)->verref; ++ elf_tdata (rinfo->info->output_bfd)->verref = t; ++ } ++ ++ amt = sizeof *a; ++ a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->info->output_bfd, amt); ++ if (a == NULL) ++ { ++ rinfo->failed = true; ++ return false; ++ } ++ ++ a->vna_nodename = relr; ++ a->vna_flags = 0; ++ a->vna_nextptr = t->vn_auxptr; ++ a->vna_other = rinfo->vers + 1; ++ ++rinfo->vers; ++ ++ t->vn_auxptr = a; ++ ++ return true; ++} ++ ++/* Look through the symbols which are defined in other shared ++ libraries and referenced here. Update the list of version ++ dependencies. This will be put into the .gnu.version_r section. ++ This function is called via elf_link_hash_traverse. */ ++ ++static bool ++_bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h, ++ void *data) ++{ ++ struct elf_find_verdep_info *rinfo = (struct elf_find_verdep_info *) data; ++ Elf_Internal_Verneed *t; ++ Elf_Internal_Vernaux *a; ++ size_t amt; ++ ++ /* We only care about symbols defined in shared objects with version ++ information. */ ++ if (!h->def_dynamic ++ || h->def_regular ++ || h->dynindx == -1 ++ || h->verinfo.verdef == NULL ++ || (elf_dyn_lib_class (h->verinfo.verdef->vd_bfd) ++ & (DYN_AS_NEEDED | DYN_DT_NEEDED | DYN_NO_NEEDED))) ++ return true; ++ ++ /* See if we already know about this version. */ ++ for (t = elf_tdata (rinfo->info->output_bfd)->verref; ++ t != NULL; ++ t = t->vn_nextref) ++ { ++ if (t->vn_bfd != h->verinfo.verdef->vd_bfd) ++ continue; ++ ++ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) ++ if (a->vna_nodename == h->verinfo.verdef->vd_nodename) ++ return true; ++ ++ break; ++ } ++ ++ /* This is a new version. Add it to tree we are building. */ ++ ++ if (t == NULL) ++ { ++ amt = sizeof *t; ++ t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->info->output_bfd, amt); ++ if (t == NULL) ++ { ++ rinfo->failed = true; ++ return false; ++ } ++ ++ t->vn_bfd = h->verinfo.verdef->vd_bfd; ++ t->vn_nextref = elf_tdata (rinfo->info->output_bfd)->verref; ++ elf_tdata (rinfo->info->output_bfd)->verref = t; ++ } ++ ++ amt = sizeof *a; ++ a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->info->output_bfd, amt); ++ if (a == NULL) ++ { ++ rinfo->failed = true; ++ return false; ++ } ++ ++ /* Note that we are copying a string pointer here, and testing it ++ above. If bfd_elf_string_from_elf_section is ever changed to ++ discard the string data when low in memory, this will have to be ++ fixed. */ ++ a->vna_nodename = h->verinfo.verdef->vd_nodename; ++ ++ a->vna_flags = h->verinfo.verdef->vd_flags; ++ a->vna_nextptr = t->vn_auxptr; ++ ++ h->verinfo.verdef->vd_exp_refno = rinfo->vers; ++ ++rinfo->vers; ++ ++ a->vna_other = h->verinfo.verdef->vd_exp_refno + 1; ++ ++ t->vn_auxptr = a; ++ ++ return true; ++} ++ ++/* Return TRUE and set *HIDE to TRUE if the versioned symbol is ++ hidden. Set *T_P to NULL if there is no match. */ ++ ++static bool ++_bfd_elf_link_hide_versioned_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, ++ const char *version_p, ++ struct bfd_elf_version_tree **t_p, ++ bool *hide) ++{ ++ struct bfd_elf_version_tree *t; ++ ++ /* Look for the version. If we find it, it is no longer weak. */ ++ for (t = info->version_info; t != NULL; t = t->next) ++ { ++ if (strcmp (t->name, version_p) == 0) ++ { ++ size_t len; ++ char *alc; ++ struct bfd_elf_version_expr *d; ++ ++ len = version_p - h->root.root.string; ++ alc = (char *) bfd_malloc (len); ++ if (alc == NULL) ++ return false; ++ memcpy (alc, h->root.root.string, len - 1); ++ alc[len - 1] = '\0'; ++ if (alc[len - 2] == ELF_VER_CHR) ++ alc[len - 2] = '\0'; ++ ++ h->verinfo.vertree = t; ++ t->used = true; ++ d = NULL; ++ ++ if (t->globals.list != NULL) ++ d = (*t->match) (&t->globals, NULL, alc); ++ ++ /* See if there is anything to force this symbol to ++ local scope. */ ++ if (d == NULL && t->locals.list != NULL) ++ { ++ d = (*t->match) (&t->locals, NULL, alc); ++ if (d != NULL ++ && h->dynindx != -1 ++ && ! info->export_dynamic) ++ *hide = true; ++ } ++ ++ free (alc); ++ break; ++ } ++ } ++ ++ *t_p = t; ++ ++ return true; ++} ++ ++/* Return TRUE if the symbol H is hidden by version script. */ ++ ++bool ++_bfd_elf_link_hide_sym_by_version (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h) ++{ ++ const char *p; ++ bool hide = false; ++ const struct elf_backend_data *bed ++ = get_elf_backend_data (info->output_bfd); ++ ++ /* Version script only hides symbols defined in regular objects. */ ++ if (!h->def_regular && !ELF_COMMON_DEF_P (h)) ++ return true; ++ ++ p = strchr (h->root.root.string, ELF_VER_CHR); ++ if (p != NULL && h->verinfo.vertree == NULL) ++ { ++ struct bfd_elf_version_tree *t; ++ ++ ++p; ++ if (*p == ELF_VER_CHR) ++ ++p; ++ ++ if (*p != '\0' ++ && _bfd_elf_link_hide_versioned_symbol (info, h, p, &t, &hide) ++ && hide) ++ { ++ if (hide) ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ return true; ++ } ++ } ++ ++ /* If we don't have a version for this symbol, see if we can find ++ something. */ ++ if (h->verinfo.vertree == NULL && info->version_info != NULL) ++ { ++ h->verinfo.vertree ++ = bfd_find_version_for_sym (info->version_info, ++ h->root.root.string, &hide); ++ if (h->verinfo.vertree != NULL && hide) ++ { ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++/* Figure out appropriate versions for all the symbols. We may not ++ have the version number script until we have read all of the input ++ files, so until that point we don't know which symbols should be ++ local. This function is called via elf_link_hash_traverse. */ ++ ++static bool ++_bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) ++{ ++ struct elf_info_failed *sinfo; ++ struct bfd_link_info *info; ++ const struct elf_backend_data *bed; ++ struct elf_info_failed eif; ++ char *p; ++ bool hide; ++ ++ sinfo = (struct elf_info_failed *) data; ++ info = sinfo->info; ++ ++ /* Fix the symbol flags. */ ++ eif.failed = false; ++ eif.info = info; ++ if (! _bfd_elf_fix_symbol_flags (h, &eif)) ++ { ++ if (eif.failed) ++ sinfo->failed = true; ++ return false; ++ } ++ ++ bed = get_elf_backend_data (info->output_bfd); ++ ++ /* We only need version numbers for symbols defined in regular ++ objects. */ ++ if (!h->def_regular && !ELF_COMMON_DEF_P (h)) ++ { ++ /* Hide symbols defined in discarded input sections. */ ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && discarded_section (h->root.u.def.section)) ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ return true; ++ } ++ ++ hide = false; ++ p = strchr (h->root.root.string, ELF_VER_CHR); ++ if (p != NULL && h->verinfo.vertree == NULL) ++ { ++ struct bfd_elf_version_tree *t; ++ ++ ++p; ++ if (*p == ELF_VER_CHR) ++ ++p; ++ ++ /* If there is no version string, we can just return out. */ ++ if (*p == '\0') ++ return true; ++ ++ if (!_bfd_elf_link_hide_versioned_symbol (info, h, p, &t, &hide)) ++ { ++ sinfo->failed = true; ++ return false; ++ } ++ ++ if (hide) ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ ++ /* If we are building an application, we need to create a ++ version node for this version. */ ++ if (t == NULL && bfd_link_executable (info)) ++ { ++ struct bfd_elf_version_tree **pp; ++ int version_index; ++ ++ /* If we aren't going to export this symbol, we don't need ++ to worry about it. */ ++ if (h->dynindx == -1) ++ return true; ++ ++ t = (struct bfd_elf_version_tree *) bfd_zalloc (info->output_bfd, ++ sizeof *t); ++ if (t == NULL) ++ { ++ sinfo->failed = true; ++ return false; ++ } ++ ++ t->name = p; ++ t->name_indx = (unsigned int) -1; ++ t->used = true; ++ ++ version_index = 1; ++ /* Don't count anonymous version tag. */ ++ if (sinfo->info->version_info != NULL ++ && sinfo->info->version_info->vernum == 0) ++ version_index = 0; ++ for (pp = &sinfo->info->version_info; ++ *pp != NULL; ++ pp = &(*pp)->next) ++ ++version_index; ++ t->vernum = version_index; ++ ++ *pp = t; ++ ++ h->verinfo.vertree = t; ++ } ++ else if (t == NULL) ++ { ++ /* We could not find the version for a symbol when ++ generating a shared archive. Return an error. */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: version node not found for symbol %s"), ++ info->output_bfd, h->root.root.string); ++ bfd_set_error (bfd_error_bad_value); ++ sinfo->failed = true; ++ return false; ++ } ++ } ++ ++ /* If we don't have a version for this symbol, see if we can find ++ something. */ ++ if (!hide ++ && h->verinfo.vertree == NULL ++ && sinfo->info->version_info != NULL) ++ { ++ h->verinfo.vertree ++ = bfd_find_version_for_sym (sinfo->info->version_info, ++ h->root.root.string, &hide); ++ if (h->verinfo.vertree != NULL && hide) ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ } ++ ++ return true; ++} ++ ++/* Read and swap the relocs from the section indicated by SHDR. This ++ may be either a REL or a RELA section. The relocations are ++ translated into RELA relocations and stored in INTERNAL_RELOCS, ++ which should have already been allocated to contain enough space. ++ The EXTERNAL_RELOCS are a buffer where the external form of the ++ relocations should be stored. ++ ++ Returns FALSE if something goes wrong. */ ++ ++static bool ++elf_link_read_relocs_from_section (bfd *abfd, ++ asection *sec, ++ Elf_Internal_Shdr *shdr, ++ void *external_relocs, ++ Elf_Internal_Rela *internal_relocs) ++{ ++ const struct elf_backend_data *bed; ++ void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++ const bfd_byte *erela; ++ const bfd_byte *erelaend; ++ Elf_Internal_Rela *irela; ++ Elf_Internal_Shdr *symtab_hdr; ++ size_t nsyms; ++ ++ /* Position ourselves at the start of the section. */ ++ if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0) ++ return false; ++ ++ /* Read the relocations. */ ++ if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size) ++ return false; ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ nsyms = NUM_SHDR_ENTRIES (symtab_hdr); ++ ++ bed = get_elf_backend_data (abfd); ++ ++ /* Convert the external relocations to the internal format. */ ++ if (shdr->sh_entsize == bed->s->sizeof_rel) ++ swap_in = bed->s->swap_reloc_in; ++ else if (shdr->sh_entsize == bed->s->sizeof_rela) ++ swap_in = bed->s->swap_reloca_in; ++ else ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ return false; ++ } ++ ++ erela = (const bfd_byte *) external_relocs; ++ /* Setting erelaend like this and comparing with <= handles case of ++ a fuzzed object with sh_size not a multiple of sh_entsize. */ ++ erelaend = erela + shdr->sh_size - shdr->sh_entsize; ++ irela = internal_relocs; ++ while (erela <= erelaend) ++ { ++ bfd_vma r_symndx; ++ ++ (*swap_in) (abfd, erela, irela); ++ r_symndx = ELF32_R_SYM (irela->r_info); ++ if (bed->s->arch_size == 64) ++ r_symndx >>= 24; ++ if (nsyms > 0) ++ { ++ if ((size_t) r_symndx >= nsyms) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: bad reloc symbol index (%#" PRIx64 " >= %#lx)" ++ " for offset %#" PRIx64 " in section `%pA'"), ++ abfd, (uint64_t) r_symndx, (unsigned long) nsyms, ++ (uint64_t) irela->r_offset, sec); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ } ++ else if (r_symndx != STN_UNDEF) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: non-zero symbol index (%#" PRIx64 ")" ++ " for offset %#" PRIx64 " in section `%pA'" ++ " when the object file has no symbol table"), ++ abfd, (uint64_t) r_symndx, ++ (uint64_t) irela->r_offset, sec); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ irela += bed->s->int_rels_per_ext_rel; ++ erela += shdr->sh_entsize; ++ } ++ ++ return true; ++} ++ ++/* Read and swap the relocs for a section O. They may have been ++ cached. If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are ++ not NULL, they are used as buffers to read into. They are known to ++ be large enough. If the INTERNAL_RELOCS relocs argument is NULL, ++ the return value is allocated using either malloc or bfd_alloc, ++ according to the KEEP_MEMORY argument. If O has two relocation ++ sections (both REL and RELA relocations), then the REL_HDR ++ relocations will appear first in INTERNAL_RELOCS, followed by the ++ RELA_HDR relocations. If INFO isn't NULL and KEEP_MEMORY is true, ++ update cache_size. */ ++ ++Elf_Internal_Rela * ++_bfd_elf_link_info_read_relocs (bfd *abfd, ++ struct bfd_link_info *info, ++ asection *o, ++ void *external_relocs, ++ Elf_Internal_Rela *internal_relocs, ++ bool keep_memory) ++{ ++ void *alloc1 = NULL; ++ Elf_Internal_Rela *alloc2 = NULL; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct bfd_elf_section_data *esdo = elf_section_data (o); ++ Elf_Internal_Rela *internal_rela_relocs; ++ ++ if (esdo->relocs != NULL) ++ return esdo->relocs; ++ ++ if (o->reloc_count == 0) ++ return NULL; ++ ++ if (internal_relocs == NULL) ++ { ++ bfd_size_type size; ++ ++ size = (bfd_size_type) o->reloc_count * sizeof (Elf_Internal_Rela); ++ if (keep_memory) ++ { ++ internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_alloc (abfd, size); ++ if (info) ++ info->cache_size += size; ++ } ++ else ++ internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size); ++ if (internal_relocs == NULL) ++ goto error_return; ++ } ++ ++ if (external_relocs == NULL) ++ { ++ bfd_size_type size = 0; ++ ++ if (esdo->rel.hdr) ++ size += esdo->rel.hdr->sh_size; ++ if (esdo->rela.hdr) ++ size += esdo->rela.hdr->sh_size; ++ ++ alloc1 = bfd_malloc (size); ++ if (alloc1 == NULL) ++ goto error_return; ++ external_relocs = alloc1; ++ } ++ ++ internal_rela_relocs = internal_relocs; ++ if (esdo->rel.hdr) ++ { ++ if (!elf_link_read_relocs_from_section (abfd, o, esdo->rel.hdr, ++ external_relocs, ++ internal_relocs)) ++ goto error_return; ++ external_relocs = (((bfd_byte *) external_relocs) ++ + esdo->rel.hdr->sh_size); ++ internal_rela_relocs += (NUM_SHDR_ENTRIES (esdo->rel.hdr) ++ * bed->s->int_rels_per_ext_rel); ++ } ++ ++ if (esdo->rela.hdr ++ && (!elf_link_read_relocs_from_section (abfd, o, esdo->rela.hdr, ++ external_relocs, ++ internal_rela_relocs))) ++ goto error_return; ++ ++ /* Cache the results for next time, if we can. */ ++ if (keep_memory) ++ esdo->relocs = internal_relocs; ++ ++ free (alloc1); ++ ++ /* Don't free alloc2, since if it was allocated we are passing it ++ back (under the name of internal_relocs). */ ++ ++ return internal_relocs; ++ ++ error_return: ++ free (alloc1); ++ if (alloc2 != NULL) ++ { ++ if (keep_memory) ++ bfd_release (abfd, alloc2); ++ else ++ free (alloc2); ++ } ++ return NULL; ++} ++ ++/* This is similar to _bfd_elf_link_info_read_relocs, except for that ++ NULL is passed to _bfd_elf_link_info_read_relocs for pointer to ++ struct bfd_link_info. */ ++ ++Elf_Internal_Rela * ++_bfd_elf_link_read_relocs (bfd *abfd, ++ asection *o, ++ void *external_relocs, ++ Elf_Internal_Rela *internal_relocs, ++ bool keep_memory) ++{ ++ return _bfd_elf_link_info_read_relocs (abfd, NULL, o, external_relocs, ++ internal_relocs, keep_memory); ++ ++} ++ ++/* Compute the size of, and allocate space for, REL_HDR which is the ++ section header for a section containing relocations for O. */ ++ ++static bool ++_bfd_elf_link_size_reloc_section (bfd *abfd, ++ struct bfd_elf_section_reloc_data *reldata) ++{ ++ Elf_Internal_Shdr *rel_hdr = reldata->hdr; ++ ++ /* That allows us to calculate the size of the section. */ ++ rel_hdr->sh_size = rel_hdr->sh_entsize * reldata->count; ++ ++ /* The contents field must last into write_object_contents, so we ++ allocate it with bfd_alloc rather than malloc. Also since we ++ cannot be sure that the contents will actually be filled in, ++ we zero the allocated space. */ ++ rel_hdr->contents = (unsigned char *) bfd_zalloc (abfd, rel_hdr->sh_size); ++ if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0) ++ return false; ++ ++ if (reldata->hashes == NULL && reldata->count) ++ { ++ struct elf_link_hash_entry **p; ++ ++ p = ((struct elf_link_hash_entry **) ++ bfd_zmalloc (reldata->count * sizeof (*p))); ++ if (p == NULL) ++ return false; ++ ++ reldata->hashes = p; ++ } ++ ++ return true; ++} ++ ++/* Copy the relocations indicated by the INTERNAL_RELOCS (which ++ originated from the section given by INPUT_REL_HDR) to the ++ OUTPUT_BFD. */ ++ ++bool ++_bfd_elf_link_output_relocs (bfd *output_bfd, ++ asection *input_section, ++ Elf_Internal_Shdr *input_rel_hdr, ++ Elf_Internal_Rela *internal_relocs, ++ struct elf_link_hash_entry **rel_hash ++ ATTRIBUTE_UNUSED) ++{ ++ Elf_Internal_Rela *irela; ++ Elf_Internal_Rela *irelaend; ++ bfd_byte *erel; ++ struct bfd_elf_section_reloc_data *output_reldata; ++ asection *output_section; ++ const struct elf_backend_data *bed; ++ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++ struct bfd_elf_section_data *esdo; ++ ++ output_section = input_section->output_section; ++ ++ bed = get_elf_backend_data (output_bfd); ++ esdo = elf_section_data (output_section); ++ if (esdo->rel.hdr && esdo->rel.hdr->sh_entsize == input_rel_hdr->sh_entsize) ++ { ++ output_reldata = &esdo->rel; ++ swap_out = bed->s->swap_reloc_out; ++ } ++ else if (esdo->rela.hdr ++ && esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize) ++ { ++ output_reldata = &esdo->rela; ++ swap_out = bed->s->swap_reloca_out; ++ } ++ else ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: relocation size mismatch in %pB section %pA"), ++ output_bfd, input_section->owner, input_section); ++ bfd_set_error (bfd_error_wrong_format); ++ return false; ++ } ++ ++ erel = output_reldata->hdr->contents; ++ erel += output_reldata->count * input_rel_hdr->sh_entsize; ++ irela = internal_relocs; ++ irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) ++ * bed->s->int_rels_per_ext_rel); ++ while (irela < irelaend) ++ { ++ (*swap_out) (output_bfd, irela, erel); ++ irela += bed->s->int_rels_per_ext_rel; ++ erel += input_rel_hdr->sh_entsize; ++ } ++ ++ /* Bump the counter, so that we know where to add the next set of ++ relocations. */ ++ output_reldata->count += NUM_SHDR_ENTRIES (input_rel_hdr); ++ ++ return true; ++} ++ ++/* Make weak undefined symbols in PIE dynamic. */ ++ ++bool ++_bfd_elf_link_hash_fixup_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h) ++{ ++ if (bfd_link_pie (info) ++ && h->dynindx == -1 ++ && h->root.type == bfd_link_hash_undefweak) ++ return bfd_elf_link_record_dynamic_symbol (info, h); ++ ++ return true; ++} ++ ++/* Fix up the flags for a symbol. This handles various cases which ++ can only be fixed after all the input files are seen. This is ++ currently called by both adjust_dynamic_symbol and ++ assign_sym_version, which is unnecessary but perhaps more robust in ++ the face of future changes. */ ++ ++static bool ++_bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, ++ struct elf_info_failed *eif) ++{ ++ const struct elf_backend_data *bed; ++ ++ /* If this symbol was mentioned in a non-ELF file, try to set ++ DEF_REGULAR and REF_REGULAR correctly. This is the only way to ++ permit a non-ELF file to correctly refer to a symbol defined in ++ an ELF dynamic object. */ ++ if (h->non_elf) ++ { ++ while (h->root.type == bfd_link_hash_indirect) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if (h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak) ++ { ++ h->ref_regular = 1; ++ h->ref_regular_nonweak = 1; ++ } ++ else ++ { ++ if (h->root.u.def.section->owner != NULL ++ && (bfd_get_flavour (h->root.u.def.section->owner) ++ == bfd_target_elf_flavour)) ++ { ++ h->ref_regular = 1; ++ h->ref_regular_nonweak = 1; ++ } ++ else ++ h->def_regular = 1; ++ } ++ ++ if (h->dynindx == -1 ++ && (h->def_dynamic ++ || h->ref_dynamic)) ++ { ++ if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) ++ { ++ eif->failed = true; ++ return false; ++ } ++ } ++ } ++ else ++ { ++ /* Unfortunately, NON_ELF is only correct if the symbol ++ was first seen in a non-ELF file. Fortunately, if the symbol ++ was first seen in an ELF file, we're probably OK unless the ++ symbol was defined in a non-ELF file. Catch that case here. ++ FIXME: We're still in trouble if the symbol was first seen in ++ a dynamic object, and then later in a non-ELF regular object. */ ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && !h->def_regular ++ && (h->root.u.def.section->owner != NULL ++ ? (bfd_get_flavour (h->root.u.def.section->owner) ++ != bfd_target_elf_flavour) ++ : (bfd_is_abs_section (h->root.u.def.section) ++ && !h->def_dynamic))) ++ h->def_regular = 1; ++ } ++ ++ /* Backend specific symbol fixup. */ ++ bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); ++ if (bed->elf_backend_fixup_symbol ++ && !(*bed->elf_backend_fixup_symbol) (eif->info, h)) ++ return false; ++ ++ /* If this is a final link, and the symbol was defined as a common ++ symbol in a regular object file, and there was no definition in ++ any dynamic object, then the linker will have allocated space for ++ the symbol in a common section but the DEF_REGULAR ++ flag will not have been set. */ ++ if (h->root.type == bfd_link_hash_defined ++ && !h->def_regular ++ && h->ref_regular ++ && !h->def_dynamic ++ && (h->root.u.def.section->owner->flags & (DYNAMIC | BFD_PLUGIN)) == 0) ++ h->def_regular = 1; ++ ++ /* Symbols defined in discarded sections shouldn't be dynamic. */ ++ if (h->root.type == bfd_link_hash_undefined && h->indx == -3) ++ (*bed->elf_backend_hide_symbol) (eif->info, h, true); ++ ++ /* If a weak undefined symbol has non-default visibility, we also ++ hide it from the dynamic linker. */ ++ else if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT ++ && h->root.type == bfd_link_hash_undefweak) ++ (*bed->elf_backend_hide_symbol) (eif->info, h, true); ++ ++ /* A hidden versioned symbol in executable should be forced local if ++ it is is locally defined, not referenced by shared library and not ++ exported. */ ++ else if (bfd_link_executable (eif->info) ++ && h->versioned == versioned_hidden ++ && !eif->info->export_dynamic ++ && !h->dynamic ++ && !h->ref_dynamic ++ && h->def_regular) ++ (*bed->elf_backend_hide_symbol) (eif->info, h, true); ++ ++ /* If -Bsymbolic was used (which means to bind references to global ++ symbols to the definition within the shared object), and this ++ symbol was defined in a regular object, then it actually doesn't ++ need a PLT entry. Likewise, if the symbol has non-default ++ visibility. If the symbol has hidden or internal visibility, we ++ will force it local. */ ++ else if (h->needs_plt ++ && bfd_link_pic (eif->info) ++ && is_elf_hash_table (eif->info->hash) ++ && (SYMBOLIC_BIND (eif->info, h) ++ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) ++ && h->def_regular) ++ { ++ bool force_local; ++ ++ force_local = (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL ++ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN); ++ (*bed->elf_backend_hide_symbol) (eif->info, h, force_local); ++ } ++ ++ /* If this is a weak defined symbol in a dynamic object, and we know ++ the real definition in the dynamic object, copy interesting flags ++ over to the real definition. */ ++ if (h->is_weakalias) ++ { ++ struct elf_link_hash_entry *def = weakdef (h); ++ ++ /* If the real definition is defined by a regular object file, ++ don't do anything special. See the longer description in ++ _bfd_elf_adjust_dynamic_symbol, below. If the def is not ++ bfd_link_hash_defined as it was when put on the alias list ++ then it must have originally been a versioned symbol (for ++ which a non-versioned indirect symbol is created) and later ++ a definition for the non-versioned symbol is found. In that ++ case the indirection is flipped with the versioned symbol ++ becoming an indirect pointing at the non-versioned symbol. ++ Thus, not an alias any more. */ ++ if (def->def_regular ++ || def->root.type != bfd_link_hash_defined) ++ { ++ h = def; ++ while ((h = h->u.alias) != def) ++ h->is_weakalias = 0; ++ } ++ else ++ { ++ while (h->root.type == bfd_link_hash_indirect) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ BFD_ASSERT (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak); ++ BFD_ASSERT (def->def_dynamic); ++ (*bed->elf_backend_copy_indirect_symbol) (eif->info, def, h); ++ } ++ } ++ ++ return true; ++} ++ ++/* Make the backend pick a good value for a dynamic symbol. This is ++ called via elf_link_hash_traverse, and also calls itself ++ recursively. */ ++ ++static bool ++_bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data) ++{ ++ struct elf_info_failed *eif = (struct elf_info_failed *) data; ++ struct elf_link_hash_table *htab; ++ const struct elf_backend_data *bed; ++ ++ if (! is_elf_hash_table (eif->info->hash)) ++ return false; ++ ++ /* Ignore indirect symbols. These are added by the versioning code. */ ++ if (h->root.type == bfd_link_hash_indirect) ++ return true; ++ ++ /* Fix the symbol flags. */ ++ if (! _bfd_elf_fix_symbol_flags (h, eif)) ++ return false; ++ ++ htab = elf_hash_table (eif->info); ++ bed = get_elf_backend_data (htab->dynobj); ++ ++ if (h->root.type == bfd_link_hash_undefweak) ++ { ++ if (eif->info->dynamic_undefined_weak == 0) ++ (*bed->elf_backend_hide_symbol) (eif->info, h, true); ++ else if (eif->info->dynamic_undefined_weak > 0 ++ && h->ref_regular ++ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT ++ && !bfd_hide_sym_by_version (eif->info->version_info, ++ h->root.root.string)) ++ { ++ if (!bfd_elf_link_record_dynamic_symbol (eif->info, h)) ++ { ++ eif->failed = true; ++ return false; ++ } ++ } ++ } ++ ++ /* If this symbol does not require a PLT entry, and it is not ++ defined by a dynamic object, or is not referenced by a regular ++ object, ignore it. We do have to handle a weak defined symbol, ++ even if no regular object refers to it, if we decided to add it ++ to the dynamic symbol table. FIXME: Do we normally need to worry ++ about symbols which are defined by one dynamic object and ++ referenced by another one? */ ++ if (!h->needs_plt ++ && h->type != STT_GNU_IFUNC ++ && (h->def_regular ++ || !h->def_dynamic ++ || (!h->ref_regular ++ && (!h->is_weakalias || weakdef (h)->dynindx == -1)))) ++ { ++ h->plt = elf_hash_table (eif->info)->init_plt_offset; ++ return true; ++ } ++ ++ /* If we've already adjusted this symbol, don't do it again. This ++ can happen via a recursive call. */ ++ if (h->dynamic_adjusted) ++ return true; ++ ++ /* Don't look at this symbol again. Note that we must set this ++ after checking the above conditions, because we may look at a ++ symbol once, decide not to do anything, and then get called ++ recursively later after REF_REGULAR is set below. */ ++ h->dynamic_adjusted = 1; ++ ++ /* If this is a weak definition, and we know a real definition, and ++ the real symbol is not itself defined by a regular object file, ++ then get a good value for the real definition. We handle the ++ real symbol first, for the convenience of the backend routine. ++ ++ Note that there is a confusing case here. If the real definition ++ is defined by a regular object file, we don't get the real symbol ++ from the dynamic object, but we do get the weak symbol. If the ++ processor backend uses a COPY reloc, then if some routine in the ++ dynamic object changes the real symbol, we will not see that ++ change in the corresponding weak symbol. This is the way other ++ ELF linkers work as well, and seems to be a result of the shared ++ library model. ++ ++ I will clarify this issue. Most SVR4 shared libraries define the ++ variable _timezone and define timezone as a weak synonym. The ++ tzset call changes _timezone. If you write ++ extern int timezone; ++ int _timezone = 5; ++ int main () { tzset (); printf ("%d %d\n", timezone, _timezone); } ++ you might expect that, since timezone is a synonym for _timezone, ++ the same number will print both times. However, if the processor ++ backend uses a COPY reloc, then actually timezone will be copied ++ into your process image, and, since you define _timezone ++ yourself, _timezone will not. Thus timezone and _timezone will ++ wind up at different memory locations. The tzset call will set ++ _timezone, leaving timezone unchanged. */ ++ ++ if (h->is_weakalias) ++ { ++ struct elf_link_hash_entry *def = weakdef (h); ++ ++ /* If we get to this point, there is an implicit reference to ++ the alias by a regular object file via the weak symbol H. */ ++ def->ref_regular = 1; ++ ++ /* Ensure that the backend adjust_dynamic_symbol function sees ++ the strong alias before H by recursively calling ourselves. */ ++ if (!_bfd_elf_adjust_dynamic_symbol (def, eif)) ++ return false; ++ } ++ ++ /* If a symbol has no type and no size and does not require a PLT ++ entry, then we are probably about to do the wrong thing here: we ++ are probably going to create a COPY reloc for an empty object. ++ This case can arise when a shared object is built with assembly ++ code, and the assembly code fails to set the symbol type. */ ++ if (h->size == 0 ++ && h->type == STT_NOTYPE ++ && !h->needs_plt) ++ _bfd_error_handler ++ (_("warning: type and size of dynamic symbol `%s' are not defined"), ++ h->root.root.string); ++ ++ if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h)) ++ { ++ eif->failed = true; ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Adjust the dynamic symbol, H, for copy in the dynamic bss section, ++ DYNBSS. */ ++ ++bool ++_bfd_elf_adjust_dynamic_copy (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, ++ asection *dynbss) ++{ ++ unsigned int power_of_two; ++ bfd_vma mask; ++ asection *sec = h->root.u.def.section; ++ ++ /* The section alignment of the definition is the maximum alignment ++ requirement of symbols defined in the section. Since we don't ++ know the symbol alignment requirement, we start with the ++ maximum alignment and check low bits of the symbol address ++ for the minimum alignment. */ ++ power_of_two = bfd_section_alignment (sec); ++ mask = ((bfd_vma) 1 << power_of_two) - 1; ++ while ((h->root.u.def.value & mask) != 0) ++ { ++ mask >>= 1; ++ --power_of_two; ++ } ++ ++ if (power_of_two > bfd_section_alignment (dynbss)) ++ { ++ /* Adjust the section alignment if needed. */ ++ if (!bfd_set_section_alignment (dynbss, power_of_two)) ++ return false; ++ } ++ ++ /* We make sure that the symbol will be aligned properly. */ ++ dynbss->size = BFD_ALIGN (dynbss->size, mask + 1); ++ ++ /* Define the symbol as being at this point in DYNBSS. */ ++ h->root.u.def.section = dynbss; ++ h->root.u.def.value = dynbss->size; ++ ++ /* Increment the size of DYNBSS to make room for the symbol. */ ++ dynbss->size += h->size; ++ ++ /* No error if extern_protected_data is true. */ ++ if (h->protected_def ++ && (!info->extern_protected_data ++ || (info->extern_protected_data < 0 ++ && !get_elf_backend_data (dynbss->owner)->extern_protected_data))) ++ info->callbacks->einfo ++ (_("%P: copy reloc against protected `%pT' is dangerous\n"), ++ h->root.root.string); ++ ++ return true; ++} ++ ++/* Adjust all external symbols pointing into SEC_MERGE sections ++ to reflect the object merging within the sections. */ ++ ++static bool ++_bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data) ++{ ++ asection *sec; ++ ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && ((sec = h->root.u.def.section)->flags & SEC_MERGE) ++ && sec->sec_info_type == SEC_INFO_TYPE_MERGE) ++ { ++ bfd *output_bfd = (bfd *) data; ++ ++ h->root.u.def.value = ++ _bfd_merged_section_offset (output_bfd, ++ &h->root.u.def.section, ++ elf_section_data (sec)->sec_info, ++ h->root.u.def.value); ++ } ++ ++ return true; ++} ++ ++/* Returns false if the symbol referred to by H should be considered ++ to resolve local to the current module, and true if it should be ++ considered to bind dynamically. */ ++ ++bool ++_bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h, ++ struct bfd_link_info *info, ++ bool not_local_protected) ++{ ++ bool binding_stays_local_p; ++ const struct elf_backend_data *bed; ++ struct elf_link_hash_table *hash_table; ++ ++ if (h == NULL) ++ return false; ++ ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ /* If it was forced local, then clearly it's not dynamic. */ ++ if (h->dynindx == -1) ++ return false; ++ if (h->forced_local) ++ return false; ++ ++ /* Identify the cases where name binding rules say that a ++ visible symbol resolves locally. */ ++ binding_stays_local_p = (bfd_link_executable (info) ++ || SYMBOLIC_BIND (info, h)); ++ ++ switch (ELF_ST_VISIBILITY (h->other)) ++ { ++ case STV_INTERNAL: ++ case STV_HIDDEN: ++ return false; ++ ++ case STV_PROTECTED: ++ hash_table = elf_hash_table (info); ++ if (!is_elf_hash_table (&hash_table->root)) ++ return false; ++ ++ bed = get_elf_backend_data (hash_table->dynobj); ++ ++ /* Proper resolution for function pointer equality may require ++ that these symbols perhaps be resolved dynamically, even though ++ we should be resolving them to the current module. */ ++ if (!not_local_protected || !bed->is_function_type (h->type)) ++ binding_stays_local_p = true; ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* If it isn't defined locally, then clearly it's dynamic. */ ++ if (!h->def_regular && !ELF_COMMON_DEF_P (h)) ++ return true; ++ ++ /* Otherwise, the symbol is dynamic if binding rules don't tell ++ us that it remains local. */ ++ return !binding_stays_local_p; ++} ++ ++/* Return true if the symbol referred to by H should be considered ++ to resolve local to the current module, and false otherwise. Differs ++ from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of ++ undefined symbols. The two functions are virtually identical except ++ for the place where dynindx == -1 is tested. If that test is true, ++ _bfd_elf_dynamic_symbol_p will say the symbol is local, while ++ _bfd_elf_symbol_refs_local_p will say the symbol is local only for ++ defined symbols. ++ It might seem that _bfd_elf_dynamic_symbol_p could be rewritten as ++ !_bfd_elf_symbol_refs_local_p, except that targets differ in their ++ treatment of undefined weak symbols. For those that do not make ++ undefined weak symbols dynamic, both functions may return false. */ ++ ++bool ++_bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h, ++ struct bfd_link_info *info, ++ bool local_protected) ++{ ++ const struct elf_backend_data *bed; ++ struct elf_link_hash_table *hash_table; ++ ++ /* If it's a local sym, of course we resolve locally. */ ++ if (h == NULL) ++ return true; ++ ++ /* STV_HIDDEN or STV_INTERNAL ones must be local. */ ++ if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN ++ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL) ++ return true; ++ ++ /* Forced local symbols resolve locally. */ ++ if (h->forced_local) ++ return true; ++ ++ /* Common symbols that become definitions don't get the DEF_REGULAR ++ flag set, so test it first, and don't bail out. */ ++ if (ELF_COMMON_DEF_P (h)) ++ /* Do nothing. */; ++ /* If we don't have a definition in a regular file, then we can't ++ resolve locally. The sym is either undefined or dynamic. */ ++ else if (!h->def_regular) ++ return false; ++ ++ /* Non-dynamic symbols resolve locally. */ ++ if (h->dynindx == -1) ++ return true; ++ ++ /* At this point, we know the symbol is defined and dynamic. In an ++ executable it must resolve locally, likewise when building symbolic ++ shared libraries. */ ++ if (bfd_link_executable (info) || SYMBOLIC_BIND (info, h)) ++ return true; ++ ++ /* Now deal with defined dynamic symbols in shared libraries. Ones ++ with default visibility might not resolve locally. */ ++ if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ++ return false; ++ ++ hash_table = elf_hash_table (info); ++ if (!is_elf_hash_table (&hash_table->root)) ++ return true; ++ ++ /* STV_PROTECTED symbols with indirect external access are local. */ ++ if (info->indirect_extern_access > 0) ++ return true; ++ ++ bed = get_elf_backend_data (hash_table->dynobj); ++ ++ /* If extern_protected_data is false, STV_PROTECTED non-function ++ symbols are local. */ ++ if ((!info->extern_protected_data ++ || (info->extern_protected_data < 0 ++ && !bed->extern_protected_data)) ++ && !bed->is_function_type (h->type)) ++ return true; ++ ++ /* Function pointer equality tests may require that STV_PROTECTED ++ symbols be treated as dynamic symbols. If the address of a ++ function not defined in an executable is set to that function's ++ plt entry in the executable, then the address of the function in ++ a shared library must also be the plt entry in the executable. */ ++ return local_protected; ++} ++ ++/* Caches some TLS segment info, and ensures that the TLS segment vma is ++ aligned. Returns the first TLS output section. */ ++ ++struct bfd_section * ++_bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info) ++{ ++ struct bfd_section *sec, *tls; ++ unsigned int align = 0; ++ ++ for (sec = obfd->sections; sec != NULL; sec = sec->next) ++ if ((sec->flags & SEC_THREAD_LOCAL) != 0) ++ break; ++ tls = sec; ++ ++ for (; sec != NULL && (sec->flags & SEC_THREAD_LOCAL) != 0; sec = sec->next) ++ if (sec->alignment_power > align) ++ align = sec->alignment_power; ++ ++ elf_hash_table (info)->tls_sec = tls; ++ ++ /* Ensure the alignment of the first section (usually .tdata) is the largest ++ alignment, so that the tls segment starts aligned. */ ++ if (tls != NULL) ++ tls->alignment_power = align; ++ ++ return tls; ++} ++ ++/* Return TRUE iff this is a non-common, definition of a non-function symbol. */ ++static bool ++is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED, ++ Elf_Internal_Sym *sym) ++{ ++ const struct elf_backend_data *bed; ++ ++ /* Local symbols do not count, but target specific ones might. */ ++ if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL ++ && ELF_ST_BIND (sym->st_info) < STB_LOOS) ++ return false; ++ ++ bed = get_elf_backend_data (abfd); ++ /* Function symbols do not count. */ ++ if (bed->is_function_type (ELF_ST_TYPE (sym->st_info))) ++ return false; ++ ++ /* If the section is undefined, then so is the symbol. */ ++ if (sym->st_shndx == SHN_UNDEF) ++ return false; ++ ++ /* If the symbol is defined in the common section, then ++ it is a common definition and so does not count. */ ++ if (bed->common_definition (sym)) ++ return false; ++ ++ /* If the symbol is in a target specific section then we ++ must rely upon the backend to tell us what it is. */ ++ if (sym->st_shndx >= SHN_LORESERVE && sym->st_shndx < SHN_ABS) ++ /* FIXME - this function is not coded yet: ++ ++ return _bfd_is_global_symbol_definition (abfd, sym); ++ ++ Instead for now assume that the definition is not global, ++ Even if this is wrong, at least the linker will behave ++ in the same way that it used to do. */ ++ return false; ++ ++ return true; ++} ++ ++/* Search the symbol table of the archive element of the archive ABFD ++ whose archive map contains a mention of SYMDEF, and determine if ++ the symbol is defined in this element. */ ++static bool ++elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) ++{ ++ Elf_Internal_Shdr * hdr; ++ size_t symcount; ++ size_t extsymcount; ++ size_t extsymoff; ++ Elf_Internal_Sym *isymbuf; ++ Elf_Internal_Sym *isym; ++ Elf_Internal_Sym *isymend; ++ bool result; ++ ++ abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset, NULL); ++ if (abfd == NULL) ++ return false; ++ ++ if (! bfd_check_format (abfd, bfd_object)) ++ return false; ++ ++ if (elf_use_dt_symtab_p (abfd)) ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ return false; ++ } ++ ++ /* Select the appropriate symbol table. If we don't know if the ++ object file is an IR object, give linker LTO plugin a chance to ++ get the correct symbol table. */ ++ if (abfd->plugin_format == bfd_plugin_yes ++#if BFD_SUPPORTS_PLUGINS ++ || (abfd->plugin_format == bfd_plugin_unknown ++ && bfd_link_plugin_object_p (abfd)) ++#endif ++ ) ++ { ++ /* Use the IR symbol table if the object has been claimed by ++ plugin. */ ++ abfd = abfd->plugin_dummy_bfd; ++ hdr = &elf_tdata (abfd)->symtab_hdr; ++ } ++ else if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0) ++ hdr = &elf_tdata (abfd)->symtab_hdr; ++ else ++ hdr = &elf_tdata (abfd)->dynsymtab_hdr; ++ ++ symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; ++ ++ /* The sh_info field of the symtab header tells us where the ++ external symbols start. We don't care about the local symbols. */ ++ if (elf_bad_symtab (abfd)) ++ { ++ extsymcount = symcount; ++ extsymoff = 0; ++ } ++ else ++ { ++ extsymcount = symcount - hdr->sh_info; ++ extsymoff = hdr->sh_info; ++ } ++ ++ if (extsymcount == 0) ++ return false; ++ ++ /* Read in the symbol table. */ ++ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, ++ NULL, NULL, NULL); ++ if (isymbuf == NULL) ++ return false; ++ ++ /* Scan the symbol table looking for SYMDEF. */ ++ result = false; ++ for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++) ++ { ++ const char *name; ++ ++ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, ++ isym->st_name); ++ if (name == NULL) ++ break; ++ ++ if (strcmp (name, symdef->name) == 0) ++ { ++ result = is_global_data_symbol_definition (abfd, isym); ++ break; ++ } ++ } ++ ++ free (isymbuf); ++ ++ return result; ++} ++ ++/* Add an entry to the .dynamic table. */ ++ ++bool ++_bfd_elf_add_dynamic_entry (struct bfd_link_info *info, ++ bfd_vma tag, ++ bfd_vma val) ++{ ++ struct elf_link_hash_table *hash_table; ++ const struct elf_backend_data *bed; ++ asection *s; ++ bfd_size_type newsize; ++ bfd_byte *newcontents; ++ Elf_Internal_Dyn dyn; ++ ++ hash_table = elf_hash_table (info); ++ if (! is_elf_hash_table (&hash_table->root)) ++ return false; ++ ++ if (tag == DT_RELA || tag == DT_REL) ++ hash_table->dynamic_relocs = true; ++ ++ bed = get_elf_backend_data (hash_table->dynobj); ++ s = bfd_get_linker_section (hash_table->dynobj, ".dynamic"); ++ BFD_ASSERT (s != NULL); ++ ++ newsize = s->size + bed->s->sizeof_dyn; ++ newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize); ++ if (newcontents == NULL) ++ return false; ++ ++ dyn.d_tag = tag; ++ dyn.d_un.d_val = val; ++ bed->s->swap_dyn_out (hash_table->dynobj, &dyn, newcontents + s->size); ++ ++ s->size = newsize; ++ s->contents = newcontents; ++ ++ return true; ++} ++ ++/* Strip zero-sized dynamic sections. */ ++ ++bool ++_bfd_elf_strip_zero_sized_dynamic_sections (struct bfd_link_info *info) ++{ ++ struct elf_link_hash_table *hash_table; ++ const struct elf_backend_data *bed; ++ asection *s, *sdynamic, **pp; ++ asection *rela_dyn, *rel_dyn; ++ Elf_Internal_Dyn dyn; ++ bfd_byte *extdyn, *next; ++ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); ++ bool strip_zero_sized; ++ bool strip_zero_sized_plt; ++ ++ if (bfd_link_relocatable (info)) ++ return true; ++ ++ hash_table = elf_hash_table (info); ++ if (!is_elf_hash_table (&hash_table->root)) ++ return false; ++ ++ if (!hash_table->dynobj) ++ return true; ++ ++ sdynamic= bfd_get_linker_section (hash_table->dynobj, ".dynamic"); ++ if (!sdynamic) ++ return true; ++ ++ bed = get_elf_backend_data (hash_table->dynobj); ++ swap_dyn_in = bed->s->swap_dyn_in; ++ ++ strip_zero_sized = false; ++ strip_zero_sized_plt = false; ++ ++ /* Strip zero-sized dynamic sections. */ ++ rela_dyn = bfd_get_section_by_name (info->output_bfd, ".rela.dyn"); ++ rel_dyn = bfd_get_section_by_name (info->output_bfd, ".rel.dyn"); ++ for (pp = &info->output_bfd->sections; (s = *pp) != NULL;) ++ if (s->size == 0 ++ && (s == rela_dyn ++ || s == rel_dyn ++ || s == hash_table->srelplt->output_section ++ || s == hash_table->splt->output_section)) ++ { ++ *pp = s->next; ++ info->output_bfd->section_count--; ++ strip_zero_sized = true; ++ if (s == rela_dyn) ++ s = rela_dyn; ++ if (s == rel_dyn) ++ s = rel_dyn; ++ else if (s == hash_table->splt->output_section) ++ { ++ s = hash_table->splt; ++ strip_zero_sized_plt = true; ++ } ++ else ++ s = hash_table->srelplt; ++ s->flags |= SEC_EXCLUDE; ++ s->output_section = bfd_abs_section_ptr; ++ } ++ else ++ pp = &s->next; ++ ++ if (strip_zero_sized_plt && sdynamic->size != 0) ++ for (extdyn = sdynamic->contents; ++ extdyn < sdynamic->contents + sdynamic->size; ++ extdyn = next) ++ { ++ next = extdyn + bed->s->sizeof_dyn; ++ swap_dyn_in (hash_table->dynobj, extdyn, &dyn); ++ switch (dyn.d_tag) ++ { ++ default: ++ break; ++ case DT_JMPREL: ++ case DT_PLTRELSZ: ++ case DT_PLTREL: ++ /* Strip DT_PLTRELSZ, DT_JMPREL and DT_PLTREL entries if ++ the procedure linkage table (the .plt section) has been ++ removed. */ ++ memmove (extdyn, next, ++ sdynamic->size - (next - sdynamic->contents)); ++ next = extdyn; ++ } ++ } ++ ++ if (strip_zero_sized) ++ { ++ /* Regenerate program headers. */ ++ elf_seg_map (info->output_bfd) = NULL; ++ return _bfd_elf_map_sections_to_segments (info->output_bfd, info, ++ NULL); ++ } ++ ++ return true; ++} ++ ++/* Add a DT_NEEDED entry for this dynamic object. Returns -1 on error, ++ 1 if a DT_NEEDED tag already exists, and 0 on success. */ ++ ++int ++bfd_elf_add_dt_needed_tag (bfd *abfd, struct bfd_link_info *info) ++{ ++ struct elf_link_hash_table *hash_table; ++ size_t strindex; ++ const char *soname; ++ ++ if (!_bfd_elf_link_create_dynstrtab (abfd, info)) ++ return -1; ++ ++ hash_table = elf_hash_table (info); ++ soname = elf_dt_name (abfd); ++ strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, false); ++ if (strindex == (size_t) -1) ++ return -1; ++ ++ if (_bfd_elf_strtab_refcount (hash_table->dynstr, strindex) != 1) ++ { ++ asection *sdyn; ++ const struct elf_backend_data *bed; ++ bfd_byte *extdyn; ++ ++ bed = get_elf_backend_data (hash_table->dynobj); ++ sdyn = bfd_get_linker_section (hash_table->dynobj, ".dynamic"); ++ if (sdyn != NULL && sdyn->size != 0) ++ for (extdyn = sdyn->contents; ++ extdyn < sdyn->contents + sdyn->size; ++ extdyn += bed->s->sizeof_dyn) ++ { ++ Elf_Internal_Dyn dyn; ++ ++ bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn); ++ if (dyn.d_tag == DT_NEEDED ++ && dyn.d_un.d_val == strindex) ++ { ++ _bfd_elf_strtab_delref (hash_table->dynstr, strindex); ++ return 1; ++ } ++ } ++ } ++ ++ if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info)) ++ return -1; ++ ++ if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex)) ++ return -1; ++ ++ return 0; ++} ++ ++/* Return true if SONAME is on the needed list between NEEDED and STOP ++ (or the end of list if STOP is NULL), and needed by a library that ++ will be loaded. */ ++ ++static bool ++on_needed_list (const char *soname, ++ struct bfd_link_needed_list *needed, ++ struct bfd_link_needed_list *stop) ++{ ++ struct bfd_link_needed_list *look; ++ for (look = needed; look != stop; look = look->next) ++ if (strcmp (soname, look->name) == 0 ++ && ((elf_dyn_lib_class (look->by) & DYN_AS_NEEDED) == 0 ++ /* If needed by a library that itself is not directly ++ needed, recursively check whether that library is ++ indirectly needed. Since we add DT_NEEDED entries to ++ the end of the list, library dependencies appear after ++ the library. Therefore search prior to the current ++ LOOK, preventing possible infinite recursion. */ ++ || on_needed_list (elf_dt_name (look->by), needed, look))) ++ return true; ++ ++ return false; ++} ++ ++/* Sort symbol by value, section, size, and type. */ ++static int ++elf_sort_symbol (const void *arg1, const void *arg2) ++{ ++ const struct elf_link_hash_entry *h1; ++ const struct elf_link_hash_entry *h2; ++ bfd_signed_vma vdiff; ++ int sdiff; ++ const char *n1; ++ const char *n2; ++ ++ h1 = *(const struct elf_link_hash_entry **) arg1; ++ h2 = *(const struct elf_link_hash_entry **) arg2; ++ vdiff = h1->root.u.def.value - h2->root.u.def.value; ++ if (vdiff != 0) ++ return vdiff > 0 ? 1 : -1; ++ ++ sdiff = h1->root.u.def.section->id - h2->root.u.def.section->id; ++ if (sdiff != 0) ++ return sdiff; ++ ++ /* Sort so that sized symbols are selected over zero size symbols. */ ++ vdiff = h1->size - h2->size; ++ if (vdiff != 0) ++ return vdiff > 0 ? 1 : -1; ++ ++ /* Sort so that STT_OBJECT is selected over STT_NOTYPE. */ ++ if (h1->type != h2->type) ++ return h1->type - h2->type; ++ ++ /* If symbols are properly sized and typed, and multiple strong ++ aliases are not defined in a shared library by the user we ++ shouldn't get here. Unfortunately linker script symbols like ++ __bss_start sometimes match a user symbol defined at the start of ++ .bss without proper size and type. We'd like to preference the ++ user symbol over reserved system symbols. Sort on leading ++ underscores. */ ++ n1 = h1->root.root.string; ++ n2 = h2->root.root.string; ++ while (*n1 == *n2) ++ { ++ if (*n1 == 0) ++ break; ++ ++n1; ++ ++n2; ++ } ++ if (*n1 == '_') ++ return -1; ++ if (*n2 == '_') ++ return 1; ++ ++ /* Final sort on name selects user symbols like '_u' over reserved ++ system symbols like '_Z' and also will avoid qsort instability. */ ++ return *n1 - *n2; ++} ++ ++/* This function is used to adjust offsets into .dynstr for ++ dynamic symbols. This is called via elf_link_hash_traverse. */ ++ ++static bool ++elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data) ++{ ++ struct elf_strtab_hash *dynstr = (struct elf_strtab_hash *) data; ++ ++ if (h->dynindx != -1) ++ h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index); ++ return true; ++} ++ ++/* Assign string offsets in .dynstr, update all structures referencing ++ them. */ ++ ++static bool ++elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info) ++{ ++ struct elf_link_hash_table *hash_table = elf_hash_table (info); ++ struct elf_link_local_dynamic_entry *entry; ++ struct elf_strtab_hash *dynstr = hash_table->dynstr; ++ bfd *dynobj = hash_table->dynobj; ++ asection *sdyn; ++ bfd_size_type size; ++ const struct elf_backend_data *bed; ++ bfd_byte *extdyn; ++ ++ _bfd_elf_strtab_finalize (dynstr); ++ size = _bfd_elf_strtab_size (dynstr); ++ ++ /* Allow the linker to examine the dynsymtab now it's fully populated. */ ++ ++ if (info->callbacks->examine_strtab) ++ info->callbacks->examine_strtab (dynstr); ++ ++ bed = get_elf_backend_data (dynobj); ++ sdyn = bfd_get_linker_section (dynobj, ".dynamic"); ++ BFD_ASSERT (sdyn != NULL); ++ ++ /* Update all .dynamic entries referencing .dynstr strings. */ ++ for (extdyn = sdyn->contents; ++ extdyn < PTR_ADD (sdyn->contents, sdyn->size); ++ extdyn += bed->s->sizeof_dyn) ++ { ++ Elf_Internal_Dyn dyn; ++ ++ bed->s->swap_dyn_in (dynobj, extdyn, &dyn); ++ switch (dyn.d_tag) ++ { ++ case DT_STRSZ: ++ dyn.d_un.d_val = size; ++ break; ++ case DT_NEEDED: ++ case DT_SONAME: ++ case DT_RPATH: ++ case DT_RUNPATH: ++ case DT_FILTER: ++ case DT_AUXILIARY: ++ case DT_AUDIT: ++ case DT_DEPAUDIT: ++ dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val); ++ break; ++ default: ++ continue; ++ } ++ bed->s->swap_dyn_out (dynobj, &dyn, extdyn); ++ } ++ ++ /* Now update local dynamic symbols. */ ++ for (entry = hash_table->dynlocal; entry ; entry = entry->next) ++ entry->isym.st_name = _bfd_elf_strtab_offset (dynstr, ++ entry->isym.st_name); ++ ++ /* And the rest of dynamic symbols. */ ++ elf_link_hash_traverse (hash_table, elf_adjust_dynstr_offsets, dynstr); ++ ++ /* Adjust version definitions. */ ++ if (elf_tdata (output_bfd)->cverdefs) ++ { ++ asection *s; ++ bfd_byte *p; ++ size_t i; ++ Elf_Internal_Verdef def; ++ Elf_Internal_Verdaux defaux; ++ ++ s = bfd_get_linker_section (dynobj, ".gnu.version_d"); ++ p = s->contents; ++ do ++ { ++ _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p, ++ &def); ++ p += sizeof (Elf_External_Verdef); ++ if (def.vd_aux != sizeof (Elf_External_Verdef)) ++ continue; ++ for (i = 0; i < def.vd_cnt; ++i) ++ { ++ _bfd_elf_swap_verdaux_in (output_bfd, ++ (Elf_External_Verdaux *) p, &defaux); ++ defaux.vda_name = _bfd_elf_strtab_offset (dynstr, ++ defaux.vda_name); ++ _bfd_elf_swap_verdaux_out (output_bfd, ++ &defaux, (Elf_External_Verdaux *) p); ++ p += sizeof (Elf_External_Verdaux); ++ } ++ } ++ while (def.vd_next); ++ } ++ ++ /* Adjust version references. */ ++ if (elf_tdata (output_bfd)->verref) ++ { ++ asection *s; ++ bfd_byte *p; ++ size_t i; ++ Elf_Internal_Verneed need; ++ Elf_Internal_Vernaux needaux; ++ ++ s = bfd_get_linker_section (dynobj, ".gnu.version_r"); ++ p = s->contents; ++ do ++ { ++ _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p, ++ &need); ++ need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file); ++ _bfd_elf_swap_verneed_out (output_bfd, &need, ++ (Elf_External_Verneed *) p); ++ p += sizeof (Elf_External_Verneed); ++ for (i = 0; i < need.vn_cnt; ++i) ++ { ++ _bfd_elf_swap_vernaux_in (output_bfd, ++ (Elf_External_Vernaux *) p, &needaux); ++ needaux.vna_name = _bfd_elf_strtab_offset (dynstr, ++ needaux.vna_name); ++ _bfd_elf_swap_vernaux_out (output_bfd, ++ &needaux, ++ (Elf_External_Vernaux *) p); ++ p += sizeof (Elf_External_Vernaux); ++ } ++ } ++ while (need.vn_next); ++ } ++ ++ return true; ++} ++ ++/* Return TRUE iff relocations for INPUT are compatible with OUTPUT. ++ The default is to only match when the INPUT and OUTPUT are exactly ++ the same target. */ ++ ++bool ++_bfd_elf_default_relocs_compatible (const bfd_target *input, ++ const bfd_target *output) ++{ ++ return input == output; ++} ++ ++/* Return TRUE iff relocations for INPUT are compatible with OUTPUT. ++ This version is used when different targets for the same architecture ++ are virtually identical. */ ++ ++bool ++_bfd_elf_relocs_compatible (const bfd_target *input, ++ const bfd_target *output) ++{ ++ const struct elf_backend_data *obed, *ibed; ++ ++ if (input == output) ++ return true; ++ ++ ibed = xvec_get_elf_backend_data (input); ++ obed = xvec_get_elf_backend_data (output); ++ ++ if (ibed->arch != obed->arch) ++ return false; ++ ++ /* If both backends are using this function, deem them compatible. */ ++ return ibed->relocs_compatible == obed->relocs_compatible; ++} ++ ++/* Make a special call to the linker "notice" function to tell it that ++ we are about to handle an as-needed lib, or have finished ++ processing the lib. */ ++ ++bool ++_bfd_elf_notice_as_needed (bfd *ibfd, ++ struct bfd_link_info *info, ++ enum notice_asneeded_action act) ++{ ++ return (*info->callbacks->notice) (info, NULL, NULL, ibfd, NULL, act, 0); ++} ++ ++/* Call ACTION on each relocation in an ELF object file. */ ++ ++bool ++_bfd_elf_link_iterate_on_relocs ++ (bfd *abfd, struct bfd_link_info *info, ++ bool (*action) (bfd *, struct bfd_link_info *, asection *, ++ const Elf_Internal_Rela *)) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct elf_link_hash_table *htab = elf_hash_table (info); ++ ++ /* If this object is the same format as the output object, and it is ++ not a shared library, then let the backend look through the ++ relocs. ++ ++ This is required to build global offset table entries and to ++ arrange for dynamic relocs. It is not required for the ++ particular common case of linking non PIC code, even when linking ++ against shared libraries, but unfortunately there is no way of ++ knowing whether an object file has been compiled PIC or not. ++ Looking through the relocs is not particularly time consuming. ++ The problem is that we must either (1) keep the relocs in memory, ++ which causes the linker to require additional runtime memory or ++ (2) read the relocs twice from the input file, which wastes time. ++ This would be a good case for using mmap. ++ ++ I have no idea how to handle linking PIC code into a file of a ++ different format. It probably can't be done. */ ++ if ((abfd->flags & DYNAMIC) == 0 ++ && is_elf_hash_table (&htab->root) ++ && elf_object_id (abfd) == elf_hash_table_id (htab) ++ && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec)) ++ { ++ asection *o; ++ ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ Elf_Internal_Rela *internal_relocs; ++ bool ok; ++ ++ /* Don't check relocations in excluded sections. Don't do ++ anything special with non-loaded, non-alloced sections. ++ In particular, any relocs in such sections should not ++ affect GOT and PLT reference counting (ie. we don't ++ allow them to create GOT or PLT entries), there's no ++ possibility or desire to optimize TLS relocs, and ++ there's not much point in propagating relocs to shared ++ libs that the dynamic linker won't relocate. */ ++ if ((o->flags & SEC_ALLOC) == 0 ++ || (o->flags & SEC_RELOC) == 0 ++ || (o->flags & SEC_EXCLUDE) != 0 ++ || o->reloc_count == 0 ++ || ((info->strip == strip_all || info->strip == strip_debugger) ++ && (o->flags & SEC_DEBUGGING) != 0) ++ || bfd_is_abs_section (o->output_section)) ++ continue; ++ ++ internal_relocs = _bfd_elf_link_info_read_relocs (abfd, info, ++ o, NULL, ++ NULL, ++ _bfd_link_keep_memory (info)); ++ if (internal_relocs == NULL) ++ return false; ++ ++ ok = action (abfd, info, o, internal_relocs); ++ ++ if (elf_section_data (o)->relocs != internal_relocs) ++ free (internal_relocs); ++ ++ if (! ok) ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++/* Check relocations in an ELF object file. This is called after ++ all input files have been opened. */ ++ ++bool ++_bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ if (bed->check_relocs != NULL) ++ return _bfd_elf_link_iterate_on_relocs (abfd, info, ++ bed->check_relocs); ++ return true; ++} ++ ++/* Add symbols from an ELF object file to the linker hash table. */ ++ ++static bool ++elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) ++{ ++ Elf_Internal_Ehdr *ehdr; ++ Elf_Internal_Shdr *hdr; ++ size_t symcount; ++ size_t extsymcount; ++ size_t extsymoff; ++ struct elf_link_hash_entry **sym_hash; ++ bool dynamic; ++ Elf_External_Versym *extversym = NULL; ++ Elf_External_Versym *extversym_end = NULL; ++ Elf_External_Versym *ever; ++ struct elf_link_hash_entry *weaks; ++ struct elf_link_hash_entry **nondeflt_vers = NULL; ++ size_t nondeflt_vers_cnt = 0; ++ Elf_Internal_Sym *isymbuf = NULL; ++ Elf_Internal_Sym *isym; ++ Elf_Internal_Sym *isymend; ++ const struct elf_backend_data *bed; ++ bool add_needed; ++ struct elf_link_hash_table *htab; ++ void *alloc_mark = NULL; ++ struct bfd_hash_entry **old_table = NULL; ++ unsigned int old_size = 0; ++ unsigned int old_count = 0; ++ void *old_tab = NULL; ++ void *old_ent; ++ struct bfd_link_hash_entry *old_undefs = NULL; ++ struct bfd_link_hash_entry *old_undefs_tail = NULL; ++ void *old_strtab = NULL; ++ size_t tabsize = 0; ++ asection *s; ++ bool just_syms; ++ ++ htab = elf_hash_table (info); ++ bed = get_elf_backend_data (abfd); ++ ++ if (elf_use_dt_symtab_p (abfd)) ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ return false; ++ } ++ ++ if ((abfd->flags & DYNAMIC) == 0) ++ dynamic = false; ++ else ++ { ++ dynamic = true; ++ ++ /* You can't use -r against a dynamic object. Also, there's no ++ hope of using a dynamic object which does not exactly match ++ the format of the output file. */ ++ if (bfd_link_relocatable (info) ++ || !is_elf_hash_table (&htab->root) ++ || info->output_bfd->xvec != abfd->xvec) ++ { ++ if (bfd_link_relocatable (info)) ++ bfd_set_error (bfd_error_invalid_operation); ++ else ++ bfd_set_error (bfd_error_wrong_format); ++ goto error_return; ++ } ++ } ++ ++ ehdr = elf_elfheader (abfd); ++ if (info->warn_alternate_em ++ && bed->elf_machine_code != ehdr->e_machine ++ && ((bed->elf_machine_alt1 != 0 ++ && ehdr->e_machine == bed->elf_machine_alt1) ++ || (bed->elf_machine_alt2 != 0 ++ && ehdr->e_machine == bed->elf_machine_alt2))) ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("alternate ELF machine code found (%d) in %pB, expecting %d"), ++ ehdr->e_machine, abfd, bed->elf_machine_code); ++ ++ /* As a GNU extension, any input sections which are named ++ .gnu.warning.SYMBOL are treated as warning symbols for the given ++ symbol. This differs from .gnu.warning sections, which generate ++ warnings when they are included in an output file. */ ++ /* PR 12761: Also generate this warning when building shared libraries. */ ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ const char *name; ++ ++ name = bfd_section_name (s); ++ if (startswith (name, ".gnu.warning.")) ++ { ++ char *msg; ++ bfd_size_type sz; ++ ++ name += sizeof ".gnu.warning." - 1; ++ ++ /* If this is a shared object, then look up the symbol ++ in the hash table. If it is there, and it is already ++ been defined, then we will not be using the entry ++ from this shared object, so we don't need to warn. ++ FIXME: If we see the definition in a regular object ++ later on, we will warn, but we shouldn't. The only ++ fix is to keep track of what warnings we are supposed ++ to emit, and then handle them all at the end of the ++ link. */ ++ if (dynamic) ++ { ++ struct elf_link_hash_entry *h; ++ ++ h = elf_link_hash_lookup (htab, name, false, false, true); ++ ++ /* FIXME: What about bfd_link_hash_common? */ ++ if (h != NULL ++ && (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak)) ++ continue; ++ } ++ ++ sz = s->size; ++ msg = (char *) bfd_alloc (abfd, sz + 1); ++ if (msg == NULL) ++ goto error_return; ++ ++ if (! bfd_get_section_contents (abfd, s, msg, 0, sz)) ++ goto error_return; ++ ++ msg[sz] = '\0'; ++ ++ if (! (_bfd_generic_link_add_one_symbol ++ (info, abfd, name, BSF_WARNING, s, 0, msg, ++ false, bed->collect, NULL))) ++ goto error_return; ++ ++ if (bfd_link_executable (info)) ++ { ++ /* Clobber the section size so that the warning does ++ not get copied into the output file. */ ++ s->size = 0; ++ ++ /* Also set SEC_EXCLUDE, so that symbols defined in ++ the warning section don't get copied to the output. */ ++ s->flags |= SEC_EXCLUDE; ++ } ++ } ++ } ++ ++ just_syms = ((s = abfd->sections) != NULL ++ && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS); ++ ++ add_needed = true; ++ if (! dynamic) ++ { ++ /* If we are creating a shared library, create all the dynamic ++ sections immediately. We need to attach them to something, ++ so we attach them to this BFD, provided it is the right ++ format and is not from ld --just-symbols. Always create the ++ dynamic sections for -E/--dynamic-list. FIXME: If there ++ are no input BFD's of the same format as the output, we can't ++ make a shared library. */ ++ if (!just_syms ++ && (bfd_link_pic (info) ++ || (!bfd_link_relocatable (info) ++ && info->nointerp ++ && (info->export_dynamic || info->dynamic))) ++ && is_elf_hash_table (&htab->root) ++ && info->output_bfd->xvec == abfd->xvec ++ && !htab->dynamic_sections_created) ++ { ++ if (! _bfd_elf_link_create_dynamic_sections (abfd, info)) ++ goto error_return; ++ } ++ } ++ else if (!is_elf_hash_table (&htab->root)) ++ goto error_return; ++ else ++ { ++ const char *soname = NULL; ++ char *audit = NULL; ++ struct bfd_link_needed_list *rpath = NULL, *runpath = NULL; ++ const Elf_Internal_Phdr *phdr; ++ struct elf_link_loaded_list *loaded_lib; ++ ++ /* ld --just-symbols and dynamic objects don't mix very well. ++ ld shouldn't allow it. */ ++ if (just_syms) ++ abort (); ++ ++ /* If this dynamic lib was specified on the command line with ++ --as-needed in effect, then we don't want to add a DT_NEEDED ++ tag unless the lib is actually used. Similary for libs brought ++ in by another lib's DT_NEEDED. When --no-add-needed is used ++ on a dynamic lib, we don't want to add a DT_NEEDED entry for ++ any dynamic library in DT_NEEDED tags in the dynamic lib at ++ all. */ ++ add_needed = (elf_dyn_lib_class (abfd) ++ & (DYN_AS_NEEDED | DYN_DT_NEEDED ++ | DYN_NO_NEEDED)) == 0; ++ ++ s = bfd_get_section_by_name (abfd, ".dynamic"); ++ if (s != NULL && s->size != 0 && (s->flags & SEC_HAS_CONTENTS) != 0) ++ { ++ bfd_byte *dynbuf; ++ bfd_byte *extdyn; ++ unsigned int elfsec; ++ unsigned long shlink; ++ ++ if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) ++ { ++ error_free_dyn: ++ free (dynbuf); ++ goto error_return; ++ } ++ ++ elfsec = _bfd_elf_section_from_bfd_section (abfd, s); ++ if (elfsec == SHN_BAD) ++ goto error_free_dyn; ++ shlink = elf_elfsections (abfd)[elfsec]->sh_link; ++ ++ for (extdyn = dynbuf; ++ (size_t) (dynbuf + s->size - extdyn) >= bed->s->sizeof_dyn; ++ extdyn += bed->s->sizeof_dyn) ++ { ++ Elf_Internal_Dyn dyn; ++ ++ bed->s->swap_dyn_in (abfd, extdyn, &dyn); ++ if (dyn.d_tag == DT_SONAME) ++ { ++ unsigned int tagv = dyn.d_un.d_val; ++ soname = bfd_elf_string_from_elf_section (abfd, shlink, tagv); ++ if (soname == NULL) ++ goto error_free_dyn; ++ } ++ if (dyn.d_tag == DT_NEEDED) ++ { ++ struct bfd_link_needed_list *n, **pn; ++ char *fnm, *anm; ++ unsigned int tagv = dyn.d_un.d_val; ++ size_t amt = sizeof (struct bfd_link_needed_list); ++ ++ n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); ++ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); ++ if (n == NULL || fnm == NULL) ++ goto error_free_dyn; ++ amt = strlen (fnm) + 1; ++ anm = (char *) bfd_alloc (abfd, amt); ++ if (anm == NULL) ++ goto error_free_dyn; ++ memcpy (anm, fnm, amt); ++ n->name = anm; ++ n->by = abfd; ++ n->next = NULL; ++ for (pn = &htab->needed; *pn != NULL; pn = &(*pn)->next) ++ ; ++ *pn = n; ++ } ++ if (dyn.d_tag == DT_RUNPATH) ++ { ++ struct bfd_link_needed_list *n, **pn; ++ char *fnm, *anm; ++ unsigned int tagv = dyn.d_un.d_val; ++ size_t amt = sizeof (struct bfd_link_needed_list); ++ ++ n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); ++ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); ++ if (n == NULL || fnm == NULL) ++ goto error_free_dyn; ++ amt = strlen (fnm) + 1; ++ anm = (char *) bfd_alloc (abfd, amt); ++ if (anm == NULL) ++ goto error_free_dyn; ++ memcpy (anm, fnm, amt); ++ n->name = anm; ++ n->by = abfd; ++ n->next = NULL; ++ for (pn = & runpath; ++ *pn != NULL; ++ pn = &(*pn)->next) ++ ; ++ *pn = n; ++ } ++ /* Ignore DT_RPATH if we have seen DT_RUNPATH. */ ++ if (!runpath && dyn.d_tag == DT_RPATH) ++ { ++ struct bfd_link_needed_list *n, **pn; ++ char *fnm, *anm; ++ unsigned int tagv = dyn.d_un.d_val; ++ size_t amt = sizeof (struct bfd_link_needed_list); ++ ++ n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); ++ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); ++ if (n == NULL || fnm == NULL) ++ goto error_free_dyn; ++ amt = strlen (fnm) + 1; ++ anm = (char *) bfd_alloc (abfd, amt); ++ if (anm == NULL) ++ goto error_free_dyn; ++ memcpy (anm, fnm, amt); ++ n->name = anm; ++ n->by = abfd; ++ n->next = NULL; ++ for (pn = & rpath; ++ *pn != NULL; ++ pn = &(*pn)->next) ++ ; ++ *pn = n; ++ } ++ if (dyn.d_tag == DT_AUDIT) ++ { ++ unsigned int tagv = dyn.d_un.d_val; ++ audit = bfd_elf_string_from_elf_section (abfd, shlink, tagv); ++ } ++ if (dyn.d_tag == DT_FLAGS_1) ++ elf_tdata (abfd)->is_pie = (dyn.d_un.d_val & DF_1_PIE) != 0; ++ } ++ ++ free (dynbuf); ++ } ++ ++ /* DT_RUNPATH overrides DT_RPATH. Do _NOT_ bfd_release, as that ++ frees all more recently bfd_alloc'd blocks as well. */ ++ if (runpath) ++ rpath = runpath; ++ ++ if (rpath) ++ { ++ struct bfd_link_needed_list **pn; ++ for (pn = &htab->runpath; *pn != NULL; pn = &(*pn)->next) ++ ; ++ *pn = rpath; ++ } ++ ++ /* If we have a PT_GNU_RELRO program header, mark as read-only ++ all sections contained fully therein. This makes relro ++ shared library sections appear as they will at run-time. */ ++ phdr = elf_tdata (abfd)->phdr + elf_elfheader (abfd)->e_phnum; ++ while (phdr-- > elf_tdata (abfd)->phdr) ++ if (phdr->p_type == PT_GNU_RELRO) ++ { ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ unsigned int opb = bfd_octets_per_byte (abfd, s); ++ ++ if ((s->flags & SEC_ALLOC) != 0 ++ && s->vma * opb >= phdr->p_vaddr ++ && s->vma * opb + s->size <= phdr->p_vaddr + phdr->p_memsz) ++ s->flags |= SEC_READONLY; ++ } ++ break; ++ } ++ ++ /* We do not want to include any of the sections in a dynamic ++ object in the output file. We hack by simply clobbering the ++ list of sections in the BFD. This could be handled more ++ cleanly by, say, a new section flag; the existing ++ SEC_NEVER_LOAD flag is not the one we want, because that one ++ still implies that the section takes up space in the output ++ file. */ ++ bfd_section_list_clear (abfd); ++ ++ /* Find the name to use in a DT_NEEDED entry that refers to this ++ object. If the object has a DT_SONAME entry, we use it. ++ Otherwise, if the generic linker stuck something in ++ elf_dt_name, we use that. Otherwise, we just use the file ++ name. */ ++ if (soname == NULL || *soname == '\0') ++ { ++ soname = elf_dt_name (abfd); ++ if (soname == NULL || *soname == '\0') ++ soname = bfd_get_filename (abfd); ++ } ++ ++ /* Save the SONAME because sometimes the linker emulation code ++ will need to know it. */ ++ elf_dt_name (abfd) = soname; ++ ++ /* If we have already included this dynamic object in the ++ link, just ignore it. There is no reason to include a ++ particular dynamic object more than once. */ ++ for (loaded_lib = htab->dyn_loaded; ++ loaded_lib != NULL; ++ loaded_lib = loaded_lib->next) ++ { ++ if (strcmp (elf_dt_name (loaded_lib->abfd), soname) == 0) ++ return true; ++ } ++ ++ /* Create dynamic sections for backends that require that be done ++ before setup_gnu_properties. */ ++ if (add_needed ++ && !_bfd_elf_link_create_dynamic_sections (abfd, info)) ++ return false; ++ ++ /* Save the DT_AUDIT entry for the linker emulation code. */ ++ elf_dt_audit (abfd) = audit; ++ } ++ ++ /* If this is a dynamic object, we always link against the .dynsym ++ symbol table, not the .symtab symbol table. The dynamic linker ++ will only see the .dynsym symbol table, so there is no reason to ++ look at .symtab for a dynamic object. */ ++ ++ if (! dynamic || elf_dynsymtab (abfd) == 0) ++ hdr = &elf_tdata (abfd)->symtab_hdr; ++ else ++ hdr = &elf_tdata (abfd)->dynsymtab_hdr; ++ ++ symcount = hdr->sh_size / bed->s->sizeof_sym; ++ ++ /* The sh_info field of the symtab header tells us where the ++ external symbols start. We don't care about the local symbols at ++ this point. */ ++ if (elf_bad_symtab (abfd)) ++ { ++ extsymcount = symcount; ++ extsymoff = 0; ++ } ++ else ++ { ++ extsymcount = symcount - hdr->sh_info; ++ extsymoff = hdr->sh_info; ++ } ++ ++ sym_hash = elf_sym_hashes (abfd); ++ if (extsymcount != 0) ++ { ++ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, ++ NULL, NULL, NULL); ++ if (isymbuf == NULL) ++ goto error_return; ++ ++ if (sym_hash == NULL) ++ { ++ /* We store a pointer to the hash table entry for each ++ external symbol. */ ++ size_t amt = extsymcount * sizeof (struct elf_link_hash_entry *); ++ sym_hash = (struct elf_link_hash_entry **) bfd_zalloc (abfd, amt); ++ if (sym_hash == NULL) ++ goto error_free_sym; ++ elf_sym_hashes (abfd) = sym_hash; ++ } ++ } ++ ++ if (dynamic) ++ { ++ /* Read in any version definitions. */ ++ if (!_bfd_elf_slurp_version_tables (abfd, ++ info->default_imported_symver)) ++ goto error_free_sym; ++ ++ /* Read in the symbol versions, but don't bother to convert them ++ to internal format. */ ++ if (elf_dynversym (abfd) != 0) ++ { ++ Elf_Internal_Shdr *versymhdr = &elf_tdata (abfd)->dynversym_hdr; ++ bfd_size_type amt = versymhdr->sh_size; ++ ++ if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0) ++ goto error_free_sym; ++ extversym = (Elf_External_Versym *) ++ _bfd_malloc_and_read (abfd, amt, amt); ++ if (extversym == NULL) ++ goto error_free_sym; ++ extversym_end = extversym + amt / sizeof (*extversym); ++ } ++ } ++ ++ /* If we are loading an as-needed shared lib, save the symbol table ++ state before we start adding symbols. If the lib turns out ++ to be unneeded, restore the state. */ ++ if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) ++ { ++ unsigned int i; ++ size_t entsize; ++ ++ for (entsize = 0, i = 0; i < htab->root.table.size; i++) ++ { ++ struct bfd_hash_entry *p; ++ struct elf_link_hash_entry *h; ++ ++ for (p = htab->root.table.table[i]; p != NULL; p = p->next) ++ { ++ h = (struct elf_link_hash_entry *) p; ++ entsize += htab->root.table.entsize; ++ if (h->root.type == bfd_link_hash_warning) ++ { ++ entsize += htab->root.table.entsize; ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ } ++ if (h->root.type == bfd_link_hash_common) ++ entsize += sizeof (*h->root.u.c.p); ++ } ++ } ++ ++ tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry *); ++ old_tab = bfd_malloc (tabsize + entsize); ++ if (old_tab == NULL) ++ goto error_free_vers; ++ ++ /* Remember the current objalloc pointer, so that all mem for ++ symbols added can later be reclaimed. */ ++ alloc_mark = bfd_hash_allocate (&htab->root.table, 1); ++ if (alloc_mark == NULL) ++ goto error_free_vers; ++ ++ /* Make a special call to the linker "notice" function to ++ tell it that we are about to handle an as-needed lib. */ ++ if (!(*bed->notice_as_needed) (abfd, info, notice_as_needed)) ++ goto error_free_vers; ++ ++ /* Clone the symbol table. Remember some pointers into the ++ symbol table, and dynamic symbol count. */ ++ old_ent = (char *) old_tab + tabsize; ++ memcpy (old_tab, htab->root.table.table, tabsize); ++ old_undefs = htab->root.undefs; ++ old_undefs_tail = htab->root.undefs_tail; ++ old_table = htab->root.table.table; ++ old_size = htab->root.table.size; ++ old_count = htab->root.table.count; ++ old_strtab = NULL; ++ if (htab->dynstr != NULL) ++ { ++ old_strtab = _bfd_elf_strtab_save (htab->dynstr); ++ if (old_strtab == NULL) ++ goto error_free_vers; ++ } ++ ++ for (i = 0; i < htab->root.table.size; i++) ++ { ++ struct bfd_hash_entry *p; ++ struct elf_link_hash_entry *h; ++ ++ for (p = htab->root.table.table[i]; p != NULL; p = p->next) ++ { ++ h = (struct elf_link_hash_entry *) p; ++ memcpy (old_ent, h, htab->root.table.entsize); ++ old_ent = (char *) old_ent + htab->root.table.entsize; ++ if (h->root.type == bfd_link_hash_warning) ++ { ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ memcpy (old_ent, h, htab->root.table.entsize); ++ old_ent = (char *) old_ent + htab->root.table.entsize; ++ } ++ if (h->root.type == bfd_link_hash_common) ++ { ++ memcpy (old_ent, h->root.u.c.p, sizeof (*h->root.u.c.p)); ++ old_ent = (char *) old_ent + sizeof (*h->root.u.c.p); ++ } ++ } ++ } ++ } ++ ++ weaks = NULL; ++ if (extversym == NULL) ++ ever = NULL; ++ else if (extversym + extsymoff < extversym_end) ++ ever = extversym + extsymoff; ++ else ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: invalid version offset %lx (max %lx)"), ++ abfd, (long) extsymoff, ++ (long) (extversym_end - extversym) / sizeof (* extversym)); ++ bfd_set_error (bfd_error_bad_value); ++ goto error_free_vers; ++ } ++ ++ if (!bfd_link_relocatable (info) ++ && abfd->lto_slim_object) ++ { ++ _bfd_error_handler ++ (_("%pB: plugin needed to handle lto object"), abfd); ++ } ++ ++ for (isym = isymbuf, isymend = PTR_ADD (isymbuf, extsymcount); ++ isym < isymend; ++ isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL)) ++ { ++ int bind; ++ bfd_vma value; ++ asection *sec, *new_sec; ++ flagword flags; ++ const char *name; ++ struct elf_link_hash_entry *h; ++ struct elf_link_hash_entry *hi; ++ bool definition; ++ bool size_change_ok; ++ bool type_change_ok; ++ bool new_weak; ++ bool old_weak; ++ bfd *override; ++ bool common; ++ bool discarded; ++ unsigned int old_alignment; ++ unsigned int shindex; ++ bfd *old_bfd; ++ bool matched; ++ ++ override = NULL; ++ ++ flags = BSF_NO_FLAGS; ++ sec = NULL; ++ value = isym->st_value; ++ common = bed->common_definition (isym); ++ if (common && info->inhibit_common_definition) ++ { ++ /* Treat common symbol as undefined for --no-define-common. */ ++ isym->st_shndx = SHN_UNDEF; ++ common = false; ++ } ++ discarded = false; ++ ++ bind = ELF_ST_BIND (isym->st_info); ++ switch (bind) ++ { ++ case STB_LOCAL: ++ /* This should be impossible, since ELF requires that all ++ global symbols follow all local symbols, and that sh_info ++ point to the first global symbol. Unfortunately, Irix 5 ++ screws this up. */ ++ if (elf_bad_symtab (abfd)) ++ continue; ++ ++ /* If we aren't prepared to handle locals within the globals ++ then we'll likely segfault on a NULL symbol hash if the ++ symbol is ever referenced in relocations. */ ++ shindex = elf_elfheader (abfd)->e_shstrndx; ++ name = bfd_elf_string_from_elf_section (abfd, shindex, hdr->sh_name); ++ _bfd_error_handler (_("%pB: %s local symbol at index %lu" ++ " (>= sh_info of %lu)"), ++ abfd, name, (long) (isym - isymbuf + extsymoff), ++ (long) extsymoff); ++ ++ /* Dynamic object relocations are not processed by ld, so ++ ld won't run into the problem mentioned above. */ ++ if (dynamic) ++ continue; ++ bfd_set_error (bfd_error_bad_value); ++ goto error_free_vers; ++ ++ case STB_GLOBAL: ++ if (isym->st_shndx != SHN_UNDEF && !common) ++ flags = BSF_GLOBAL; ++ break; ++ ++ case STB_WEAK: ++ flags = BSF_WEAK; ++ break; ++ ++ case STB_GNU_UNIQUE: ++ flags = BSF_GNU_UNIQUE; ++ break; ++ ++ default: ++ /* Leave it up to the processor backend. */ ++ break; ++ } ++ ++ if (isym->st_shndx == SHN_UNDEF) ++ sec = bfd_und_section_ptr; ++ else if (isym->st_shndx == SHN_ABS) ++ sec = bfd_abs_section_ptr; ++ else if (isym->st_shndx == SHN_COMMON) ++ { ++ sec = bfd_com_section_ptr; ++ /* What ELF calls the size we call the value. What ELF ++ calls the value we call the alignment. */ ++ value = isym->st_size; ++ } ++ else ++ { ++ sec = bfd_section_from_elf_index (abfd, isym->st_shndx); ++ if (sec == NULL) ++ sec = bfd_abs_section_ptr; ++ else if (discarded_section (sec)) ++ { ++ /* Symbols from discarded section are undefined. We keep ++ its visibility. */ ++ sec = bfd_und_section_ptr; ++ discarded = true; ++ isym->st_shndx = SHN_UNDEF; ++ } ++ else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) ++ value -= sec->vma; ++ } ++ ++ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, ++ isym->st_name); ++ if (name == NULL) ++ goto error_free_vers; ++ ++ if (isym->st_shndx == SHN_COMMON ++ && (abfd->flags & BFD_PLUGIN) != 0) ++ { ++ asection *xc = bfd_get_section_by_name (abfd, "COMMON"); ++ ++ if (xc == NULL) ++ { ++ flagword sflags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP ++ | SEC_EXCLUDE); ++ xc = bfd_make_section_with_flags (abfd, "COMMON", sflags); ++ if (xc == NULL) ++ goto error_free_vers; ++ } ++ sec = xc; ++ } ++ else if (isym->st_shndx == SHN_COMMON ++ && ELF_ST_TYPE (isym->st_info) == STT_TLS ++ && !bfd_link_relocatable (info)) ++ { ++ asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon"); ++ ++ if (tcomm == NULL) ++ { ++ flagword sflags = (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_IS_COMMON ++ | SEC_LINKER_CREATED); ++ tcomm = bfd_make_section_with_flags (abfd, ".tcommon", sflags); ++ if (tcomm == NULL) ++ goto error_free_vers; ++ } ++ sec = tcomm; ++ } ++ else if (bed->elf_add_symbol_hook) ++ { ++ if (! (*bed->elf_add_symbol_hook) (abfd, info, isym, &name, &flags, ++ &sec, &value)) ++ goto error_free_vers; ++ ++ /* The hook function sets the name to NULL if this symbol ++ should be skipped for some reason. */ ++ if (name == NULL) ++ continue; ++ } ++ ++ /* Sanity check that all possibilities were handled. */ ++ if (sec == NULL) ++ abort (); ++ ++ /* Silently discard TLS symbols from --just-syms. There's ++ no way to combine a static TLS block with a new TLS block ++ for this executable. */ ++ if (ELF_ST_TYPE (isym->st_info) == STT_TLS ++ && sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ continue; ++ ++ if (bfd_is_und_section (sec) ++ || bfd_is_com_section (sec)) ++ definition = false; ++ else ++ definition = true; ++ ++ size_change_ok = false; ++ type_change_ok = bed->type_change_ok; ++ old_weak = false; ++ matched = false; ++ old_alignment = 0; ++ old_bfd = NULL; ++ new_sec = sec; ++ ++ if (is_elf_hash_table (&htab->root)) ++ { ++ Elf_Internal_Versym iver; ++ unsigned int vernum = 0; ++ bool skip; ++ ++ if (ever == NULL) ++ { ++ if (info->default_imported_symver) ++ /* Use the default symbol version created earlier. */ ++ iver.vs_vers = elf_tdata (abfd)->cverdefs; ++ else ++ iver.vs_vers = 0; ++ } ++ else if (ever >= extversym_end) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: not enough version information"), ++ abfd); ++ bfd_set_error (bfd_error_bad_value); ++ goto error_free_vers; ++ } ++ else ++ _bfd_elf_swap_versym_in (abfd, ever, &iver); ++ ++ vernum = iver.vs_vers & VERSYM_VERSION; ++ ++ /* If this is a hidden symbol, or if it is not version ++ 1, we append the version name to the symbol name. ++ However, we do not modify a non-hidden absolute symbol ++ if it is not a function, because it might be the version ++ symbol itself. FIXME: What if it isn't? */ ++ if ((iver.vs_vers & VERSYM_HIDDEN) != 0 ++ || (vernum > 1 ++ && (!bfd_is_abs_section (sec) ++ || bed->is_function_type (ELF_ST_TYPE (isym->st_info))))) ++ { ++ const char *verstr; ++ size_t namelen, verlen, newlen; ++ char *newname, *p; ++ ++ if (isym->st_shndx != SHN_UNDEF) ++ { ++ if (vernum > elf_tdata (abfd)->cverdefs) ++ verstr = NULL; ++ else if (vernum > 1) ++ verstr = ++ elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; ++ else ++ verstr = ""; ++ ++ if (verstr == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: %s: invalid version %u (max %d)"), ++ abfd, name, vernum, ++ elf_tdata (abfd)->cverdefs); ++ bfd_set_error (bfd_error_bad_value); ++ goto error_free_vers; ++ } ++ } ++ else ++ { ++ /* We cannot simply test for the number of ++ entries in the VERNEED section since the ++ numbers for the needed versions do not start ++ at 0. */ ++ Elf_Internal_Verneed *t; ++ ++ verstr = NULL; ++ for (t = elf_tdata (abfd)->verref; ++ t != NULL; ++ t = t->vn_nextref) ++ { ++ Elf_Internal_Vernaux *a; ++ ++ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) ++ { ++ if (a->vna_other == vernum) ++ { ++ verstr = a->vna_nodename; ++ break; ++ } ++ } ++ if (a != NULL) ++ break; ++ } ++ if (verstr == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: %s: invalid needed version %d"), ++ abfd, name, vernum); ++ bfd_set_error (bfd_error_bad_value); ++ goto error_free_vers; ++ } ++ } ++ ++ namelen = strlen (name); ++ verlen = strlen (verstr); ++ newlen = namelen + verlen + 2; ++ if ((iver.vs_vers & VERSYM_HIDDEN) == 0 ++ && isym->st_shndx != SHN_UNDEF) ++ ++newlen; ++ ++ newname = (char *) bfd_hash_allocate (&htab->root.table, newlen); ++ if (newname == NULL) ++ goto error_free_vers; ++ memcpy (newname, name, namelen); ++ p = newname + namelen; ++ *p++ = ELF_VER_CHR; ++ /* If this is a defined non-hidden version symbol, ++ we add another @ to the name. This indicates the ++ default version of the symbol. */ ++ if ((iver.vs_vers & VERSYM_HIDDEN) == 0 ++ && isym->st_shndx != SHN_UNDEF) ++ *p++ = ELF_VER_CHR; ++ memcpy (p, verstr, verlen + 1); ++ ++ name = newname; ++ } ++ ++ /* If this symbol has default visibility and the user has ++ requested we not re-export it, then mark it as hidden. */ ++ if (!bfd_is_und_section (sec) ++ && !dynamic ++ && abfd->no_export ++ && ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL) ++ isym->st_other = (STV_HIDDEN ++ | (isym->st_other & ~ELF_ST_VISIBILITY (-1))); ++ ++ if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value, ++ sym_hash, &old_bfd, &old_weak, ++ &old_alignment, &skip, &override, ++ &type_change_ok, &size_change_ok, ++ &matched)) ++ goto error_free_vers; ++ ++ if (skip) ++ continue; ++ ++ /* Override a definition only if the new symbol matches the ++ existing one. */ ++ if (override && matched) ++ definition = false; ++ ++ h = *sym_hash; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if (h->versioned != unversioned ++ && elf_tdata (abfd)->verdef != NULL ++ && vernum > 1 ++ && definition) ++ h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1]; ++ } ++ ++ if (! (_bfd_generic_link_add_one_symbol ++ (info, override ? override : abfd, name, flags, sec, value, ++ NULL, false, bed->collect, ++ (struct bfd_link_hash_entry **) sym_hash))) ++ goto error_free_vers; ++ ++ h = *sym_hash; ++ /* We need to make sure that indirect symbol dynamic flags are ++ updated. */ ++ hi = h; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ *sym_hash = h; ++ ++ /* Setting the index to -3 tells elf_link_output_extsym that ++ this symbol is defined in a discarded section. */ ++ if (discarded && is_elf_hash_table (&htab->root)) ++ h->indx = -3; ++ ++ new_weak = (flags & BSF_WEAK) != 0; ++ if (dynamic ++ && definition ++ && new_weak ++ && !bed->is_function_type (ELF_ST_TYPE (isym->st_info)) ++ && is_elf_hash_table (&htab->root) ++ && h->u.alias == NULL) ++ { ++ /* Keep a list of all weak defined non function symbols from ++ a dynamic object, using the alias field. Later in this ++ function we will set the alias field to the correct ++ value. We only put non-function symbols from dynamic ++ objects on this list, because that happens to be the only ++ time we need to know the normal symbol corresponding to a ++ weak symbol, and the information is time consuming to ++ figure out. If the alias field is not already NULL, ++ then this symbol was already defined by some previous ++ dynamic object, and we will be using that previous ++ definition anyhow. */ ++ ++ h->u.alias = weaks; ++ weaks = h; ++ } ++ ++ /* Set the alignment of a common symbol. */ ++ if ((common || bfd_is_com_section (sec)) ++ && h->root.type == bfd_link_hash_common) ++ { ++ unsigned int align; ++ ++ if (common) ++ align = bfd_log2 (isym->st_value); ++ else ++ { ++ /* The new symbol is a common symbol in a shared object. ++ We need to get the alignment from the section. */ ++ align = new_sec->alignment_power; ++ } ++ if (align > old_alignment) ++ h->root.u.c.p->alignment_power = align; ++ else ++ h->root.u.c.p->alignment_power = old_alignment; ++ } ++ ++ if (is_elf_hash_table (&htab->root)) ++ { ++ /* Set a flag in the hash table entry indicating the type of ++ reference or definition we just found. A dynamic symbol ++ is one which is referenced or defined by both a regular ++ object and a shared object. */ ++ bool dynsym = false; ++ ++ /* Plugin symbols aren't normal. Don't set def/ref flags. */ ++ if ((abfd->flags & BFD_PLUGIN) != 0) ++ { ++ /* Except for this flag to track nonweak references. */ ++ if (!definition ++ && bind != STB_WEAK) ++ h->ref_ir_nonweak = 1; ++ } ++ else if (!dynamic) ++ { ++ if (! definition) ++ { ++ h->ref_regular = 1; ++ if (bind != STB_WEAK) ++ h->ref_regular_nonweak = 1; ++ } ++ else ++ { ++ h->def_regular = 1; ++ if (h->def_dynamic) ++ { ++ h->def_dynamic = 0; ++ h->ref_dynamic = 1; ++ } ++ } ++ } ++ else ++ { ++ if (! definition) ++ { ++ h->ref_dynamic = 1; ++ hi->ref_dynamic = 1; ++ } ++ else ++ { ++ h->def_dynamic = 1; ++ hi->def_dynamic = 1; ++ } ++ } ++ ++ /* If an indirect symbol has been forced local, don't ++ make the real symbol dynamic. */ ++ if (h != hi && hi->forced_local) ++ ; ++ else if (!dynamic) ++ { ++ if (bfd_link_dll (info) ++ || h->def_dynamic ++ || h->ref_dynamic) ++ dynsym = true; ++ } ++ else ++ { ++ if (h->def_regular ++ || h->ref_regular ++ || (h->is_weakalias ++ && weakdef (h)->dynindx != -1)) ++ dynsym = true; ++ } ++ ++ /* Check to see if we need to add an indirect symbol for ++ the default name. */ ++ if ((definition ++ || (!override && h->root.type == bfd_link_hash_common)) ++ && !(hi != h ++ && hi->versioned == versioned_hidden)) ++ if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym, ++ sec, value, &old_bfd, &dynsym)) ++ goto error_free_vers; ++ ++ /* Check the alignment when a common symbol is involved. This ++ can change when a common symbol is overridden by a normal ++ definition or a common symbol is ignored due to the old ++ normal definition. We need to make sure the maximum ++ alignment is maintained. */ ++ if ((old_alignment || common) ++ && h->root.type != bfd_link_hash_common) ++ { ++ unsigned int common_align; ++ unsigned int normal_align; ++ unsigned int symbol_align; ++ bfd *normal_bfd; ++ bfd *common_bfd; ++ ++ BFD_ASSERT (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak); ++ ++ symbol_align = ffs (h->root.u.def.value) - 1; ++ if (h->root.u.def.section->owner != NULL ++ && (h->root.u.def.section->owner->flags ++ & (DYNAMIC | BFD_PLUGIN)) == 0) ++ { ++ normal_align = h->root.u.def.section->alignment_power; ++ if (normal_align > symbol_align) ++ normal_align = symbol_align; ++ } ++ else ++ normal_align = symbol_align; ++ ++ if (old_alignment) ++ { ++ common_align = old_alignment; ++ common_bfd = old_bfd; ++ normal_bfd = abfd; ++ } ++ else ++ { ++ common_align = bfd_log2 (isym->st_value); ++ common_bfd = abfd; ++ normal_bfd = old_bfd; ++ } ++ ++ if (normal_align < common_align) ++ { ++ /* PR binutils/2735 */ ++ if (normal_bfd == NULL) ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("warning: alignment %u of common symbol `%s' in %pB is" ++ " greater than the alignment (%u) of its section %pA"), ++ 1 << common_align, name, common_bfd, ++ 1 << normal_align, h->root.u.def.section); ++ else ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("warning: alignment %u of normal symbol `%s' in %pB" ++ " is smaller than %u used by the common definition in %pB"), ++ 1 << normal_align, name, normal_bfd, ++ 1 << common_align, common_bfd); ++ ++ /* PR 30499: make sure that users understand that this warning is serious. */ ++ _bfd_error_handler ++ (_("warning: NOTE: alignment discrepancies can cause real problems. Investigation is advised.")); ++ } ++ } ++ ++ /* Remember the symbol size if it isn't undefined. */ ++ if (isym->st_size != 0 ++ && isym->st_shndx != SHN_UNDEF ++ && (definition || h->size == 0)) ++ { ++ if (h->size != 0 ++ && h->size != isym->st_size ++ && ! size_change_ok) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("warning: size of symbol `%s' changed" ++ " from %" PRIu64 " in %pB to %" PRIu64 " in %pB"), ++ name, (uint64_t) h->size, old_bfd, ++ (uint64_t) isym->st_size, abfd); ++ ++ /* PR 30499: make sure that users understand that this warning is serious. */ ++ _bfd_error_handler ++ (_("warning: NOTE: size discrepancies can cause real problems. Investigation is advised.")); ++ } ++ ++ h->size = isym->st_size; ++ } ++ ++ /* If this is a common symbol, then we always want H->SIZE ++ to be the size of the common symbol. The code just above ++ won't fix the size if a common symbol becomes larger. We ++ don't warn about a size change here, because that is ++ covered by --warn-common. Allow changes between different ++ function types. */ ++ if (h->root.type == bfd_link_hash_common) ++ h->size = h->root.u.c.size; ++ ++ if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE ++ && ((definition && !new_weak) ++ || (old_weak && h->root.type == bfd_link_hash_common) ++ || h->type == STT_NOTYPE)) ++ { ++ unsigned int type = ELF_ST_TYPE (isym->st_info); ++ ++ /* Turn an IFUNC symbol from a DSO into a normal FUNC ++ symbol. */ ++ if (type == STT_GNU_IFUNC ++ && (abfd->flags & DYNAMIC) != 0) ++ type = STT_FUNC; ++ ++ if (h->type != type) ++ { ++ if (h->type != STT_NOTYPE && ! type_change_ok) ++ /* xgettext:c-format */ ++ _bfd_error_handler ++ (_("warning: type of symbol `%s' changed" ++ " from %d to %d in %pB"), ++ name, h->type, type, abfd); ++ ++ h->type = type; ++ } ++ } ++ ++ /* Merge st_other field. */ ++ elf_merge_st_other (abfd, h, isym->st_other, sec, ++ definition, dynamic); ++ ++ /* We don't want to make debug symbol dynamic. */ ++ if (definition ++ && (sec->flags & SEC_DEBUGGING) ++ && !bfd_link_relocatable (info)) ++ dynsym = false; ++ ++ /* Nor should we make plugin symbols dynamic. */ ++ if ((abfd->flags & BFD_PLUGIN) != 0) ++ dynsym = false; ++ ++ if (definition) ++ { ++ h->target_internal = isym->st_target_internal; ++ h->unique_global = (flags & BSF_GNU_UNIQUE) != 0; ++ } ++ ++ /* Don't add indirect symbols for .symver x, x@FOO aliases ++ in IR. Since all data or text symbols in IR have the ++ same type, value and section, we can't tell if a symbol ++ is an alias of another symbol by their types, values and ++ sections. */ ++ if (definition ++ && !dynamic ++ && (abfd->flags & BFD_PLUGIN) == 0) ++ { ++ char *p = strchr (name, ELF_VER_CHR); ++ if (p != NULL && p[1] != ELF_VER_CHR) ++ { ++ /* Queue non-default versions so that .symver x, x@FOO ++ aliases can be checked. */ ++ if (!nondeflt_vers) ++ { ++ size_t amt = ((isymend - isym + 1) ++ * sizeof (struct elf_link_hash_entry *)); ++ nondeflt_vers ++ = (struct elf_link_hash_entry **) bfd_malloc (amt); ++ if (!nondeflt_vers) ++ goto error_free_vers; ++ } ++ nondeflt_vers[nondeflt_vers_cnt++] = h; ++ } ++ } ++ ++ if (dynsym && h->dynindx == -1) ++ { ++ if (! bfd_elf_link_record_dynamic_symbol (info, h)) ++ goto error_free_vers; ++ if (h->is_weakalias ++ && weakdef (h)->dynindx == -1) ++ { ++ if (!bfd_elf_link_record_dynamic_symbol (info, weakdef (h))) ++ goto error_free_vers; ++ } ++ } ++ else if (h->dynindx != -1) ++ /* If the symbol already has a dynamic index, but ++ visibility says it should not be visible, turn it into ++ a local symbol. */ ++ switch (ELF_ST_VISIBILITY (h->other)) ++ { ++ case STV_INTERNAL: ++ case STV_HIDDEN: ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ dynsym = false; ++ break; ++ } ++ ++ if (!add_needed ++ && matched ++ && definition ++ && h->root.type != bfd_link_hash_indirect ++ && ((dynsym ++ && h->ref_regular_nonweak) ++ || (old_bfd != NULL ++ && (old_bfd->flags & BFD_PLUGIN) != 0 ++ && h->ref_ir_nonweak ++ && !info->lto_all_symbols_read) ++ || (h->ref_dynamic_nonweak ++ && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0 ++ && !on_needed_list (elf_dt_name (abfd), ++ htab->needed, NULL)))) ++ { ++ const char *soname = elf_dt_name (abfd); ++ ++ info->callbacks->minfo ("%!", soname, old_bfd, ++ h->root.root.string); ++ ++ /* A symbol from a library loaded via DT_NEEDED of some ++ other library is referenced by a regular object. ++ Add a DT_NEEDED entry for it. Issue an error if ++ --no-add-needed is used and the reference was not ++ a weak one. */ ++ if (old_bfd != NULL ++ && (elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: undefined reference to symbol '%s'"), ++ old_bfd, name); ++ bfd_set_error (bfd_error_missing_dso); ++ goto error_free_vers; ++ } ++ ++ elf_dyn_lib_class (abfd) = (enum dynamic_lib_link_class) ++ (elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED); ++ ++ /* Create dynamic sections for backends that require ++ that be done before setup_gnu_properties. */ ++ if (!_bfd_elf_link_create_dynamic_sections (abfd, info)) ++ return false; ++ add_needed = true; ++ } ++ } ++ } ++ ++ if (info->lto_plugin_active ++ && !bfd_link_relocatable (info) ++ && (abfd->flags & BFD_PLUGIN) == 0 ++ && !just_syms ++ && extsymcount) ++ { ++ int r_sym_shift; ++ ++ if (bed->s->arch_size == 32) ++ r_sym_shift = 8; ++ else ++ r_sym_shift = 32; ++ ++ /* If linker plugin is enabled, set non_ir_ref_regular on symbols ++ referenced in regular objects so that linker plugin will get ++ the correct symbol resolution. */ ++ ++ sym_hash = elf_sym_hashes (abfd); ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *rel, *relend; ++ ++ /* Don't check relocations in excluded sections. */ ++ if ((s->flags & SEC_RELOC) == 0 ++ || s->reloc_count == 0 ++ || (s->flags & SEC_EXCLUDE) != 0 ++ || ((info->strip == strip_all ++ || info->strip == strip_debugger) ++ && (s->flags & SEC_DEBUGGING) != 0)) ++ continue; ++ ++ internal_relocs = _bfd_elf_link_info_read_relocs (abfd, info, ++ s, NULL, ++ NULL, ++ _bfd_link_keep_memory (info)); ++ if (internal_relocs == NULL) ++ goto error_free_vers; ++ ++ rel = internal_relocs; ++ relend = rel + s->reloc_count; ++ for ( ; rel < relend; rel++) ++ { ++ unsigned long r_symndx = rel->r_info >> r_sym_shift; ++ struct elf_link_hash_entry *h; ++ ++ /* Skip local symbols. */ ++ if (r_symndx < extsymoff) ++ continue; ++ ++ h = sym_hash[r_symndx - extsymoff]; ++ if (h != NULL) ++ h->root.non_ir_ref_regular = 1; ++ } ++ ++ if (elf_section_data (s)->relocs != internal_relocs) ++ free (internal_relocs); ++ } ++ } ++ ++ free (extversym); ++ extversym = NULL; ++ free (isymbuf); ++ isymbuf = NULL; ++ ++ if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) ++ { ++ unsigned int i; ++ ++ /* Restore the symbol table. */ ++ old_ent = (char *) old_tab + tabsize; ++ memset (elf_sym_hashes (abfd), 0, ++ extsymcount * sizeof (struct elf_link_hash_entry *)); ++ htab->root.table.table = old_table; ++ htab->root.table.size = old_size; ++ htab->root.table.count = old_count; ++ memcpy (htab->root.table.table, old_tab, tabsize); ++ htab->root.undefs = old_undefs; ++ htab->root.undefs_tail = old_undefs_tail; ++ if (htab->dynstr != NULL) ++ _bfd_elf_strtab_restore (htab->dynstr, old_strtab); ++ free (old_strtab); ++ old_strtab = NULL; ++ for (i = 0; i < htab->root.table.size; i++) ++ { ++ struct bfd_hash_entry *p; ++ struct elf_link_hash_entry *h; ++ unsigned int non_ir_ref_dynamic; ++ ++ for (p = htab->root.table.table[i]; p != NULL; p = p->next) ++ { ++ /* Preserve non_ir_ref_dynamic so that this symbol ++ will be exported when the dynamic lib becomes needed ++ in the second pass. */ ++ h = (struct elf_link_hash_entry *) p; ++ if (h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ non_ir_ref_dynamic = h->root.non_ir_ref_dynamic; ++ ++ h = (struct elf_link_hash_entry *) p; ++ memcpy (h, old_ent, htab->root.table.entsize); ++ old_ent = (char *) old_ent + htab->root.table.entsize; ++ if (h->root.type == bfd_link_hash_warning) ++ { ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ memcpy (h, old_ent, htab->root.table.entsize); ++ old_ent = (char *) old_ent + htab->root.table.entsize; ++ } ++ if (h->root.type == bfd_link_hash_common) ++ { ++ memcpy (h->root.u.c.p, old_ent, sizeof (*h->root.u.c.p)); ++ old_ent = (char *) old_ent + sizeof (*h->root.u.c.p); ++ } ++ h->root.non_ir_ref_dynamic = non_ir_ref_dynamic; ++ } ++ } ++ ++ /* Make a special call to the linker "notice" function to ++ tell it that symbols added for crefs may need to be removed. */ ++ if (!(*bed->notice_as_needed) (abfd, info, notice_not_needed)) ++ goto error_free_vers; ++ ++ free (old_tab); ++ objalloc_free_block ((struct objalloc *) htab->root.table.memory, ++ alloc_mark); ++ free (nondeflt_vers); ++ return true; ++ } ++ ++ if (old_tab != NULL) ++ { ++ if (!(*bed->notice_as_needed) (abfd, info, notice_needed)) ++ goto error_free_vers; ++ free (old_tab); ++ old_tab = NULL; ++ } ++ ++ /* Now that all the symbols from this input file are created, if ++ not performing a relocatable link, handle .symver foo, foo@BAR ++ such that any relocs against foo become foo@BAR. */ ++ if (!bfd_link_relocatable (info) && nondeflt_vers != NULL) ++ { ++ size_t cnt, symidx; ++ ++ for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt) ++ { ++ struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi; ++ char *shortname, *p; ++ size_t amt; ++ ++ p = strchr (h->root.root.string, ELF_VER_CHR); ++ if (p == NULL ++ || (h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak)) ++ continue; ++ ++ amt = p - h->root.root.string; ++ shortname = (char *) bfd_malloc (amt + 1); ++ if (!shortname) ++ goto error_free_vers; ++ memcpy (shortname, h->root.root.string, amt); ++ shortname[amt] = '\0'; ++ ++ hi = (struct elf_link_hash_entry *) ++ bfd_link_hash_lookup (&htab->root, shortname, ++ false, false, false); ++ if (hi != NULL ++ && hi->root.type == h->root.type ++ && hi->root.u.def.value == h->root.u.def.value ++ && hi->root.u.def.section == h->root.u.def.section) ++ { ++ (*bed->elf_backend_hide_symbol) (info, hi, true); ++ hi->root.type = bfd_link_hash_indirect; ++ hi->root.u.i.link = (struct bfd_link_hash_entry *) h; ++ (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); ++ sym_hash = elf_sym_hashes (abfd); ++ if (sym_hash) ++ for (symidx = 0; symidx < extsymcount; ++symidx) ++ if (sym_hash[symidx] == hi) ++ { ++ sym_hash[symidx] = h; ++ break; ++ } ++ } ++ free (shortname); ++ } ++ free (nondeflt_vers); ++ nondeflt_vers = NULL; ++ } ++ ++ /* Now set the alias field correctly for all the weak defined ++ symbols we found. The only way to do this is to search all the ++ symbols. Since we only need the information for non functions in ++ dynamic objects, that's the only time we actually put anything on ++ the list WEAKS. We need this information so that if a regular ++ object refers to a symbol defined weakly in a dynamic object, the ++ real symbol in the dynamic object is also put in the dynamic ++ symbols; we also must arrange for both symbols to point to the ++ same memory location. We could handle the general case of symbol ++ aliasing, but a general symbol alias can only be generated in ++ assembler code, handling it correctly would be very time ++ consuming, and other ELF linkers don't handle general aliasing ++ either. */ ++ if (weaks != NULL) ++ { ++ struct elf_link_hash_entry **hpp; ++ struct elf_link_hash_entry **hppend; ++ struct elf_link_hash_entry **sorted_sym_hash; ++ struct elf_link_hash_entry *h; ++ size_t sym_count, amt; ++ ++ /* Since we have to search the whole symbol list for each weak ++ defined symbol, search time for N weak defined symbols will be ++ O(N^2). Binary search will cut it down to O(NlogN). */ ++ amt = extsymcount * sizeof (*sorted_sym_hash); ++ sorted_sym_hash = bfd_malloc (amt); ++ if (sorted_sym_hash == NULL) ++ goto error_return; ++ sym_hash = sorted_sym_hash; ++ hpp = elf_sym_hashes (abfd); ++ hppend = hpp + extsymcount; ++ sym_count = 0; ++ for (; hpp < hppend; hpp++) ++ { ++ h = *hpp; ++ if (h != NULL ++ && h->root.type == bfd_link_hash_defined ++ && !bed->is_function_type (h->type)) ++ { ++ *sym_hash = h; ++ sym_hash++; ++ sym_count++; ++ } ++ } ++ ++ qsort (sorted_sym_hash, sym_count, sizeof (*sorted_sym_hash), ++ elf_sort_symbol); ++ ++ while (weaks != NULL) ++ { ++ struct elf_link_hash_entry *hlook; ++ asection *slook; ++ bfd_vma vlook; ++ size_t i, j, idx = 0; ++ ++ hlook = weaks; ++ weaks = hlook->u.alias; ++ hlook->u.alias = NULL; ++ ++ if (hlook->root.type != bfd_link_hash_defined ++ && hlook->root.type != bfd_link_hash_defweak) ++ continue; ++ ++ slook = hlook->root.u.def.section; ++ vlook = hlook->root.u.def.value; ++ ++ i = 0; ++ j = sym_count; ++ while (i != j) ++ { ++ bfd_signed_vma vdiff; ++ idx = (i + j) / 2; ++ h = sorted_sym_hash[idx]; ++ vdiff = vlook - h->root.u.def.value; ++ if (vdiff < 0) ++ j = idx; ++ else if (vdiff > 0) ++ i = idx + 1; ++ else ++ { ++ int sdiff = slook->id - h->root.u.def.section->id; ++ if (sdiff < 0) ++ j = idx; ++ else if (sdiff > 0) ++ i = idx + 1; ++ else ++ break; ++ } ++ } ++ ++ /* We didn't find a value/section match. */ ++ if (i == j) ++ continue; ++ ++ /* With multiple aliases, or when the weak symbol is already ++ strongly defined, we have multiple matching symbols and ++ the binary search above may land on any of them. Step ++ one past the matching symbol(s). */ ++ while (++idx != j) ++ { ++ h = sorted_sym_hash[idx]; ++ if (h->root.u.def.section != slook ++ || h->root.u.def.value != vlook) ++ break; ++ } ++ ++ /* Now look back over the aliases. Since we sorted by size ++ as well as value and section, we'll choose the one with ++ the largest size. */ ++ while (idx-- != i) ++ { ++ h = sorted_sym_hash[idx]; ++ ++ /* Stop if value or section doesn't match. */ ++ if (h->root.u.def.section != slook ++ || h->root.u.def.value != vlook) ++ break; ++ else if (h != hlook) ++ { ++ struct elf_link_hash_entry *t; ++ ++ hlook->u.alias = h; ++ hlook->is_weakalias = 1; ++ t = h; ++ if (t->u.alias != NULL) ++ while (t->u.alias != h) ++ t = t->u.alias; ++ t->u.alias = hlook; ++ ++ /* If the weak definition is in the list of dynamic ++ symbols, make sure the real definition is put ++ there as well. */ ++ if (hlook->dynindx != -1 && h->dynindx == -1) ++ { ++ if (! bfd_elf_link_record_dynamic_symbol (info, h)) ++ { ++ err_free_sym_hash: ++ free (sorted_sym_hash); ++ goto error_return; ++ } ++ } ++ ++ /* If the real definition is in the list of dynamic ++ symbols, make sure the weak definition is put ++ there as well. If we don't do this, then the ++ dynamic loader might not merge the entries for the ++ real definition and the weak definition. */ ++ if (h->dynindx != -1 && hlook->dynindx == -1) ++ { ++ if (! bfd_elf_link_record_dynamic_symbol (info, hlook)) ++ goto err_free_sym_hash; ++ } ++ break; ++ } ++ } ++ } ++ ++ free (sorted_sym_hash); ++ } ++ ++ if (bed->check_directives ++ && !(*bed->check_directives) (abfd, info)) ++ return false; ++ ++ /* If this is a non-traditional link, try to optimize the handling ++ of the .stab/.stabstr sections. */ ++ if (! dynamic ++ && ! info->traditional_format ++ && is_elf_hash_table (&htab->root) ++ && (info->strip != strip_all && info->strip != strip_debugger)) ++ { ++ asection *stabstr; ++ ++ stabstr = bfd_get_section_by_name (abfd, ".stabstr"); ++ if (stabstr != NULL) ++ { ++ bfd_size_type string_offset = 0; ++ asection *stab; ++ ++ for (stab = abfd->sections; stab; stab = stab->next) ++ if (startswith (stab->name, ".stab") ++ && (!stab->name[5] || ++ (stab->name[5] == '.' && ISDIGIT (stab->name[6]))) ++ && (stab->flags & SEC_MERGE) == 0 ++ && !bfd_is_abs_section (stab->output_section)) ++ { ++ struct bfd_elf_section_data *secdata; ++ ++ secdata = elf_section_data (stab); ++ if (! _bfd_link_section_stabs (abfd, &htab->stab_info, stab, ++ stabstr, &secdata->sec_info, ++ &string_offset)) ++ goto error_return; ++ if (secdata->sec_info) ++ stab->sec_info_type = SEC_INFO_TYPE_STABS; ++ } ++ } ++ } ++ ++ if (dynamic && add_needed) ++ { ++ /* Add this bfd to the loaded list. */ ++ struct elf_link_loaded_list *n; ++ ++ n = (struct elf_link_loaded_list *) bfd_alloc (abfd, sizeof (*n)); ++ if (n == NULL) ++ goto error_return; ++ n->abfd = abfd; ++ n->next = htab->dyn_loaded; ++ htab->dyn_loaded = n; ++ } ++ if (dynamic && !add_needed ++ && (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) != 0) ++ elf_dyn_lib_class (abfd) |= DYN_NO_NEEDED; ++ ++ return true; ++ ++ error_free_vers: ++ free (old_tab); ++ free (old_strtab); ++ free (nondeflt_vers); ++ free (extversym); ++ error_free_sym: ++ free (isymbuf); ++ error_return: ++ return false; ++} ++ ++/* Return the linker hash table entry of a symbol that might be ++ satisfied by an archive symbol. Return -1 on error. */ ++ ++struct bfd_link_hash_entry * ++_bfd_elf_archive_symbol_lookup (bfd *abfd, ++ struct bfd_link_info *info, ++ const char *name) ++{ ++ struct bfd_link_hash_entry *h; ++ char *p, *copy; ++ size_t len, first; ++ ++ h = bfd_link_hash_lookup (info->hash, name, false, false, true); ++ if (h != NULL) ++ return h; ++ ++ /* If this is a default version (the name contains @@), look up the ++ symbol again with only one `@' as well as without the version. ++ The effect is that references to the symbol with and without the ++ version will be matched by the default symbol in the archive. */ ++ ++ p = strchr (name, ELF_VER_CHR); ++ if (p == NULL || p[1] != ELF_VER_CHR) ++ return h; ++ ++ /* First check with only one `@'. */ ++ len = strlen (name); ++ copy = (char *) bfd_alloc (abfd, len); ++ if (copy == NULL) ++ return (struct bfd_link_hash_entry *) -1; ++ ++ first = p - name + 1; ++ memcpy (copy, name, first); ++ memcpy (copy + first, name + first + 1, len - first); ++ ++ h = bfd_link_hash_lookup (info->hash, copy, false, false, true); ++ if (h == NULL) ++ { ++ /* We also need to check references to the symbol without the ++ version. */ ++ copy[first - 1] = '\0'; ++ h = bfd_link_hash_lookup (info->hash, copy, false, false, true); ++ } ++ ++ bfd_release (abfd, copy); ++ return h; ++} ++ ++/* Add symbols from an ELF archive file to the linker hash table. We ++ don't use _bfd_generic_link_add_archive_symbols because we need to ++ handle versioned symbols. ++ ++ Fortunately, ELF archive handling is simpler than that done by ++ _bfd_generic_link_add_archive_symbols, which has to allow for a.out ++ oddities. In ELF, if we find a symbol in the archive map, and the ++ symbol is currently undefined, we know that we must pull in that ++ object file. ++ ++ Unfortunately, we do have to make multiple passes over the symbol ++ table until nothing further is resolved. */ ++ ++static bool ++elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) ++{ ++ symindex c; ++ unsigned char *included = NULL; ++ carsym *symdefs; ++ bool loop; ++ size_t amt; ++ const struct elf_backend_data *bed; ++ struct bfd_link_hash_entry * (*archive_symbol_lookup) ++ (bfd *, struct bfd_link_info *, const char *); ++ ++ if (! bfd_has_map (abfd)) ++ { ++ /* An empty archive is a special case. */ ++ if (bfd_openr_next_archived_file (abfd, NULL) == NULL) ++ return true; ++ bfd_set_error (bfd_error_no_armap); ++ return false; ++ } ++ ++ /* Keep track of all symbols we know to be already defined, and all ++ files we know to be already included. This is to speed up the ++ second and subsequent passes. */ ++ c = bfd_ardata (abfd)->symdef_count; ++ if (c == 0) ++ return true; ++ amt = c * sizeof (*included); ++ included = (unsigned char *) bfd_zmalloc (amt); ++ if (included == NULL) ++ return false; ++ ++ symdefs = bfd_ardata (abfd)->symdefs; ++ bed = get_elf_backend_data (abfd); ++ archive_symbol_lookup = bed->elf_backend_archive_symbol_lookup; ++ ++ do ++ { ++ file_ptr last; ++ symindex i; ++ carsym *symdef; ++ carsym *symdefend; ++ ++ loop = false; ++ last = -1; ++ ++ symdef = symdefs; ++ symdefend = symdef + c; ++ for (i = 0; symdef < symdefend; symdef++, i++) ++ { ++ struct bfd_link_hash_entry *h; ++ bfd *element; ++ struct bfd_link_hash_entry *undefs_tail; ++ symindex mark; ++ ++ if (included[i]) ++ continue; ++ if (symdef->file_offset == last) ++ { ++ included[i] = true; ++ continue; ++ } ++ ++ h = archive_symbol_lookup (abfd, info, symdef->name); ++ if (h == (struct bfd_link_hash_entry *) -1) ++ goto error_return; ++ ++ if (h == NULL) ++ continue; ++ ++ if (h->type == bfd_link_hash_undefined) ++ { ++ /* If the archive element has already been loaded then one ++ of the symbols defined by that element might have been ++ made undefined due to being in a discarded section. */ ++ if (is_elf_hash_table (info->hash) ++ && ((struct elf_link_hash_entry *) h)->indx == -3) ++ continue; ++ } ++ else if (h->type == bfd_link_hash_common) ++ { ++ /* We currently have a common symbol. The archive map contains ++ a reference to this symbol, so we may want to include it. We ++ only want to include it however, if this archive element ++ contains a definition of the symbol, not just another common ++ declaration of it. ++ ++ Unfortunately some archivers (including GNU ar) will put ++ declarations of common symbols into their archive maps, as ++ well as real definitions, so we cannot just go by the archive ++ map alone. Instead we must read in the element's symbol ++ table and check that to see what kind of symbol definition ++ this is. */ ++ if (! elf_link_is_defined_archive_symbol (abfd, symdef)) ++ continue; ++ } ++ else ++ { ++ if (h->type != bfd_link_hash_undefweak) ++ /* Symbol must be defined. Don't check it again. */ ++ included[i] = true; ++ continue; ++ } ++ ++ /* We need to include this archive member. */ ++ element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset, ++ info); ++ if (element == NULL) ++ goto error_return; ++ ++ if (! bfd_check_format (element, bfd_object)) ++ goto error_return; ++ ++ undefs_tail = info->hash->undefs_tail; ++ ++ if (!(*info->callbacks ++ ->add_archive_element) (info, element, symdef->name, &element)) ++ continue; ++ if (!bfd_link_add_symbols (element, info)) ++ goto error_return; ++ ++ /* If there are any new undefined symbols, we need to make ++ another pass through the archive in order to see whether ++ they can be defined. FIXME: This isn't perfect, because ++ common symbols wind up on undefs_tail and because an ++ undefined symbol which is defined later on in this pass ++ does not require another pass. This isn't a bug, but it ++ does make the code less efficient than it could be. */ ++ if (undefs_tail != info->hash->undefs_tail) ++ loop = true; ++ ++ /* Look backward to mark all symbols from this object file ++ which we have already seen in this pass. */ ++ mark = i; ++ do ++ { ++ included[mark] = true; ++ if (mark == 0) ++ break; ++ --mark; ++ } ++ while (symdefs[mark].file_offset == symdef->file_offset); ++ ++ /* We mark subsequent symbols from this object file as we go ++ on through the loop. */ ++ last = symdef->file_offset; ++ } ++ } ++ while (loop); ++ ++ free (included); ++ return true; ++ ++ error_return: ++ free (included); ++ return false; ++} ++ ++/* Given an ELF BFD, add symbols to the global hash table as ++ appropriate. */ ++ ++bool ++bfd_elf_link_add_symbols (bfd *abfd, struct bfd_link_info *info) ++{ ++ switch (bfd_get_format (abfd)) ++ { ++ case bfd_object: ++ return elf_link_add_object_symbols (abfd, info); ++ case bfd_archive: ++ return elf_link_add_archive_symbols (abfd, info); ++ default: ++ bfd_set_error (bfd_error_wrong_format); ++ return false; ++ } ++} ++ ++struct hash_codes_info ++{ ++ unsigned long *hashcodes; ++ bool error; ++}; ++ ++/* This function will be called though elf_link_hash_traverse to store ++ all hash value of the exported symbols in an array. */ ++ ++static bool ++elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data) ++{ ++ struct hash_codes_info *inf = (struct hash_codes_info *) data; ++ const char *name; ++ unsigned long ha; ++ char *alc = NULL; ++ ++ /* Ignore indirect symbols. These are added by the versioning code. */ ++ if (h->dynindx == -1) ++ return true; ++ ++ name = h->root.root.string; ++ if (h->versioned >= versioned) ++ { ++ char *p = strchr (name, ELF_VER_CHR); ++ if (p != NULL) ++ { ++ alc = (char *) bfd_malloc (p - name + 1); ++ if (alc == NULL) ++ { ++ inf->error = true; ++ return false; ++ } ++ memcpy (alc, name, p - name); ++ alc[p - name] = '\0'; ++ name = alc; ++ } ++ } ++ ++ /* Compute the hash value. */ ++ ha = bfd_elf_hash (name); ++ ++ /* Store the found hash value in the array given as the argument. */ ++ *(inf->hashcodes)++ = ha; ++ ++ /* And store it in the struct so that we can put it in the hash table ++ later. */ ++ h->u.elf_hash_value = ha; ++ ++ free (alc); ++ return true; ++} ++ ++struct collect_gnu_hash_codes ++{ ++ bfd *output_bfd; ++ const struct elf_backend_data *bed; ++ unsigned long int nsyms; ++ unsigned long int maskbits; ++ unsigned long int *hashcodes; ++ unsigned long int *hashval; ++ unsigned long int *indx; ++ unsigned long int *counts; ++ bfd_vma *bitmask; ++ bfd_byte *contents; ++ bfd_size_type xlat; ++ long int min_dynindx; ++ unsigned long int bucketcount; ++ unsigned long int symindx; ++ long int local_indx; ++ long int shift1, shift2; ++ unsigned long int mask; ++ bool error; ++}; ++ ++/* This function will be called though elf_link_hash_traverse to store ++ all hash value of the exported symbols in an array. */ ++ ++static bool ++elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data) ++{ ++ struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data; ++ const char *name; ++ unsigned long ha; ++ char *alc = NULL; ++ ++ /* Ignore indirect symbols. These are added by the versioning code. */ ++ if (h->dynindx == -1) ++ return true; ++ ++ /* Ignore also local symbols and undefined symbols. */ ++ if (! (*s->bed->elf_hash_symbol) (h)) ++ return true; ++ ++ name = h->root.root.string; ++ if (h->versioned >= versioned) ++ { ++ char *p = strchr (name, ELF_VER_CHR); ++ if (p != NULL) ++ { ++ alc = (char *) bfd_malloc (p - name + 1); ++ if (alc == NULL) ++ { ++ s->error = true; ++ return false; ++ } ++ memcpy (alc, name, p - name); ++ alc[p - name] = '\0'; ++ name = alc; ++ } ++ } ++ ++ /* Compute the hash value. */ ++ ha = bfd_elf_gnu_hash (name); ++ ++ /* Store the found hash value in the array for compute_bucket_count, ++ and also for .dynsym reordering purposes. */ ++ s->hashcodes[s->nsyms] = ha; ++ s->hashval[h->dynindx] = ha; ++ ++s->nsyms; ++ if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx) ++ s->min_dynindx = h->dynindx; ++ ++ free (alc); ++ return true; ++} ++ ++/* This function will be called though elf_link_hash_traverse to do ++ final dynamic symbol renumbering in case of .gnu.hash. ++ If using .MIPS.xhash, invoke record_xhash_symbol to add symbol index ++ to the translation table. */ ++ ++static bool ++elf_gnu_hash_process_symidx (struct elf_link_hash_entry *h, void *data) ++{ ++ struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data; ++ unsigned long int bucket; ++ unsigned long int val; ++ ++ /* Ignore indirect symbols. */ ++ if (h->dynindx == -1) ++ return true; ++ ++ /* Ignore also local symbols and undefined symbols. */ ++ if (! (*s->bed->elf_hash_symbol) (h)) ++ { ++ if (h->dynindx >= s->min_dynindx) ++ { ++ if (s->bed->record_xhash_symbol != NULL) ++ { ++ (*s->bed->record_xhash_symbol) (h, 0); ++ s->local_indx++; ++ } ++ else ++ h->dynindx = s->local_indx++; ++ } ++ return true; ++ } ++ ++ bucket = s->hashval[h->dynindx] % s->bucketcount; ++ val = (s->hashval[h->dynindx] >> s->shift1) ++ & ((s->maskbits >> s->shift1) - 1); ++ s->bitmask[val] |= ((bfd_vma) 1) << (s->hashval[h->dynindx] & s->mask); ++ s->bitmask[val] ++ |= ((bfd_vma) 1) << ((s->hashval[h->dynindx] >> s->shift2) & s->mask); ++ val = s->hashval[h->dynindx] & ~(unsigned long int) 1; ++ if (s->counts[bucket] == 1) ++ /* Last element terminates the chain. */ ++ val |= 1; ++ bfd_put_32 (s->output_bfd, val, ++ s->contents + (s->indx[bucket] - s->symindx) * 4); ++ --s->counts[bucket]; ++ if (s->bed->record_xhash_symbol != NULL) ++ { ++ bfd_vma xlat_loc = s->xlat + (s->indx[bucket]++ - s->symindx) * 4; ++ ++ (*s->bed->record_xhash_symbol) (h, xlat_loc); ++ } ++ else ++ h->dynindx = s->indx[bucket]++; ++ return true; ++} ++ ++/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ ++ ++bool ++_bfd_elf_hash_symbol (struct elf_link_hash_entry *h) ++{ ++ return !(h->forced_local ++ || h->root.type == bfd_link_hash_undefined ++ || h->root.type == bfd_link_hash_undefweak ++ || ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && h->root.u.def.section->output_section == NULL)); ++} ++ ++/* Array used to determine the number of hash table buckets to use ++ based on the number of symbols there are. If there are fewer than ++ 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets, ++ fewer than 37 we use 17 buckets, and so forth. We never use more ++ than 32771 buckets. */ ++ ++static const size_t elf_buckets[] = ++{ ++ 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, ++ 16411, 32771, 0 ++}; ++ ++/* Compute bucket count for hashing table. We do not use a static set ++ of possible tables sizes anymore. Instead we determine for all ++ possible reasonable sizes of the table the outcome (i.e., the ++ number of collisions etc) and choose the best solution. The ++ weighting functions are not too simple to allow the table to grow ++ without bounds. Instead one of the weighting factors is the size. ++ Therefore the result is always a good payoff between few collisions ++ (= short chain lengths) and table size. */ ++static size_t ++compute_bucket_count (struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ unsigned long int *hashcodes ATTRIBUTE_UNUSED, ++ unsigned long int nsyms, ++ int gnu_hash) ++{ ++ size_t best_size = 0; ++ unsigned long int i; ++ ++ if (info->optimize) ++ { ++ size_t minsize; ++ size_t maxsize; ++ uint64_t best_chlen = ~((uint64_t) 0); ++ bfd *dynobj = elf_hash_table (info)->dynobj; ++ size_t dynsymcount = elf_hash_table (info)->dynsymcount; ++ const struct elf_backend_data *bed = get_elf_backend_data (dynobj); ++ unsigned long int *counts; ++ bfd_size_type amt; ++ unsigned int no_improvement_count = 0; ++ ++ /* Possible optimization parameters: if we have NSYMS symbols we say ++ that the hashing table must at least have NSYMS/4 and at most ++ 2*NSYMS buckets. */ ++ minsize = nsyms / 4; ++ if (minsize == 0) ++ minsize = 1; ++ best_size = maxsize = nsyms * 2; ++ if (gnu_hash) ++ { ++ if (minsize < 2) ++ minsize = 2; ++ if ((best_size & 31) == 0) ++ ++best_size; ++ } ++ ++ /* Create array where we count the collisions in. We must use bfd_malloc ++ since the size could be large. */ ++ amt = maxsize; ++ amt *= sizeof (unsigned long int); ++ counts = (unsigned long int *) bfd_malloc (amt); ++ if (counts == NULL) ++ return 0; ++ ++ /* Compute the "optimal" size for the hash table. The criteria is a ++ minimal chain length. The minor criteria is (of course) the size ++ of the table. */ ++ for (i = minsize; i < maxsize; ++i) ++ { ++ /* Walk through the array of hashcodes and count the collisions. */ ++ uint64_t max; ++ unsigned long int j; ++ unsigned long int fact; ++ ++ if (gnu_hash && (i & 31) == 0) ++ continue; ++ ++ memset (counts, '\0', i * sizeof (unsigned long int)); ++ ++ /* Determine how often each hash bucket is used. */ ++ for (j = 0; j < nsyms; ++j) ++ ++counts[hashcodes[j] % i]; ++ ++ /* For the weight function we need some information about the ++ pagesize on the target. This is information need not be 100% ++ accurate. Since this information is not available (so far) we ++ define it here to a reasonable default value. If it is crucial ++ to have a better value some day simply define this value. */ ++# ifndef BFD_TARGET_PAGESIZE ++# define BFD_TARGET_PAGESIZE (4096) ++# endif ++ ++ /* We in any case need 2 + DYNSYMCOUNT entries for the size values ++ and the chains. */ ++ max = (2 + dynsymcount) * bed->s->sizeof_hash_entry; ++ ++# if 1 ++ /* Variant 1: optimize for short chains. We add the squares ++ of all the chain lengths (which favors many small chain ++ over a few long chains). */ ++ for (j = 0; j < i; ++j) ++ max += counts[j] * counts[j]; ++ ++ /* This adds penalties for the overall size of the table. */ ++ fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; ++ max *= fact * fact; ++# else ++ /* Variant 2: Optimize a lot more for small table. Here we ++ also add squares of the size but we also add penalties for ++ empty slots (the +1 term). */ ++ for (j = 0; j < i; ++j) ++ max += (1 + counts[j]) * (1 + counts[j]); ++ ++ /* The overall size of the table is considered, but not as ++ strong as in variant 1, where it is squared. */ ++ fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; ++ max *= fact; ++# endif ++ ++ /* Compare with current best results. */ ++ if (max < best_chlen) ++ { ++ best_chlen = max; ++ best_size = i; ++ no_improvement_count = 0; ++ } ++ /* PR 11843: Avoid futile long searches for the best bucket size ++ when there are a large number of symbols. */ ++ else if (++no_improvement_count == 100) ++ break; ++ } ++ ++ free (counts); ++ } ++ else ++ { ++ for (i = 0; elf_buckets[i] != 0; i++) ++ { ++ best_size = elf_buckets[i]; ++ if (nsyms < elf_buckets[i + 1]) ++ break; ++ } ++ if (gnu_hash && best_size < 2) ++ best_size = 2; ++ } ++ ++ return best_size; ++} ++ ++/* Size any SHT_GROUP section for ld -r. */ ++ ++bool ++_bfd_elf_size_group_sections (struct bfd_link_info *info) ++{ ++ bfd *ibfd; ++ asection *s; ++ ++ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) ++ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour ++ && (s = ibfd->sections) != NULL ++ && s->sec_info_type != SEC_INFO_TYPE_JUST_SYMS ++ && !_bfd_elf_fixup_group_sections (ibfd, bfd_abs_section_ptr)) ++ return false; ++ return true; ++} ++ ++/* Set a default stack segment size. The value in INFO wins. If it ++ is unset, LEGACY_SYMBOL's value is used, and if that symbol is ++ undefined it is initialized. */ ++ ++bool ++bfd_elf_stack_segment_size (bfd *output_bfd, ++ struct bfd_link_info *info, ++ const char *legacy_symbol, ++ bfd_vma default_size) ++{ ++ struct elf_link_hash_entry *h = NULL; ++ ++ /* Look for legacy symbol. */ ++ if (legacy_symbol) ++ h = elf_link_hash_lookup (elf_hash_table (info), legacy_symbol, ++ false, false, false); ++ if (h && (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && h->def_regular ++ && (h->type == STT_NOTYPE || h->type == STT_OBJECT)) ++ { ++ /* The symbol has no type if specified on the command line. */ ++ h->type = STT_OBJECT; ++ if (info->stacksize) ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: stack size specified and %s set"), ++ output_bfd, legacy_symbol); ++ else if (h->root.u.def.section != bfd_abs_section_ptr) ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: %s not absolute"), ++ output_bfd, legacy_symbol); ++ else ++ info->stacksize = h->root.u.def.value; ++ } ++ ++ if (!info->stacksize) ++ /* If the user didn't set a size, or explicitly inhibit the ++ size, set it now. */ ++ info->stacksize = default_size; ++ ++ /* Provide the legacy symbol, if it is referenced. */ ++ if (h && (h->root.type == bfd_link_hash_undefined ++ || h->root.type == bfd_link_hash_undefweak)) ++ { ++ struct bfd_link_hash_entry *bh = NULL; ++ ++ if (!(_bfd_generic_link_add_one_symbol ++ (info, output_bfd, legacy_symbol, ++ BSF_GLOBAL, bfd_abs_section_ptr, ++ info->stacksize >= 0 ? info->stacksize : 0, ++ NULL, false, get_elf_backend_data (output_bfd)->collect, &bh))) ++ return false; ++ ++ h = (struct elf_link_hash_entry *) bh; ++ h->def_regular = 1; ++ h->type = STT_OBJECT; ++ } ++ ++ return true; ++} ++ ++/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */ ++ ++struct elf_gc_sweep_symbol_info ++{ ++ struct bfd_link_info *info; ++ void (*hide_symbol) (struct bfd_link_info *, struct elf_link_hash_entry *, ++ bool); ++}; ++ ++static bool ++elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data) ++{ ++ if (!h->mark ++ && (((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && !((h->def_regular || ELF_COMMON_DEF_P (h)) ++ && h->root.u.def.section->gc_mark)) ++ || h->root.type == bfd_link_hash_undefined ++ || h->root.type == bfd_link_hash_undefweak)) ++ { ++ struct elf_gc_sweep_symbol_info *inf; ++ ++ inf = (struct elf_gc_sweep_symbol_info *) data; ++ (*inf->hide_symbol) (inf->info, h, true); ++ h->def_regular = 0; ++ h->ref_regular = 0; ++ h->ref_regular_nonweak = 0; ++ } ++ ++ return true; ++} ++ ++/* Set up the sizes and contents of the ELF dynamic sections. This is ++ called by the ELF linker emulation before_allocation routine. We ++ must set the sizes of the sections before the linker sets the ++ addresses of the various sections. */ ++ ++bool ++bfd_elf_size_dynamic_sections (bfd *output_bfd, ++ const char *soname, ++ const char *rpath, ++ const char *filter_shlib, ++ const char *audit, ++ const char *depaudit, ++ const char * const *auxiliary_filters, ++ struct bfd_link_info *info, ++ asection **sinterpptr) ++{ ++ bfd *dynobj; ++ const struct elf_backend_data *bed; ++ ++ *sinterpptr = NULL; ++ ++ if (!is_elf_hash_table (info->hash)) ++ return true; ++ ++ /* Any syms created from now on start with -1 in ++ got.refcount/offset and plt.refcount/offset. */ ++ elf_hash_table (info)->init_got_refcount ++ = elf_hash_table (info)->init_got_offset; ++ elf_hash_table (info)->init_plt_refcount ++ = elf_hash_table (info)->init_plt_offset; ++ ++ bed = get_elf_backend_data (output_bfd); ++ ++ /* The backend may have to create some sections regardless of whether ++ we're dynamic or not. */ ++ if (bed->elf_backend_always_size_sections ++ && ! (*bed->elf_backend_always_size_sections) (output_bfd, info)) ++ return false; ++ ++ dynobj = elf_hash_table (info)->dynobj; ++ ++ if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created) ++ { ++ struct bfd_elf_version_tree *verdefs; ++ struct elf_info_failed asvinfo; ++ struct bfd_elf_version_tree *t; ++ struct bfd_elf_version_expr *d; ++ asection *s; ++ size_t soname_indx; ++ ++ /* If we are supposed to export all symbols into the dynamic symbol ++ table (this is not the normal case), then do so. */ ++ if (info->export_dynamic ++ || (bfd_link_executable (info) && info->dynamic)) ++ { ++ struct elf_info_failed eif; ++ ++ eif.info = info; ++ eif.failed = false; ++ elf_link_hash_traverse (elf_hash_table (info), ++ _bfd_elf_export_symbol, ++ &eif); ++ if (eif.failed) ++ return false; ++ } ++ ++ if (soname != NULL) ++ { ++ soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, ++ soname, true); ++ if (soname_indx == (size_t) -1 ++ || !_bfd_elf_add_dynamic_entry (info, DT_SONAME, soname_indx)) ++ return false; ++ } ++ else ++ soname_indx = (size_t) -1; ++ ++ /* Make all global versions with definition. */ ++ for (t = info->version_info; t != NULL; t = t->next) ++ for (d = t->globals.list; d != NULL; d = d->next) ++ if (!d->symver && d->literal) ++ { ++ const char *verstr, *name; ++ size_t namelen, verlen, newlen; ++ char *newname, *p, leading_char; ++ struct elf_link_hash_entry *newh; ++ ++ leading_char = bfd_get_symbol_leading_char (output_bfd); ++ name = d->pattern; ++ namelen = strlen (name) + (leading_char != '\0'); ++ verstr = t->name; ++ verlen = strlen (verstr); ++ newlen = namelen + verlen + 3; ++ ++ newname = (char *) bfd_malloc (newlen); ++ if (newname == NULL) ++ return false; ++ newname[0] = leading_char; ++ memcpy (newname + (leading_char != '\0'), name, namelen); ++ ++ /* Check the hidden versioned definition. */ ++ p = newname + namelen; ++ *p++ = ELF_VER_CHR; ++ memcpy (p, verstr, verlen + 1); ++ newh = elf_link_hash_lookup (elf_hash_table (info), ++ newname, false, false, ++ false); ++ if (newh == NULL ++ || (newh->root.type != bfd_link_hash_defined ++ && newh->root.type != bfd_link_hash_defweak)) ++ { ++ /* Check the default versioned definition. */ ++ *p++ = ELF_VER_CHR; ++ memcpy (p, verstr, verlen + 1); ++ newh = elf_link_hash_lookup (elf_hash_table (info), ++ newname, false, false, ++ false); ++ } ++ free (newname); ++ ++ /* Mark this version if there is a definition and it is ++ not defined in a shared object. */ ++ if (newh != NULL ++ && !newh->def_dynamic ++ && (newh->root.type == bfd_link_hash_defined ++ || newh->root.type == bfd_link_hash_defweak)) ++ d->symver = 1; ++ } ++ ++ /* Attach all the symbols to their version information. */ ++ asvinfo.info = info; ++ asvinfo.failed = false; ++ ++ elf_link_hash_traverse (elf_hash_table (info), ++ _bfd_elf_link_assign_sym_version, ++ &asvinfo); ++ if (asvinfo.failed) ++ return false; ++ ++ if (!info->allow_undefined_version) ++ { ++ /* Check if all global versions have a definition. */ ++ bool all_defined = true; ++ for (t = info->version_info; t != NULL; t = t->next) ++ for (d = t->globals.list; d != NULL; d = d->next) ++ if (d->literal && !d->symver && !d->script) ++ { ++ _bfd_error_handler ++ (_("%s: undefined version: %s"), ++ d->pattern, t->name); ++ all_defined = false; ++ } ++ ++ if (!all_defined) ++ { ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ } ++ ++ /* Set up the version definition section. */ ++ s = bfd_get_linker_section (dynobj, ".gnu.version_d"); ++ BFD_ASSERT (s != NULL); ++ ++ /* We may have created additional version definitions if we are ++ just linking a regular application. */ ++ verdefs = info->version_info; ++ ++ /* Skip anonymous version tag. */ ++ if (verdefs != NULL && verdefs->vernum == 0) ++ verdefs = verdefs->next; ++ ++ if (verdefs == NULL && !info->create_default_symver) ++ s->flags |= SEC_EXCLUDE; ++ else ++ { ++ unsigned int cdefs; ++ bfd_size_type size; ++ bfd_byte *p; ++ Elf_Internal_Verdef def; ++ Elf_Internal_Verdaux defaux; ++ struct bfd_link_hash_entry *bh; ++ struct elf_link_hash_entry *h; ++ const char *name; ++ ++ cdefs = 0; ++ size = 0; ++ ++ /* Make space for the base version. */ ++ size += sizeof (Elf_External_Verdef); ++ size += sizeof (Elf_External_Verdaux); ++ ++cdefs; ++ ++ /* Make space for the default version. */ ++ if (info->create_default_symver) ++ { ++ size += sizeof (Elf_External_Verdef); ++ ++cdefs; ++ } ++ ++ for (t = verdefs; t != NULL; t = t->next) ++ { ++ struct bfd_elf_version_deps *n; ++ ++ /* Don't emit base version twice. */ ++ if (t->vernum == 0) ++ continue; ++ ++ size += sizeof (Elf_External_Verdef); ++ size += sizeof (Elf_External_Verdaux); ++ ++cdefs; ++ ++ for (n = t->deps; n != NULL; n = n->next) ++ size += sizeof (Elf_External_Verdaux); ++ } ++ ++ s->size = size; ++ s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); ++ if (s->contents == NULL && s->size != 0) ++ return false; ++ ++ /* Fill in the version definition section. */ ++ ++ p = s->contents; ++ ++ def.vd_version = VER_DEF_CURRENT; ++ def.vd_flags = VER_FLG_BASE; ++ def.vd_ndx = 1; ++ def.vd_cnt = 1; ++ if (info->create_default_symver) ++ { ++ def.vd_aux = 2 * sizeof (Elf_External_Verdef); ++ def.vd_next = sizeof (Elf_External_Verdef); ++ } ++ else ++ { ++ def.vd_aux = sizeof (Elf_External_Verdef); ++ def.vd_next = (sizeof (Elf_External_Verdef) ++ + sizeof (Elf_External_Verdaux)); ++ } ++ ++ if (soname_indx != (size_t) -1) ++ { ++ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, ++ soname_indx); ++ def.vd_hash = bfd_elf_hash (soname); ++ defaux.vda_name = soname_indx; ++ name = soname; ++ } ++ else ++ { ++ size_t indx; ++ ++ name = lbasename (bfd_get_filename (output_bfd)); ++ def.vd_hash = bfd_elf_hash (name); ++ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, ++ name, false); ++ if (indx == (size_t) -1) ++ return false; ++ defaux.vda_name = indx; ++ } ++ defaux.vda_next = 0; ++ ++ _bfd_elf_swap_verdef_out (output_bfd, &def, ++ (Elf_External_Verdef *) p); ++ p += sizeof (Elf_External_Verdef); ++ if (info->create_default_symver) ++ { ++ /* Add a symbol representing this version. */ ++ bh = NULL; ++ if (! (_bfd_generic_link_add_one_symbol ++ (info, dynobj, name, BSF_GLOBAL, bfd_abs_section_ptr, ++ 0, NULL, false, ++ get_elf_backend_data (dynobj)->collect, &bh))) ++ return false; ++ h = (struct elf_link_hash_entry *) bh; ++ h->non_elf = 0; ++ h->def_regular = 1; ++ h->type = STT_OBJECT; ++ h->verinfo.vertree = NULL; ++ ++ if (! bfd_elf_link_record_dynamic_symbol (info, h)) ++ return false; ++ ++ /* Create a duplicate of the base version with the same ++ aux block, but different flags. */ ++ def.vd_flags = 0; ++ def.vd_ndx = 2; ++ def.vd_aux = sizeof (Elf_External_Verdef); ++ if (verdefs) ++ def.vd_next = (sizeof (Elf_External_Verdef) ++ + sizeof (Elf_External_Verdaux)); ++ else ++ def.vd_next = 0; ++ _bfd_elf_swap_verdef_out (output_bfd, &def, ++ (Elf_External_Verdef *) p); ++ p += sizeof (Elf_External_Verdef); ++ } ++ _bfd_elf_swap_verdaux_out (output_bfd, &defaux, ++ (Elf_External_Verdaux *) p); ++ p += sizeof (Elf_External_Verdaux); ++ ++ for (t = verdefs; t != NULL; t = t->next) ++ { ++ unsigned int cdeps; ++ struct bfd_elf_version_deps *n; ++ ++ /* Don't emit the base version twice. */ ++ if (t->vernum == 0) ++ continue; ++ ++ cdeps = 0; ++ for (n = t->deps; n != NULL; n = n->next) ++ ++cdeps; ++ ++ /* Add a symbol representing this version. */ ++ bh = NULL; ++ if (! (_bfd_generic_link_add_one_symbol ++ (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr, ++ 0, NULL, false, ++ get_elf_backend_data (dynobj)->collect, &bh))) ++ return false; ++ h = (struct elf_link_hash_entry *) bh; ++ h->non_elf = 0; ++ h->def_regular = 1; ++ h->type = STT_OBJECT; ++ h->verinfo.vertree = t; ++ ++ if (! bfd_elf_link_record_dynamic_symbol (info, h)) ++ return false; ++ ++ def.vd_version = VER_DEF_CURRENT; ++ def.vd_flags = 0; ++ if (t->globals.list == NULL ++ && t->locals.list == NULL ++ && ! t->used) ++ def.vd_flags |= VER_FLG_WEAK; ++ def.vd_ndx = t->vernum + (info->create_default_symver ? 2 : 1); ++ def.vd_cnt = cdeps + 1; ++ def.vd_hash = bfd_elf_hash (t->name); ++ def.vd_aux = sizeof (Elf_External_Verdef); ++ def.vd_next = 0; ++ ++ /* If a basever node is next, it *must* be the last node in ++ the chain, otherwise Verdef construction breaks. */ ++ if (t->next != NULL && t->next->vernum == 0) ++ BFD_ASSERT (t->next->next == NULL); ++ ++ if (t->next != NULL && t->next->vernum != 0) ++ def.vd_next = (sizeof (Elf_External_Verdef) ++ + (cdeps + 1) * sizeof (Elf_External_Verdaux)); ++ ++ _bfd_elf_swap_verdef_out (output_bfd, &def, ++ (Elf_External_Verdef *) p); ++ p += sizeof (Elf_External_Verdef); ++ ++ defaux.vda_name = h->dynstr_index; ++ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, ++ h->dynstr_index); ++ defaux.vda_next = 0; ++ if (t->deps != NULL) ++ defaux.vda_next = sizeof (Elf_External_Verdaux); ++ t->name_indx = defaux.vda_name; ++ ++ _bfd_elf_swap_verdaux_out (output_bfd, &defaux, ++ (Elf_External_Verdaux *) p); ++ p += sizeof (Elf_External_Verdaux); ++ ++ for (n = t->deps; n != NULL; n = n->next) ++ { ++ if (n->version_needed == NULL) ++ { ++ /* This can happen if there was an error in the ++ version script. */ ++ defaux.vda_name = 0; ++ } ++ else ++ { ++ defaux.vda_name = n->version_needed->name_indx; ++ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, ++ defaux.vda_name); ++ } ++ if (n->next == NULL) ++ defaux.vda_next = 0; ++ else ++ defaux.vda_next = sizeof (Elf_External_Verdaux); ++ ++ _bfd_elf_swap_verdaux_out (output_bfd, &defaux, ++ (Elf_External_Verdaux *) p); ++ p += sizeof (Elf_External_Verdaux); ++ } ++ } ++ ++ elf_tdata (output_bfd)->cverdefs = cdefs; ++ } ++ } ++ ++ if (info->gc_sections && bed->can_gc_sections) ++ { ++ struct elf_gc_sweep_symbol_info sweep_info; ++ ++ /* Remove the symbols that were in the swept sections from the ++ dynamic symbol table. */ ++ sweep_info.info = info; ++ sweep_info.hide_symbol = bed->elf_backend_hide_symbol; ++ elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol, ++ &sweep_info); ++ } ++ ++ if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created) ++ { ++ asection *s; ++ struct elf_find_verdep_info sinfo; ++ ++ /* Work out the size of the version reference section. */ ++ ++ s = bfd_get_linker_section (dynobj, ".gnu.version_r"); ++ BFD_ASSERT (s != NULL); ++ ++ sinfo.info = info; ++ sinfo.vers = elf_tdata (output_bfd)->cverdefs; ++ if (sinfo.vers == 0) ++ sinfo.vers = 1; ++ sinfo.failed = false; ++ ++ elf_link_hash_traverse (elf_hash_table (info), ++ _bfd_elf_link_find_version_dependencies, ++ &sinfo); ++ if (sinfo.failed) ++ return false; ++ ++ if (info->enable_dt_relr) ++ { ++ elf_link_add_dt_relr_dependency (&sinfo); ++ if (sinfo.failed) ++ return false; ++ } ++ ++ if (elf_tdata (output_bfd)->verref == NULL) ++ s->flags |= SEC_EXCLUDE; ++ else ++ { ++ Elf_Internal_Verneed *vn; ++ unsigned int size; ++ unsigned int crefs; ++ bfd_byte *p; ++ ++ /* Build the version dependency section. */ ++ size = 0; ++ crefs = 0; ++ for (vn = elf_tdata (output_bfd)->verref; ++ vn != NULL; ++ vn = vn->vn_nextref) ++ { ++ Elf_Internal_Vernaux *a; ++ ++ size += sizeof (Elf_External_Verneed); ++ ++crefs; ++ for (a = vn->vn_auxptr; a != NULL; a = a->vna_nextptr) ++ size += sizeof (Elf_External_Vernaux); ++ } ++ ++ s->size = size; ++ s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); ++ if (s->contents == NULL) ++ return false; ++ ++ p = s->contents; ++ for (vn = elf_tdata (output_bfd)->verref; ++ vn != NULL; ++ vn = vn->vn_nextref) ++ { ++ unsigned int caux; ++ Elf_Internal_Vernaux *a; ++ size_t indx; ++ ++ caux = 0; ++ for (a = vn->vn_auxptr; a != NULL; a = a->vna_nextptr) ++ ++caux; ++ ++ vn->vn_version = VER_NEED_CURRENT; ++ vn->vn_cnt = caux; ++ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, ++ elf_dt_name (vn->vn_bfd) != NULL ++ ? elf_dt_name (vn->vn_bfd) ++ : lbasename (bfd_get_filename ++ (vn->vn_bfd)), ++ false); ++ if (indx == (size_t) -1) ++ return false; ++ vn->vn_file = indx; ++ vn->vn_aux = sizeof (Elf_External_Verneed); ++ if (vn->vn_nextref == NULL) ++ vn->vn_next = 0; ++ else ++ vn->vn_next = (sizeof (Elf_External_Verneed) ++ + caux * sizeof (Elf_External_Vernaux)); ++ ++ _bfd_elf_swap_verneed_out (output_bfd, vn, ++ (Elf_External_Verneed *) p); ++ p += sizeof (Elf_External_Verneed); ++ ++ for (a = vn->vn_auxptr; a != NULL; a = a->vna_nextptr) ++ { ++ a->vna_hash = bfd_elf_hash (a->vna_nodename); ++ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, ++ a->vna_nodename, false); ++ if (indx == (size_t) -1) ++ return false; ++ a->vna_name = indx; ++ if (a->vna_nextptr == NULL) ++ a->vna_next = 0; ++ else ++ a->vna_next = sizeof (Elf_External_Vernaux); ++ ++ _bfd_elf_swap_vernaux_out (output_bfd, a, ++ (Elf_External_Vernaux *) p); ++ p += sizeof (Elf_External_Vernaux); ++ } ++ } ++ ++ elf_tdata (output_bfd)->cverrefs = crefs; ++ } ++ } ++ ++ if (bfd_link_relocatable (info) ++ && !_bfd_elf_size_group_sections (info)) ++ return false; ++ ++ /* Determine any GNU_STACK segment requirements, after the backend ++ has had a chance to set a default segment size. */ ++ if (info->execstack) ++ { ++ /* If the user has explicitly requested warnings, then generate one even ++ though the choice is the result of another command line option. */ ++ if (info->warn_execstack == 1) ++ _bfd_error_handler ++ (_("\ ++warning: enabling an executable stack because of -z execstack command line option")); ++ elf_stack_flags (output_bfd) = PF_R | PF_W | PF_X; ++ } ++ else if (info->noexecstack) ++ elf_stack_flags (output_bfd) = PF_R | PF_W; ++ else ++ { ++ bfd *inputobj; ++ asection *notesec = NULL; ++ bfd *noteobj = NULL; ++ bfd *emptyobj = NULL; ++ int exec = 0; ++ ++ for (inputobj = info->input_bfds; ++ inputobj; ++ inputobj = inputobj->link.next) ++ { ++ asection *s; ++ ++ if (inputobj->flags ++ & (DYNAMIC | EXEC_P | BFD_PLUGIN | BFD_LINKER_CREATED)) ++ continue; ++ s = inputobj->sections; ++ if (s == NULL || s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ continue; ++ ++ s = bfd_get_section_by_name (inputobj, ".note.GNU-stack"); ++ if (s) ++ { ++ notesec = s; ++ if (s->flags & SEC_CODE) ++ { ++ noteobj = inputobj; ++ exec = PF_X; ++ /* There is no point in scanning the remaining bfds. */ ++ break; ++ } ++ } ++ else if (bed->default_execstack && info->default_execstack) ++ { ++ exec = PF_X; ++ emptyobj = inputobj; ++ } ++ } ++ ++ if (notesec || info->stacksize > 0) ++ { ++ if (exec) ++ { ++ if (info->warn_execstack != 0) ++ { ++ /* PR 29072: Because an executable stack is a serious ++ security risk, make sure that the user knows that it is ++ being enabled despite the fact that it was not requested ++ on the command line. */ ++ if (noteobj) ++ _bfd_error_handler (_("\ ++warning: %s: requires executable stack (because the .note.GNU-stack section is executable)"), ++ bfd_get_filename (noteobj)); ++ else if (emptyobj) ++ { ++ _bfd_error_handler (_("\ ++warning: %s: missing .note.GNU-stack section implies executable stack"), ++ bfd_get_filename (emptyobj)); ++ _bfd_error_handler (_("\ ++NOTE: This behaviour is deprecated and will be removed in a future version of the linker")); ++ } ++ } ++ } ++ elf_stack_flags (output_bfd) = PF_R | PF_W | exec; ++ } ++ ++ if (notesec && exec && bfd_link_relocatable (info) ++ && notesec->output_section != bfd_abs_section_ptr) ++ notesec->output_section->flags |= SEC_CODE; ++ } ++ ++ if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created) ++ { ++ struct elf_info_failed eif; ++ struct elf_link_hash_entry *h; ++ asection *dynstr; ++ asection *s; ++ ++ *sinterpptr = bfd_get_linker_section (dynobj, ".interp"); ++ BFD_ASSERT (*sinterpptr != NULL || !bfd_link_executable (info) || info->nointerp); ++ ++ if (info->symbolic) ++ { ++ if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0)) ++ return false; ++ info->flags |= DF_SYMBOLIC; ++ } ++ ++ if (rpath != NULL) ++ { ++ size_t indx; ++ bfd_vma tag; ++ ++ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath, ++ true); ++ if (indx == (size_t) -1) ++ return false; ++ ++ tag = info->new_dtags ? DT_RUNPATH : DT_RPATH; ++ if (!_bfd_elf_add_dynamic_entry (info, tag, indx)) ++ return false; ++ } ++ ++ if (filter_shlib != NULL) ++ { ++ size_t indx; ++ ++ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, ++ filter_shlib, true); ++ if (indx == (size_t) -1 ++ || !_bfd_elf_add_dynamic_entry (info, DT_FILTER, indx)) ++ return false; ++ } ++ ++ if (auxiliary_filters != NULL) ++ { ++ const char * const *p; ++ ++ for (p = auxiliary_filters; *p != NULL; p++) ++ { ++ size_t indx; ++ ++ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, ++ *p, true); ++ if (indx == (size_t) -1 ++ || !_bfd_elf_add_dynamic_entry (info, DT_AUXILIARY, indx)) ++ return false; ++ } ++ } ++ ++ if (audit != NULL) ++ { ++ size_t indx; ++ ++ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, audit, ++ true); ++ if (indx == (size_t) -1 ++ || !_bfd_elf_add_dynamic_entry (info, DT_AUDIT, indx)) ++ return false; ++ } ++ ++ if (depaudit != NULL) ++ { ++ size_t indx; ++ ++ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, depaudit, ++ true); ++ if (indx == (size_t) -1 ++ || !_bfd_elf_add_dynamic_entry (info, DT_DEPAUDIT, indx)) ++ return false; ++ } ++ ++ eif.info = info; ++ eif.failed = false; ++ ++ /* Find all symbols which were defined in a dynamic object and make ++ the backend pick a reasonable value for them. */ ++ elf_link_hash_traverse (elf_hash_table (info), ++ _bfd_elf_adjust_dynamic_symbol, ++ &eif); ++ if (eif.failed) ++ return false; ++ ++ /* Add some entries to the .dynamic section. We fill in some of the ++ values later, in bfd_elf_final_link, but we must add the entries ++ now so that we know the final size of the .dynamic section. */ ++ ++ /* If there are initialization and/or finalization functions to ++ call then add the corresponding DT_INIT/DT_FINI entries. */ ++ h = (info->init_function ++ ? elf_link_hash_lookup (elf_hash_table (info), ++ info->init_function, false, ++ false, false) ++ : NULL); ++ if (h != NULL ++ && (h->ref_regular ++ || h->def_regular)) ++ { ++ if (!_bfd_elf_add_dynamic_entry (info, DT_INIT, 0)) ++ return false; ++ } ++ h = (info->fini_function ++ ? elf_link_hash_lookup (elf_hash_table (info), ++ info->fini_function, false, ++ false, false) ++ : NULL); ++ if (h != NULL ++ && (h->ref_regular ++ || h->def_regular)) ++ { ++ if (!_bfd_elf_add_dynamic_entry (info, DT_FINI, 0)) ++ return false; ++ } ++ ++ s = bfd_get_section_by_name (output_bfd, ".preinit_array"); ++ if (s != NULL && s->linker_has_input) ++ { ++ /* DT_PREINIT_ARRAY is not allowed in shared library. */ ++ if (! bfd_link_executable (info)) ++ { ++ bfd *sub; ++ asection *o; ++ ++ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) ++ if (bfd_get_flavour (sub) == bfd_target_elf_flavour ++ && (o = sub->sections) != NULL ++ && o->sec_info_type != SEC_INFO_TYPE_JUST_SYMS) ++ for (o = sub->sections; o != NULL; o = o->next) ++ if (elf_section_data (o)->this_hdr.sh_type ++ == SHT_PREINIT_ARRAY) ++ { ++ _bfd_error_handler ++ (_("%pB: .preinit_array section is not allowed in DSO"), ++ sub); ++ break; ++ } ++ ++ bfd_set_error (bfd_error_nonrepresentable_section); ++ return false; ++ } ++ ++ if (!_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0) ++ || !_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0)) ++ return false; ++ } ++ s = bfd_get_section_by_name (output_bfd, ".init_array"); ++ if (s != NULL && s->linker_has_input) ++ { ++ if (!_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0) ++ || !_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0)) ++ return false; ++ } ++ s = bfd_get_section_by_name (output_bfd, ".fini_array"); ++ if (s != NULL && s->linker_has_input) ++ { ++ if (!_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0) ++ || !_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0)) ++ return false; ++ } ++ ++ dynstr = bfd_get_linker_section (dynobj, ".dynstr"); ++ /* If .dynstr is excluded from the link, we don't want any of ++ these tags. Strictly, we should be checking each section ++ individually; This quick check covers for the case where ++ someone does a /DISCARD/ : { *(*) }. */ ++ if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr) ++ { ++ bfd_size_type strsize; ++ ++ strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); ++ if ((info->emit_hash ++ && !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0)) ++ || (info->emit_gnu_hash ++ && (bed->record_xhash_symbol == NULL ++ && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0))) ++ || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0) ++ || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0) ++ || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize) ++ || !_bfd_elf_add_dynamic_entry (info, DT_SYMENT, ++ bed->s->sizeof_sym) ++ || (info->gnu_flags_1 ++ && !_bfd_elf_add_dynamic_entry (info, DT_GNU_FLAGS_1, ++ info->gnu_flags_1))) ++ return false; ++ } ++ } ++ ++ if (! _bfd_elf_maybe_strip_eh_frame_hdr (info)) ++ return false; ++ ++ /* The backend must work out the sizes of all the other dynamic ++ sections. */ ++ if (dynobj != NULL ++ && bed->elf_backend_size_dynamic_sections != NULL ++ && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info)) ++ return false; ++ ++ if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created) ++ { ++ if (elf_tdata (output_bfd)->cverdefs) ++ { ++ unsigned int crefs = elf_tdata (output_bfd)->cverdefs; ++ ++ if (!_bfd_elf_add_dynamic_entry (info, DT_VERDEF, 0) ++ || !_bfd_elf_add_dynamic_entry (info, DT_VERDEFNUM, crefs)) ++ return false; ++ } ++ ++ if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS)) ++ { ++ if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS, info->flags)) ++ return false; ++ } ++ else if (info->flags & DF_BIND_NOW) ++ { ++ if (!_bfd_elf_add_dynamic_entry (info, DT_BIND_NOW, 0)) ++ return false; ++ } ++ ++ if (info->flags_1) ++ { ++ if (bfd_link_executable (info)) ++ info->flags_1 &= ~ (DF_1_INITFIRST ++ | DF_1_NODELETE ++ | DF_1_NOOPEN); ++ if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1)) ++ return false; ++ } ++ ++ if (elf_tdata (output_bfd)->cverrefs) ++ { ++ unsigned int crefs = elf_tdata (output_bfd)->cverrefs; ++ ++ if (!_bfd_elf_add_dynamic_entry (info, DT_VERNEED, 0) ++ || !_bfd_elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs)) ++ return false; ++ } ++ ++ if ((elf_tdata (output_bfd)->cverrefs == 0 ++ && elf_tdata (output_bfd)->cverdefs == 0) ++ || _bfd_elf_link_renumber_dynsyms (output_bfd, info, NULL) <= 1) ++ { ++ asection *s; ++ ++ s = bfd_get_linker_section (dynobj, ".gnu.version"); ++ s->flags |= SEC_EXCLUDE; ++ } ++ } ++ return true; ++} ++ ++/* Find the first non-excluded output section. We'll use its ++ section symbol for some emitted relocs. */ ++void ++_bfd_elf_init_1_index_section (bfd *output_bfd, struct bfd_link_info *info) ++{ ++ asection *s; ++ asection *found = NULL; ++ ++ for (s = output_bfd->sections; s != NULL; s = s->next) ++ if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC ++ && !_bfd_elf_omit_section_dynsym_default (output_bfd, info, s)) ++ { ++ found = s; ++ if ((s->flags & SEC_THREAD_LOCAL) == 0) ++ break; ++ } ++ elf_hash_table (info)->text_index_section = found; ++} ++ ++/* Find two non-excluded output sections, one for code, one for data. ++ We'll use their section symbols for some emitted relocs. */ ++void ++_bfd_elf_init_2_index_sections (bfd *output_bfd, struct bfd_link_info *info) ++{ ++ asection *s; ++ asection *found = NULL; ++ ++ /* Data first, since setting text_index_section changes ++ _bfd_elf_omit_section_dynsym_default. */ ++ for (s = output_bfd->sections; s != NULL; s = s->next) ++ if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC ++ && !(s->flags & SEC_READONLY) ++ && !_bfd_elf_omit_section_dynsym_default (output_bfd, info, s)) ++ { ++ found = s; ++ if ((s->flags & SEC_THREAD_LOCAL) == 0) ++ break; ++ } ++ elf_hash_table (info)->data_index_section = found; ++ ++ for (s = output_bfd->sections; s != NULL; s = s->next) ++ if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC ++ && (s->flags & SEC_READONLY) ++ && !_bfd_elf_omit_section_dynsym_default (output_bfd, info, s)) ++ { ++ found = s; ++ break; ++ } ++ elf_hash_table (info)->text_index_section = found; ++} ++ ++#define GNU_HASH_SECTION_NAME(bed) \ ++ (bed)->record_xhash_symbol != NULL ? ".MIPS.xhash" : ".gnu.hash" ++ ++bool ++bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) ++{ ++ const struct elf_backend_data *bed; ++ unsigned long section_sym_count; ++ bfd_size_type dynsymcount = 0; ++ ++ if (!is_elf_hash_table (info->hash)) ++ return true; ++ ++ bed = get_elf_backend_data (output_bfd); ++ (*bed->elf_backend_init_index_section) (output_bfd, info); ++ ++ /* Assign dynsym indices. In a shared library we generate a section ++ symbol for each output section, which come first. Next come all ++ of the back-end allocated local dynamic syms, followed by the rest ++ of the global symbols. ++ ++ This is usually not needed for static binaries, however backends ++ can request to always do it, e.g. the MIPS backend uses dynamic ++ symbol counts to lay out GOT, which will be produced in the ++ presence of GOT relocations even in static binaries (holding fixed ++ data in that case, to satisfy those relocations). */ ++ ++ if (elf_hash_table (info)->dynamic_sections_created ++ || bed->always_renumber_dynsyms) ++ dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info, ++ §ion_sym_count); ++ ++ if (elf_hash_table (info)->dynamic_sections_created) ++ { ++ bfd *dynobj; ++ asection *s; ++ unsigned int dtagcount; ++ ++ dynobj = elf_hash_table (info)->dynobj; ++ ++ /* Work out the size of the symbol version section. */ ++ s = bfd_get_linker_section (dynobj, ".gnu.version"); ++ BFD_ASSERT (s != NULL); ++ if ((s->flags & SEC_EXCLUDE) == 0) ++ { ++ s->size = dynsymcount * sizeof (Elf_External_Versym); ++ s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); ++ if (s->contents == NULL) ++ return false; ++ ++ if (!_bfd_elf_add_dynamic_entry (info, DT_VERSYM, 0)) ++ return false; ++ } ++ ++ /* Set the size of the .dynsym and .hash sections. We counted ++ the number of dynamic symbols in elf_link_add_object_symbols. ++ We will build the contents of .dynsym and .hash when we build ++ the final symbol table, because until then we do not know the ++ correct value to give the symbols. We built the .dynstr ++ section as we went along in elf_link_add_object_symbols. */ ++ s = elf_hash_table (info)->dynsym; ++ BFD_ASSERT (s != NULL); ++ s->size = dynsymcount * bed->s->sizeof_sym; ++ ++ s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); ++ if (s->contents == NULL) ++ return false; ++ ++ /* The first entry in .dynsym is a dummy symbol. Clear all the ++ section syms, in case we don't output them all. */ ++ ++section_sym_count; ++ memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym); ++ ++ elf_hash_table (info)->bucketcount = 0; ++ ++ /* Compute the size of the hashing table. As a side effect this ++ computes the hash values for all the names we export. */ ++ if (info->emit_hash) ++ { ++ unsigned long int *hashcodes; ++ struct hash_codes_info hashinf; ++ bfd_size_type amt; ++ unsigned long int nsyms; ++ size_t bucketcount; ++ size_t hash_entry_size; ++ ++ /* Compute the hash values for all exported symbols. At the same ++ time store the values in an array so that we could use them for ++ optimizations. */ ++ amt = dynsymcount * sizeof (unsigned long int); ++ hashcodes = (unsigned long int *) bfd_malloc (amt); ++ if (hashcodes == NULL) ++ return false; ++ hashinf.hashcodes = hashcodes; ++ hashinf.error = false; ++ ++ /* Put all hash values in HASHCODES. */ ++ elf_link_hash_traverse (elf_hash_table (info), ++ elf_collect_hash_codes, &hashinf); ++ if (hashinf.error) ++ { ++ free (hashcodes); ++ return false; ++ } ++ ++ nsyms = hashinf.hashcodes - hashcodes; ++ bucketcount ++ = compute_bucket_count (info, hashcodes, nsyms, 0); ++ free (hashcodes); ++ ++ if (bucketcount == 0 && nsyms > 0) ++ return false; ++ ++ elf_hash_table (info)->bucketcount = bucketcount; ++ ++ s = bfd_get_linker_section (dynobj, ".hash"); ++ BFD_ASSERT (s != NULL); ++ hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize; ++ s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size); ++ s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); ++ if (s->contents == NULL) ++ return false; ++ ++ bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents); ++ bfd_put (8 * hash_entry_size, output_bfd, dynsymcount, ++ s->contents + hash_entry_size); ++ } ++ ++ if (info->emit_gnu_hash) ++ { ++ size_t i, cnt; ++ unsigned char *contents; ++ struct collect_gnu_hash_codes cinfo; ++ bfd_size_type amt; ++ size_t bucketcount; ++ ++ memset (&cinfo, 0, sizeof (cinfo)); ++ ++ /* Compute the hash values for all exported symbols. At the same ++ time store the values in an array so that we could use them for ++ optimizations. */ ++ amt = dynsymcount * 2 * sizeof (unsigned long int); ++ cinfo.hashcodes = (long unsigned int *) bfd_malloc (amt); ++ if (cinfo.hashcodes == NULL) ++ return false; ++ ++ cinfo.hashval = cinfo.hashcodes + dynsymcount; ++ cinfo.min_dynindx = -1; ++ cinfo.output_bfd = output_bfd; ++ cinfo.bed = bed; ++ ++ /* Put all hash values in HASHCODES. */ ++ elf_link_hash_traverse (elf_hash_table (info), ++ elf_collect_gnu_hash_codes, &cinfo); ++ if (cinfo.error) ++ { ++ free (cinfo.hashcodes); ++ return false; ++ } ++ ++ bucketcount ++ = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1); ++ ++ if (bucketcount == 0) ++ { ++ free (cinfo.hashcodes); ++ return false; ++ } ++ ++ s = bfd_get_linker_section (dynobj, GNU_HASH_SECTION_NAME (bed)); ++ BFD_ASSERT (s != NULL); ++ ++ if (cinfo.nsyms == 0) ++ { ++ /* Empty .gnu.hash or .MIPS.xhash section is special. */ ++ BFD_ASSERT (cinfo.min_dynindx == -1); ++ free (cinfo.hashcodes); ++ s->size = 5 * 4 + bed->s->arch_size / 8; ++ contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); ++ if (contents == NULL) ++ return false; ++ s->contents = contents; ++ /* 1 empty bucket. */ ++ bfd_put_32 (output_bfd, 1, contents); ++ /* SYMIDX above the special symbol 0. */ ++ bfd_put_32 (output_bfd, 1, contents + 4); ++ /* Just one word for bitmask. */ ++ bfd_put_32 (output_bfd, 1, contents + 8); ++ /* Only hash fn bloom filter. */ ++ bfd_put_32 (output_bfd, 0, contents + 12); ++ /* No hashes are valid - empty bitmask. */ ++ bfd_put (bed->s->arch_size, output_bfd, 0, contents + 16); ++ /* No hashes in the only bucket. */ ++ bfd_put_32 (output_bfd, 0, ++ contents + 16 + bed->s->arch_size / 8); ++ } ++ else ++ { ++ unsigned long int maskwords, maskbitslog2, x; ++ BFD_ASSERT (cinfo.min_dynindx != -1); ++ ++ x = cinfo.nsyms; ++ maskbitslog2 = 1; ++ while ((x >>= 1) != 0) ++ ++maskbitslog2; ++ if (maskbitslog2 < 3) ++ maskbitslog2 = 5; ++ else if ((1 << (maskbitslog2 - 2)) & cinfo.nsyms) ++ maskbitslog2 = maskbitslog2 + 3; ++ else ++ maskbitslog2 = maskbitslog2 + 2; ++ if (bed->s->arch_size == 64) ++ { ++ if (maskbitslog2 == 5) ++ maskbitslog2 = 6; ++ cinfo.shift1 = 6; ++ } ++ else ++ cinfo.shift1 = 5; ++ cinfo.mask = (1 << cinfo.shift1) - 1; ++ cinfo.shift2 = maskbitslog2; ++ cinfo.maskbits = 1 << maskbitslog2; ++ maskwords = 1 << (maskbitslog2 - cinfo.shift1); ++ amt = bucketcount * sizeof (unsigned long int) * 2; ++ amt += maskwords * sizeof (bfd_vma); ++ cinfo.bitmask = (bfd_vma *) bfd_malloc (amt); ++ if (cinfo.bitmask == NULL) ++ { ++ free (cinfo.hashcodes); ++ return false; ++ } ++ ++ cinfo.counts = (long unsigned int *) (cinfo.bitmask + maskwords); ++ cinfo.indx = cinfo.counts + bucketcount; ++ cinfo.symindx = dynsymcount - cinfo.nsyms; ++ memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma)); ++ ++ /* Determine how often each hash bucket is used. */ ++ memset (cinfo.counts, 0, bucketcount * sizeof (cinfo.counts[0])); ++ for (i = 0; i < cinfo.nsyms; ++i) ++ ++cinfo.counts[cinfo.hashcodes[i] % bucketcount]; ++ ++ for (i = 0, cnt = cinfo.symindx; i < bucketcount; ++i) ++ if (cinfo.counts[i] != 0) ++ { ++ cinfo.indx[i] = cnt; ++ cnt += cinfo.counts[i]; ++ } ++ BFD_ASSERT (cnt == dynsymcount); ++ cinfo.bucketcount = bucketcount; ++ cinfo.local_indx = cinfo.min_dynindx; ++ ++ s->size = (4 + bucketcount + cinfo.nsyms) * 4; ++ s->size += cinfo.maskbits / 8; ++ if (bed->record_xhash_symbol != NULL) ++ s->size += cinfo.nsyms * 4; ++ contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); ++ if (contents == NULL) ++ { ++ free (cinfo.bitmask); ++ free (cinfo.hashcodes); ++ return false; ++ } ++ ++ s->contents = contents; ++ bfd_put_32 (output_bfd, bucketcount, contents); ++ bfd_put_32 (output_bfd, cinfo.symindx, contents + 4); ++ bfd_put_32 (output_bfd, maskwords, contents + 8); ++ bfd_put_32 (output_bfd, cinfo.shift2, contents + 12); ++ contents += 16 + cinfo.maskbits / 8; ++ ++ for (i = 0; i < bucketcount; ++i) ++ { ++ if (cinfo.counts[i] == 0) ++ bfd_put_32 (output_bfd, 0, contents); ++ else ++ bfd_put_32 (output_bfd, cinfo.indx[i], contents); ++ contents += 4; ++ } ++ ++ cinfo.contents = contents; ++ ++ cinfo.xlat = contents + cinfo.nsyms * 4 - s->contents; ++ /* Renumber dynamic symbols, if populating .gnu.hash section. ++ If using .MIPS.xhash, populate the translation table. */ ++ elf_link_hash_traverse (elf_hash_table (info), ++ elf_gnu_hash_process_symidx, &cinfo); ++ ++ contents = s->contents + 16; ++ for (i = 0; i < maskwords; ++i) ++ { ++ bfd_put (bed->s->arch_size, output_bfd, cinfo.bitmask[i], ++ contents); ++ contents += bed->s->arch_size / 8; ++ } ++ ++ free (cinfo.bitmask); ++ free (cinfo.hashcodes); ++ } ++ } ++ ++ s = bfd_get_linker_section (dynobj, ".dynstr"); ++ BFD_ASSERT (s != NULL); ++ ++ elf_finalize_dynstr (output_bfd, info); ++ ++ s->size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); ++ ++ for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount) ++ if (!_bfd_elf_add_dynamic_entry (info, DT_NULL, 0)) ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Make sure sec_info_type is cleared if sec_info is cleared too. */ ++ ++static void ++merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED, ++ asection *sec) ++{ ++ BFD_ASSERT (sec->sec_info_type == SEC_INFO_TYPE_MERGE); ++ sec->sec_info_type = SEC_INFO_TYPE_NONE; ++} ++ ++/* Finish SHF_MERGE section merging. */ ++ ++bool ++_bfd_elf_merge_sections (bfd *obfd, struct bfd_link_info *info) ++{ ++ bfd *ibfd; ++ asection *sec; ++ ++ if (!is_elf_hash_table (info->hash)) ++ return false; ++ ++ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) ++ if ((ibfd->flags & DYNAMIC) == 0 ++ && bfd_get_flavour (ibfd) == bfd_target_elf_flavour ++ && (elf_elfheader (ibfd)->e_ident[EI_CLASS] ++ == get_elf_backend_data (obfd)->s->elfclass)) ++ for (sec = ibfd->sections; sec != NULL; sec = sec->next) ++ if ((sec->flags & SEC_MERGE) != 0 ++ && !bfd_is_abs_section (sec->output_section)) ++ { ++ struct bfd_elf_section_data *secdata; ++ ++ secdata = elf_section_data (sec); ++ if (! _bfd_add_merge_section (obfd, ++ &elf_hash_table (info)->merge_info, ++ sec, &secdata->sec_info)) ++ return false; ++ else if (secdata->sec_info) ++ sec->sec_info_type = SEC_INFO_TYPE_MERGE; ++ } ++ ++ if (elf_hash_table (info)->merge_info != NULL) ++ _bfd_merge_sections (obfd, info, elf_hash_table (info)->merge_info, ++ merge_sections_remove_hook); ++ return true; ++} ++ ++/* Create an entry in an ELF linker hash table. */ ++ ++struct bfd_hash_entry * ++_bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (entry == NULL) ++ { ++ entry = (struct bfd_hash_entry *) ++ bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)); ++ if (entry == NULL) ++ return entry; ++ } ++ ++ /* Call the allocation method of the superclass. */ ++ entry = _bfd_link_hash_newfunc (entry, table, string); ++ if (entry != NULL) ++ { ++ struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry; ++ struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table; ++ ++ /* Set local fields. */ ++ ret->indx = -1; ++ ret->dynindx = -1; ++ ret->got = htab->init_got_refcount; ++ ret->plt = htab->init_plt_refcount; ++ memset (&ret->size, 0, (sizeof (struct elf_link_hash_entry) ++ - offsetof (struct elf_link_hash_entry, size))); ++ /* Assume that we have been called by a non-ELF symbol reader. ++ This flag is then reset by the code which reads an ELF input ++ file. This ensures that a symbol created by a non-ELF symbol ++ reader will have the flag set correctly. */ ++ ret->non_elf = 1; ++ } ++ ++ return entry; ++} ++ ++/* Copy data from an indirect symbol to its direct symbol, hiding the ++ old indirect symbol. Also used for copying flags to a weakdef. */ ++ ++void ++_bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info, ++ struct elf_link_hash_entry *dir, ++ struct elf_link_hash_entry *ind) ++{ ++ struct elf_link_hash_table *htab; ++ ++ if (ind->dyn_relocs != NULL) ++ { ++ if (dir->dyn_relocs != NULL) ++ { ++ struct elf_dyn_relocs **pp; ++ struct elf_dyn_relocs *p; ++ ++ /* Add reloc counts against the indirect sym to the direct sym ++ list. Merge any entries against the same section. */ ++ for (pp = &ind->dyn_relocs; (p = *pp) != NULL; ) ++ { ++ struct elf_dyn_relocs *q; ++ ++ for (q = dir->dyn_relocs; q != NULL; q = q->next) ++ if (q->sec == p->sec) ++ { ++ q->pc_count += p->pc_count; ++ q->count += p->count; ++ *pp = p->next; ++ break; ++ } ++ if (q == NULL) ++ pp = &p->next; ++ } ++ *pp = dir->dyn_relocs; ++ } ++ ++ dir->dyn_relocs = ind->dyn_relocs; ++ ind->dyn_relocs = NULL; ++ } ++ ++ /* Copy down any references that we may have already seen to the ++ symbol which just became indirect. */ ++ ++ if (dir->versioned != versioned_hidden) ++ dir->ref_dynamic |= ind->ref_dynamic; ++ dir->ref_regular |= ind->ref_regular; ++ dir->ref_regular_nonweak |= ind->ref_regular_nonweak; ++ dir->non_got_ref |= ind->non_got_ref; ++ dir->needs_plt |= ind->needs_plt; ++ dir->pointer_equality_needed |= ind->pointer_equality_needed; ++ ++ if (ind->root.type != bfd_link_hash_indirect) ++ return; ++ ++ /* Copy over the global and procedure linkage table refcount entries. ++ These may have been already set up by a check_relocs routine. */ ++ htab = elf_hash_table (info); ++ if (ind->got.refcount > htab->init_got_refcount.refcount) ++ { ++ if (dir->got.refcount < 0) ++ dir->got.refcount = 0; ++ dir->got.refcount += ind->got.refcount; ++ ind->got.refcount = htab->init_got_refcount.refcount; ++ } ++ ++ if (ind->plt.refcount > htab->init_plt_refcount.refcount) ++ { ++ if (dir->plt.refcount < 0) ++ dir->plt.refcount = 0; ++ dir->plt.refcount += ind->plt.refcount; ++ ind->plt.refcount = htab->init_plt_refcount.refcount; ++ } ++ ++ if (ind->dynindx != -1) ++ { ++ if (dir->dynindx != -1) ++ _bfd_elf_strtab_delref (htab->dynstr, dir->dynstr_index); ++ dir->dynindx = ind->dynindx; ++ dir->dynstr_index = ind->dynstr_index; ++ ind->dynindx = -1; ++ ind->dynstr_index = 0; ++ } ++} ++ ++void ++_bfd_elf_link_hash_hide_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, ++ bool force_local) ++{ ++ /* STT_GNU_IFUNC symbol must go through PLT. */ ++ if (h->type != STT_GNU_IFUNC) ++ { ++ h->plt = elf_hash_table (info)->init_plt_offset; ++ h->needs_plt = 0; ++ } ++ if (force_local) ++ { ++ h->forced_local = 1; ++ if (h->dynindx != -1) ++ { ++ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr, ++ h->dynstr_index); ++ h->dynindx = -1; ++ h->dynstr_index = 0; ++ } ++ } ++} ++ ++/* Hide a symbol. */ ++ ++void ++_bfd_elf_link_hide_symbol (bfd *output_bfd, ++ struct bfd_link_info *info, ++ struct bfd_link_hash_entry *h) ++{ ++ if (is_elf_hash_table (info->hash)) ++ { ++ const struct elf_backend_data *bed ++ = get_elf_backend_data (output_bfd); ++ struct elf_link_hash_entry *eh ++ = (struct elf_link_hash_entry *) h; ++ bed->elf_backend_hide_symbol (info, eh, true); ++ eh->def_dynamic = 0; ++ eh->ref_dynamic = 0; ++ eh->dynamic_def = 0; ++ } ++} ++ ++/* Initialize an ELF linker hash table. *TABLE has been zeroed by our ++ caller. */ ++ ++bool ++_bfd_elf_link_hash_table_init ++ (struct elf_link_hash_table *table, ++ bfd *abfd, ++ struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, ++ struct bfd_hash_table *, ++ const char *), ++ unsigned int entsize, ++ enum elf_target_id target_id) ++{ ++ bool ret; ++ int can_refcount = get_elf_backend_data (abfd)->can_refcount; ++ ++ table->init_got_refcount.refcount = can_refcount - 1; ++ table->init_plt_refcount.refcount = can_refcount - 1; ++ table->init_got_offset.offset = -(bfd_vma) 1; ++ table->init_plt_offset.offset = -(bfd_vma) 1; ++ /* The first dynamic symbol is a dummy. */ ++ table->dynsymcount = 1; ++ ++ ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize); ++ ++ table->root.type = bfd_link_elf_hash_table; ++ table->hash_table_id = target_id; ++ table->target_os = get_elf_backend_data (abfd)->target_os; ++ ++ return ret; ++} ++ ++/* Create an ELF linker hash table. */ ++ ++struct bfd_link_hash_table * ++_bfd_elf_link_hash_table_create (bfd *abfd) ++{ ++ struct elf_link_hash_table *ret; ++ size_t amt = sizeof (struct elf_link_hash_table); ++ ++ ret = (struct elf_link_hash_table *) bfd_zmalloc (amt); ++ if (ret == NULL) ++ return NULL; ++ ++ if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc, ++ sizeof (struct elf_link_hash_entry), ++ GENERIC_ELF_DATA)) ++ { ++ free (ret); ++ return NULL; ++ } ++ ret->root.hash_table_free = _bfd_elf_link_hash_table_free; ++ ++ return &ret->root; ++} ++ ++/* Destroy an ELF linker hash table. */ ++ ++void ++_bfd_elf_link_hash_table_free (bfd *obfd) ++{ ++ struct elf_link_hash_table *htab; ++ ++ htab = (struct elf_link_hash_table *) obfd->link.hash; ++ if (htab->dynstr != NULL) ++ _bfd_elf_strtab_free (htab->dynstr); ++ _bfd_merge_sections_free (htab->merge_info); ++ _bfd_generic_link_hash_table_free (obfd); ++} ++ ++/* This is a hook for the ELF emulation code in the generic linker to ++ tell the backend linker what file name to use for the DT_NEEDED ++ entry for a dynamic object. */ ++ ++void ++bfd_elf_set_dt_needed_name (bfd *abfd, const char *name) ++{ ++ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour ++ && bfd_get_format (abfd) == bfd_object) ++ elf_dt_name (abfd) = name; ++} ++ ++int ++bfd_elf_get_dyn_lib_class (bfd *abfd) ++{ ++ int lib_class; ++ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour ++ && bfd_get_format (abfd) == bfd_object) ++ lib_class = elf_dyn_lib_class (abfd); ++ else ++ lib_class = 0; ++ return lib_class; ++} ++ ++void ++bfd_elf_set_dyn_lib_class (bfd *abfd, enum dynamic_lib_link_class lib_class) ++{ ++ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour ++ && bfd_get_format (abfd) == bfd_object) ++ elf_dyn_lib_class (abfd) = lib_class; ++} ++ ++/* Get the list of DT_NEEDED entries for a link. This is a hook for ++ the linker ELF emulation code. */ ++ ++struct bfd_link_needed_list * ++bfd_elf_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info) ++{ ++ if (! is_elf_hash_table (info->hash)) ++ return NULL; ++ return elf_hash_table (info)->needed; ++} ++ ++/* Get the list of DT_RPATH/DT_RUNPATH entries for a link. This is a ++ hook for the linker ELF emulation code. */ ++ ++struct bfd_link_needed_list * ++bfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info) ++{ ++ if (! is_elf_hash_table (info->hash)) ++ return NULL; ++ return elf_hash_table (info)->runpath; ++} ++ ++/* Get the name actually used for a dynamic object for a link. This ++ is the SONAME entry if there is one. Otherwise, it is the string ++ passed to bfd_elf_set_dt_needed_name, or it is the filename. */ ++ ++const char * ++bfd_elf_get_dt_soname (bfd *abfd) ++{ ++ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour ++ && bfd_get_format (abfd) == bfd_object) ++ return elf_dt_name (abfd); ++ return NULL; ++} ++ ++/* Get the list of DT_NEEDED entries from a BFD. This is a hook for ++ the ELF linker emulation code. */ ++ ++bool ++bfd_elf_get_bfd_needed_list (bfd *abfd, ++ struct bfd_link_needed_list **pneeded) ++{ ++ asection *s; ++ bfd_byte *dynbuf = NULL; ++ unsigned int elfsec; ++ unsigned long shlink; ++ bfd_byte *extdyn, *extdynend; ++ size_t extdynsize; ++ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); ++ ++ *pneeded = NULL; ++ ++ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour ++ || bfd_get_format (abfd) != bfd_object) ++ return true; ++ ++ s = bfd_get_section_by_name (abfd, ".dynamic"); ++ if (s == NULL || s->size == 0 || (s->flags & SEC_HAS_CONTENTS) == 0) ++ return true; ++ ++ if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) ++ goto error_return; ++ ++ elfsec = _bfd_elf_section_from_bfd_section (abfd, s); ++ if (elfsec == SHN_BAD) ++ goto error_return; ++ ++ shlink = elf_elfsections (abfd)[elfsec]->sh_link; ++ ++ extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; ++ swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; ++ ++ for (extdyn = dynbuf, extdynend = dynbuf + s->size; ++ (size_t) (extdynend - extdyn) >= extdynsize; ++ extdyn += extdynsize) ++ { ++ Elf_Internal_Dyn dyn; ++ ++ (*swap_dyn_in) (abfd, extdyn, &dyn); ++ ++ if (dyn.d_tag == DT_NULL) ++ break; ++ ++ if (dyn.d_tag == DT_NEEDED) ++ { ++ const char *string; ++ struct bfd_link_needed_list *l; ++ unsigned int tagv = dyn.d_un.d_val; ++ size_t amt; ++ ++ string = bfd_elf_string_from_elf_section (abfd, shlink, tagv); ++ if (string == NULL) ++ goto error_return; ++ ++ amt = sizeof *l; ++ l = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); ++ if (l == NULL) ++ goto error_return; ++ ++ l->by = abfd; ++ l->name = string; ++ l->next = *pneeded; ++ *pneeded = l; ++ } ++ } ++ ++ free (dynbuf); ++ ++ return true; ++ ++ error_return: ++ free (dynbuf); ++ return false; ++} ++ ++struct elf_symbuf_symbol ++{ ++ unsigned long st_name; /* Symbol name, index in string tbl */ ++ unsigned char st_info; /* Type and binding attributes */ ++ unsigned char st_other; /* Visibilty, and target specific */ ++}; ++ ++struct elf_symbuf_head ++{ ++ struct elf_symbuf_symbol *ssym; ++ size_t count; ++ unsigned int st_shndx; ++}; ++ ++struct elf_symbol ++{ ++ union ++ { ++ Elf_Internal_Sym *isym; ++ struct elf_symbuf_symbol *ssym; ++ void *p; ++ } u; ++ const char *name; ++}; ++ ++/* Sort references to symbols by ascending section number. */ ++ ++static int ++elf_sort_elf_symbol (const void *arg1, const void *arg2) ++{ ++ const Elf_Internal_Sym *s1 = *(const Elf_Internal_Sym **) arg1; ++ const Elf_Internal_Sym *s2 = *(const Elf_Internal_Sym **) arg2; ++ ++ if (s1->st_shndx != s2->st_shndx) ++ return s1->st_shndx > s2->st_shndx ? 1 : -1; ++ /* Final sort by the address of the sym in the symbuf ensures ++ a stable sort. */ ++ if (s1 != s2) ++ return s1 > s2 ? 1 : -1; ++ return 0; ++} ++ ++static int ++elf_sym_name_compare (const void *arg1, const void *arg2) ++{ ++ const struct elf_symbol *s1 = (const struct elf_symbol *) arg1; ++ const struct elf_symbol *s2 = (const struct elf_symbol *) arg2; ++ int ret = strcmp (s1->name, s2->name); ++ if (ret != 0) ++ return ret; ++ if (s1->u.p != s2->u.p) ++ return s1->u.p > s2->u.p ? 1 : -1; ++ return 0; ++} ++ ++static struct elf_symbuf_head * ++elf_create_symbuf (size_t symcount, Elf_Internal_Sym *isymbuf) ++{ ++ Elf_Internal_Sym **ind, **indbufend, **indbuf; ++ struct elf_symbuf_symbol *ssym; ++ struct elf_symbuf_head *ssymbuf, *ssymhead; ++ size_t i, shndx_count, total_size, amt; ++ ++ amt = symcount * sizeof (*indbuf); ++ indbuf = (Elf_Internal_Sym **) bfd_malloc (amt); ++ if (indbuf == NULL) ++ return NULL; ++ ++ for (ind = indbuf, i = 0; i < symcount; i++) ++ if (isymbuf[i].st_shndx != SHN_UNDEF) ++ *ind++ = &isymbuf[i]; ++ indbufend = ind; ++ ++ qsort (indbuf, indbufend - indbuf, sizeof (Elf_Internal_Sym *), ++ elf_sort_elf_symbol); ++ ++ shndx_count = 0; ++ if (indbufend > indbuf) ++ for (ind = indbuf, shndx_count++; ind < indbufend - 1; ind++) ++ if (ind[0]->st_shndx != ind[1]->st_shndx) ++ shndx_count++; ++ ++ total_size = ((shndx_count + 1) * sizeof (*ssymbuf) ++ + (indbufend - indbuf) * sizeof (*ssym)); ++ ssymbuf = (struct elf_symbuf_head *) bfd_malloc (total_size); ++ if (ssymbuf == NULL) ++ { ++ free (indbuf); ++ return NULL; ++ } ++ ++ ssym = (struct elf_symbuf_symbol *) (ssymbuf + shndx_count + 1); ++ ssymbuf->ssym = NULL; ++ ssymbuf->count = shndx_count; ++ ssymbuf->st_shndx = 0; ++ for (ssymhead = ssymbuf, ind = indbuf; ind < indbufend; ssym++, ind++) ++ { ++ if (ind == indbuf || ssymhead->st_shndx != (*ind)->st_shndx) ++ { ++ ssymhead++; ++ ssymhead->ssym = ssym; ++ ssymhead->count = 0; ++ ssymhead->st_shndx = (*ind)->st_shndx; ++ } ++ ssym->st_name = (*ind)->st_name; ++ ssym->st_info = (*ind)->st_info; ++ ssym->st_other = (*ind)->st_other; ++ ssymhead->count++; ++ } ++ BFD_ASSERT ((size_t) (ssymhead - ssymbuf) == shndx_count ++ && (uintptr_t) ssym - (uintptr_t) ssymbuf == total_size); ++ ++ free (indbuf); ++ return ssymbuf; ++} ++ ++/* Check if 2 sections define the same set of local and global ++ symbols. */ ++ ++static bool ++bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, ++ struct bfd_link_info *info) ++{ ++ bfd *bfd1, *bfd2; ++ const struct elf_backend_data *bed1, *bed2; ++ Elf_Internal_Shdr *hdr1, *hdr2; ++ size_t symcount1, symcount2; ++ Elf_Internal_Sym *isymbuf1, *isymbuf2; ++ struct elf_symbuf_head *ssymbuf1, *ssymbuf2; ++ Elf_Internal_Sym *isym, *isymend; ++ struct elf_symbol *symtable1 = NULL, *symtable2 = NULL; ++ size_t count1, count2, sec_count1, sec_count2, i; ++ unsigned int shndx1, shndx2; ++ bool result; ++ bool ignore_section_symbol_p; ++ ++ bfd1 = sec1->owner; ++ bfd2 = sec2->owner; ++ ++ /* Both sections have to be in ELF. */ ++ if (bfd_get_flavour (bfd1) != bfd_target_elf_flavour ++ || bfd_get_flavour (bfd2) != bfd_target_elf_flavour) ++ return false; ++ ++ if (elf_section_type (sec1) != elf_section_type (sec2)) ++ return false; ++ ++ shndx1 = _bfd_elf_section_from_bfd_section (bfd1, sec1); ++ shndx2 = _bfd_elf_section_from_bfd_section (bfd2, sec2); ++ if (shndx1 == SHN_BAD || shndx2 == SHN_BAD) ++ return false; ++ ++ bed1 = get_elf_backend_data (bfd1); ++ bed2 = get_elf_backend_data (bfd2); ++ hdr1 = &elf_tdata (bfd1)->symtab_hdr; ++ symcount1 = hdr1->sh_size / bed1->s->sizeof_sym; ++ hdr2 = &elf_tdata (bfd2)->symtab_hdr; ++ symcount2 = hdr2->sh_size / bed2->s->sizeof_sym; ++ ++ if (symcount1 == 0 || symcount2 == 0) ++ return false; ++ ++ result = false; ++ isymbuf1 = NULL; ++ isymbuf2 = NULL; ++ ssymbuf1 = (struct elf_symbuf_head *) elf_tdata (bfd1)->symbuf; ++ ssymbuf2 = (struct elf_symbuf_head *) elf_tdata (bfd2)->symbuf; ++ ++ /* Ignore section symbols only when matching non-debugging sections ++ or linkonce section with comdat section. */ ++ ignore_section_symbol_p ++ = ((sec1->flags & SEC_DEBUGGING) == 0 ++ || ((elf_section_flags (sec1) & SHF_GROUP) ++ != (elf_section_flags (sec2) & SHF_GROUP))); ++ ++ if (ssymbuf1 == NULL) ++ { ++ isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, symcount1, 0, ++ NULL, NULL, NULL); ++ if (isymbuf1 == NULL) ++ goto done; ++ ++ if (info != NULL && !info->reduce_memory_overheads) ++ { ++ ssymbuf1 = elf_create_symbuf (symcount1, isymbuf1); ++ elf_tdata (bfd1)->symbuf = ssymbuf1; ++ } ++ } ++ ++ if (ssymbuf1 == NULL || ssymbuf2 == NULL) ++ { ++ isymbuf2 = bfd_elf_get_elf_syms (bfd2, hdr2, symcount2, 0, ++ NULL, NULL, NULL); ++ if (isymbuf2 == NULL) ++ goto done; ++ ++ if (ssymbuf1 != NULL && info != NULL && !info->reduce_memory_overheads) ++ { ++ ssymbuf2 = elf_create_symbuf (symcount2, isymbuf2); ++ elf_tdata (bfd2)->symbuf = ssymbuf2; ++ } ++ } ++ ++ if (ssymbuf1 != NULL && ssymbuf2 != NULL) ++ { ++ /* Optimized faster version. */ ++ size_t lo, hi, mid; ++ struct elf_symbol *symp; ++ struct elf_symbuf_symbol *ssym, *ssymend; ++ ++ lo = 0; ++ hi = ssymbuf1->count; ++ ssymbuf1++; ++ count1 = 0; ++ sec_count1 = 0; ++ while (lo < hi) ++ { ++ mid = (lo + hi) / 2; ++ if (shndx1 < ssymbuf1[mid].st_shndx) ++ hi = mid; ++ else if (shndx1 > ssymbuf1[mid].st_shndx) ++ lo = mid + 1; ++ else ++ { ++ count1 = ssymbuf1[mid].count; ++ ssymbuf1 += mid; ++ break; ++ } ++ } ++ if (ignore_section_symbol_p) ++ { ++ for (i = 0; i < count1; i++) ++ if (ELF_ST_TYPE (ssymbuf1->ssym[i].st_info) == STT_SECTION) ++ sec_count1++; ++ count1 -= sec_count1; ++ } ++ ++ lo = 0; ++ hi = ssymbuf2->count; ++ ssymbuf2++; ++ count2 = 0; ++ sec_count2 = 0; ++ while (lo < hi) ++ { ++ mid = (lo + hi) / 2; ++ if (shndx2 < ssymbuf2[mid].st_shndx) ++ hi = mid; ++ else if (shndx2 > ssymbuf2[mid].st_shndx) ++ lo = mid + 1; ++ else ++ { ++ count2 = ssymbuf2[mid].count; ++ ssymbuf2 += mid; ++ break; ++ } ++ } ++ if (ignore_section_symbol_p) ++ { ++ for (i = 0; i < count2; i++) ++ if (ELF_ST_TYPE (ssymbuf2->ssym[i].st_info) == STT_SECTION) ++ sec_count2++; ++ count2 -= sec_count2; ++ } ++ ++ if (count1 == 0 || count2 == 0 || count1 != count2) ++ goto done; ++ ++ symtable1 ++ = (struct elf_symbol *) bfd_malloc (count1 * sizeof (*symtable1)); ++ symtable2 ++ = (struct elf_symbol *) bfd_malloc (count2 * sizeof (*symtable2)); ++ if (symtable1 == NULL || symtable2 == NULL) ++ goto done; ++ ++ symp = symtable1; ++ for (ssym = ssymbuf1->ssym, ssymend = ssym + count1 + sec_count1; ++ ssym < ssymend; ssym++) ++ if (sec_count1 == 0 ++ || ELF_ST_TYPE (ssym->st_info) != STT_SECTION) ++ { ++ symp->u.ssym = ssym; ++ symp->name = bfd_elf_string_from_elf_section (bfd1, ++ hdr1->sh_link, ++ ssym->st_name); ++ symp++; ++ } ++ ++ symp = symtable2; ++ for (ssym = ssymbuf2->ssym, ssymend = ssym + count2 + sec_count2; ++ ssym < ssymend; ssym++) ++ if (sec_count2 == 0 ++ || ELF_ST_TYPE (ssym->st_info) != STT_SECTION) ++ { ++ symp->u.ssym = ssym; ++ symp->name = bfd_elf_string_from_elf_section (bfd2, ++ hdr2->sh_link, ++ ssym->st_name); ++ symp++; ++ } ++ ++ /* Sort symbol by name. */ ++ qsort (symtable1, count1, sizeof (struct elf_symbol), ++ elf_sym_name_compare); ++ qsort (symtable2, count1, sizeof (struct elf_symbol), ++ elf_sym_name_compare); ++ ++ for (i = 0; i < count1; i++) ++ /* Two symbols must have the same binding, type and name. */ ++ if (symtable1 [i].u.ssym->st_info != symtable2 [i].u.ssym->st_info ++ || symtable1 [i].u.ssym->st_other != symtable2 [i].u.ssym->st_other ++ || strcmp (symtable1 [i].name, symtable2 [i].name) != 0) ++ goto done; ++ ++ result = true; ++ goto done; ++ } ++ ++ symtable1 = (struct elf_symbol *) ++ bfd_malloc (symcount1 * sizeof (struct elf_symbol)); ++ symtable2 = (struct elf_symbol *) ++ bfd_malloc (symcount2 * sizeof (struct elf_symbol)); ++ if (symtable1 == NULL || symtable2 == NULL) ++ goto done; ++ ++ /* Count definitions in the section. */ ++ count1 = 0; ++ for (isym = isymbuf1, isymend = isym + symcount1; isym < isymend; isym++) ++ if (isym->st_shndx == shndx1 ++ && (!ignore_section_symbol_p ++ || ELF_ST_TYPE (isym->st_info) != STT_SECTION)) ++ symtable1[count1++].u.isym = isym; ++ ++ count2 = 0; ++ for (isym = isymbuf2, isymend = isym + symcount2; isym < isymend; isym++) ++ if (isym->st_shndx == shndx2 ++ && (!ignore_section_symbol_p ++ || ELF_ST_TYPE (isym->st_info) != STT_SECTION)) ++ symtable2[count2++].u.isym = isym; ++ ++ if (count1 == 0 || count2 == 0 || count1 != count2) ++ goto done; ++ ++ for (i = 0; i < count1; i++) ++ symtable1[i].name ++ = bfd_elf_string_from_elf_section (bfd1, hdr1->sh_link, ++ symtable1[i].u.isym->st_name); ++ ++ for (i = 0; i < count2; i++) ++ symtable2[i].name ++ = bfd_elf_string_from_elf_section (bfd2, hdr2->sh_link, ++ symtable2[i].u.isym->st_name); ++ ++ /* Sort symbol by name. */ ++ qsort (symtable1, count1, sizeof (struct elf_symbol), ++ elf_sym_name_compare); ++ qsort (symtable2, count1, sizeof (struct elf_symbol), ++ elf_sym_name_compare); ++ ++ for (i = 0; i < count1; i++) ++ /* Two symbols must have the same binding, type and name. */ ++ if (symtable1 [i].u.isym->st_info != symtable2 [i].u.isym->st_info ++ || symtable1 [i].u.isym->st_other != symtable2 [i].u.isym->st_other ++ || strcmp (symtable1 [i].name, symtable2 [i].name) != 0) ++ goto done; ++ ++ result = true; ++ ++ done: ++ free (symtable1); ++ free (symtable2); ++ free (isymbuf1); ++ free (isymbuf2); ++ ++ return result; ++} ++ ++/* Return TRUE if 2 section types are compatible. */ ++ ++bool ++_bfd_elf_match_sections_by_type (bfd *abfd, const asection *asec, ++ bfd *bbfd, const asection *bsec) ++{ ++ if (asec == NULL ++ || bsec == NULL ++ || abfd->xvec->flavour != bfd_target_elf_flavour ++ || bbfd->xvec->flavour != bfd_target_elf_flavour) ++ return true; ++ ++ return elf_section_type (asec) == elf_section_type (bsec); ++} ++ ++/* Final phase of ELF linker. */ ++ ++/* A structure we use to avoid passing large numbers of arguments. */ ++ ++struct elf_final_link_info ++{ ++ /* General link information. */ ++ struct bfd_link_info *info; ++ /* Output BFD. */ ++ bfd *output_bfd; ++ /* Symbol string table. */ ++ struct elf_strtab_hash *symstrtab; ++ /* .hash section. */ ++ asection *hash_sec; ++ /* symbol version section (.gnu.version). */ ++ asection *symver_sec; ++ /* Buffer large enough to hold contents of any section. */ ++ bfd_byte *contents; ++ /* Buffer large enough to hold external relocs of any section. */ ++ void *external_relocs; ++ /* Buffer large enough to hold internal relocs of any section. */ ++ Elf_Internal_Rela *internal_relocs; ++ /* Buffer large enough to hold external local symbols of any input ++ BFD. */ ++ bfd_byte *external_syms; ++ /* And a buffer for symbol section indices. */ ++ Elf_External_Sym_Shndx *locsym_shndx; ++ /* Buffer large enough to hold internal local symbols of any input ++ BFD. */ ++ Elf_Internal_Sym *internal_syms; ++ /* Array large enough to hold a symbol index for each local symbol ++ of any input BFD. */ ++ long *indices; ++ /* Array large enough to hold a section pointer for each local ++ symbol of any input BFD. */ ++ asection **sections; ++ /* Buffer for SHT_SYMTAB_SHNDX section. */ ++ Elf_External_Sym_Shndx *symshndxbuf; ++ /* Number of STT_FILE syms seen. */ ++ size_t filesym_count; ++ /* Local symbol hash table. */ ++ struct bfd_hash_table local_hash_table; ++}; ++ ++struct local_hash_entry ++{ ++ /* Base hash table entry structure. */ ++ struct bfd_hash_entry root; ++ /* Size of the local symbol name. */ ++ size_t size; ++ /* Number of the duplicated local symbol names. */ ++ long count; ++}; ++ ++/* Create an entry in the local symbol hash table. */ ++ ++static struct bfd_hash_entry * ++local_hash_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (entry == NULL) ++ { ++ entry = bfd_hash_allocate (table, ++ sizeof (struct local_hash_entry)); ++ if (entry == NULL) ++ return entry; ++ } ++ ++ /* Call the allocation method of the superclass. */ ++ entry = bfd_hash_newfunc (entry, table, string); ++ if (entry != NULL) ++ { ++ ((struct local_hash_entry *) entry)->count = 0; ++ ((struct local_hash_entry *) entry)->size = 0; ++ } ++ ++ return entry; ++} ++ ++/* This struct is used to pass information to elf_link_output_extsym. */ ++ ++struct elf_outext_info ++{ ++ bool failed; ++ bool localsyms; ++ bool file_sym_done; ++ struct elf_final_link_info *flinfo; ++}; ++ ++ ++/* Support for evaluating a complex relocation. ++ ++ Complex relocations are generalized, self-describing relocations. The ++ implementation of them consists of two parts: complex symbols, and the ++ relocations themselves. ++ ++ The relocations use a reserved elf-wide relocation type code (R_RELC ++ external / BFD_RELOC_RELC internal) and an encoding of relocation field ++ information (start bit, end bit, word width, etc) into the addend. This ++ information is extracted from CGEN-generated operand tables within gas. ++ ++ Complex symbols are mangled symbols (STT_RELC external / BSF_RELC ++ internal) representing prefix-notation expressions, including but not ++ limited to those sorts of expressions normally encoded as addends in the ++ addend field. The symbol mangling format is: ++ ++ := ++ | ':' ++ | ':' ':' ++ ; ++ ++ := 's' ':' ++ | 'S' ':' ++ | '#' ++ ; ++ ++ := as in C ++ := as in C, plus "0-" for unambiguous negation. */ ++ ++static void ++set_symbol_value (bfd *bfd_with_globals, ++ Elf_Internal_Sym *isymbuf, ++ size_t locsymcount, ++ size_t symidx, ++ bfd_vma val) ++{ ++ struct elf_link_hash_entry **sym_hashes; ++ struct elf_link_hash_entry *h; ++ size_t extsymoff = locsymcount; ++ ++ if (symidx < locsymcount) ++ { ++ Elf_Internal_Sym *sym; ++ ++ sym = isymbuf + symidx; ++ if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) ++ { ++ /* It is a local symbol: move it to the ++ "absolute" section and give it a value. */ ++ sym->st_shndx = SHN_ABS; ++ sym->st_value = val; ++ return; ++ } ++ BFD_ASSERT (elf_bad_symtab (bfd_with_globals)); ++ extsymoff = 0; ++ } ++ ++ /* It is a global symbol: set its link type ++ to "defined" and give it a value. */ ++ ++ sym_hashes = elf_sym_hashes (bfd_with_globals); ++ h = sym_hashes [symidx - extsymoff]; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ h->root.type = bfd_link_hash_defined; ++ h->root.u.def.value = val; ++ h->root.u.def.section = bfd_abs_section_ptr; ++} ++ ++static bool ++resolve_symbol (const char *name, ++ bfd *input_bfd, ++ struct elf_final_link_info *flinfo, ++ bfd_vma *result, ++ Elf_Internal_Sym *isymbuf, ++ size_t locsymcount) ++{ ++ Elf_Internal_Sym *sym; ++ struct bfd_link_hash_entry *global_entry; ++ const char *candidate = NULL; ++ Elf_Internal_Shdr *symtab_hdr; ++ size_t i; ++ ++ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; ++ ++ for (i = 0; i < locsymcount; ++ i) ++ { ++ sym = isymbuf + i; ++ ++ if (ELF_ST_BIND (sym->st_info) != STB_LOCAL) ++ continue; ++ ++ candidate = bfd_elf_string_from_elf_section (input_bfd, ++ symtab_hdr->sh_link, ++ sym->st_name); ++#ifdef DEBUG ++ printf ("Comparing string: '%s' vs. '%s' = 0x%lx\n", ++ name, candidate, (unsigned long) sym->st_value); ++#endif ++ if (candidate && strcmp (candidate, name) == 0) ++ { ++ asection *sec = flinfo->sections [i]; ++ ++ *result = _bfd_elf_rel_local_sym (input_bfd, sym, &sec, 0); ++ *result += sec->output_offset + sec->output_section->vma; ++#ifdef DEBUG ++ printf ("Found symbol with value %8.8lx\n", ++ (unsigned long) *result); ++#endif ++ return true; ++ } ++ } ++ ++ /* Hmm, haven't found it yet. perhaps it is a global. */ ++ global_entry = bfd_link_hash_lookup (flinfo->info->hash, name, ++ false, false, true); ++ if (!global_entry) ++ return false; ++ ++ if (global_entry->type == bfd_link_hash_defined ++ || global_entry->type == bfd_link_hash_defweak) ++ { ++ *result = (global_entry->u.def.value ++ + global_entry->u.def.section->output_section->vma ++ + global_entry->u.def.section->output_offset); ++#ifdef DEBUG ++ printf ("Found GLOBAL symbol '%s' with value %8.8lx\n", ++ global_entry->root.string, (unsigned long) *result); ++#endif ++ return true; ++ } ++ ++ return false; ++} ++ ++/* Looks up NAME in SECTIONS. If found sets RESULT to NAME's address (in ++ bytes) and returns TRUE, otherwise returns FALSE. Accepts pseudo-section ++ names like "foo.end" which is the end address of section "foo". */ ++ ++static bool ++resolve_section (const char *name, ++ asection *sections, ++ bfd_vma *result, ++ bfd * abfd) ++{ ++ asection *curr; ++ unsigned int len; ++ ++ for (curr = sections; curr; curr = curr->next) ++ if (strcmp (curr->name, name) == 0) ++ { ++ *result = curr->vma; ++ return true; ++ } ++ ++ /* Hmm. still haven't found it. try pseudo-section names. */ ++ /* FIXME: This could be coded more efficiently... */ ++ for (curr = sections; curr; curr = curr->next) ++ { ++ len = strlen (curr->name); ++ if (len > strlen (name)) ++ continue; ++ ++ if (strncmp (curr->name, name, len) == 0) ++ { ++ if (startswith (name + len, ".end")) ++ { ++ *result = (curr->vma ++ + curr->size / bfd_octets_per_byte (abfd, curr)); ++ return true; ++ } ++ ++ /* Insert more pseudo-section names here, if you like. */ ++ } ++ } ++ ++ return false; ++} ++ ++static void ++undefined_reference (const char *reftype, const char *name) ++{ ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("undefined %s reference in complex symbol: %s"), ++ reftype, name); ++ bfd_set_error (bfd_error_bad_value); ++} ++ ++static bool ++eval_symbol (bfd_vma *result, ++ const char **symp, ++ bfd *input_bfd, ++ struct elf_final_link_info *flinfo, ++ bfd_vma dot, ++ Elf_Internal_Sym *isymbuf, ++ size_t locsymcount, ++ int signed_p) ++{ ++ size_t len; ++ size_t symlen; ++ bfd_vma a; ++ bfd_vma b; ++ char symbuf[4096]; ++ const char *sym = *symp; ++ const char *symend; ++ bool symbol_is_section = false; ++ ++ len = strlen (sym); ++ symend = sym + len; ++ ++ if (len < 1 || len > sizeof (symbuf)) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ return false; ++ } ++ ++ switch (* sym) ++ { ++ case '.': ++ *result = dot; ++ *symp = sym + 1; ++ return true; ++ ++ case '#': ++ ++sym; ++ *result = strtoul (sym, (char **) symp, 16); ++ return true; ++ ++ case 'S': ++ symbol_is_section = true; ++ /* Fall through. */ ++ case 's': ++ ++sym; ++ symlen = strtol (sym, (char **) symp, 10); ++ sym = *symp + 1; /* Skip the trailing ':'. */ ++ ++ if (symend < sym || symlen + 1 > sizeof (symbuf)) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ return false; ++ } ++ ++ memcpy (symbuf, sym, symlen); ++ symbuf[symlen] = '\0'; ++ *symp = sym + symlen; ++ ++ /* Is it always possible, with complex symbols, that gas "mis-guessed" ++ the symbol as a section, or vice-versa. so we're pretty liberal in our ++ interpretation here; section means "try section first", not "must be a ++ section", and likewise with symbol. */ ++ ++ if (symbol_is_section) ++ { ++ if (!resolve_section (symbuf, flinfo->output_bfd->sections, result, input_bfd) ++ && !resolve_symbol (symbuf, input_bfd, flinfo, result, ++ isymbuf, locsymcount)) ++ { ++ undefined_reference ("section", symbuf); ++ return false; ++ } ++ } ++ else ++ { ++ if (!resolve_symbol (symbuf, input_bfd, flinfo, result, ++ isymbuf, locsymcount) ++ && !resolve_section (symbuf, flinfo->output_bfd->sections, ++ result, input_bfd)) ++ { ++ undefined_reference ("symbol", symbuf); ++ return false; ++ } ++ } ++ ++ return true; ++ ++ /* All that remains are operators. */ ++ ++#define UNARY_OP(op) \ ++ if (startswith (sym, #op)) \ ++ { \ ++ sym += strlen (#op); \ ++ if (*sym == ':') \ ++ ++sym; \ ++ *symp = sym; \ ++ if (!eval_symbol (&a, symp, input_bfd, flinfo, dot, \ ++ isymbuf, locsymcount, signed_p)) \ ++ return false; \ ++ if (signed_p) \ ++ *result = op ((bfd_signed_vma) a); \ ++ else \ ++ *result = op a; \ ++ return true; \ ++ } ++ ++#define BINARY_OP_HEAD(op) \ ++ if (startswith (sym, #op)) \ ++ { \ ++ sym += strlen (#op); \ ++ if (*sym == ':') \ ++ ++sym; \ ++ *symp = sym; \ ++ if (!eval_symbol (&a, symp, input_bfd, flinfo, dot, \ ++ isymbuf, locsymcount, signed_p)) \ ++ return false; \ ++ ++*symp; \ ++ if (!eval_symbol (&b, symp, input_bfd, flinfo, dot, \ ++ isymbuf, locsymcount, signed_p)) \ ++ return false; ++#define BINARY_OP_TAIL(op) \ ++ if (signed_p) \ ++ *result = ((bfd_signed_vma) a) op ((bfd_signed_vma) b); \ ++ else \ ++ *result = a op b; \ ++ return true; \ ++ } ++#define BINARY_OP(op) BINARY_OP_HEAD(op) BINARY_OP_TAIL(op) ++ ++ default: ++ UNARY_OP (0-); ++ BINARY_OP_HEAD (<<); ++ if (b >= sizeof (a) * CHAR_BIT) ++ { ++ *result = 0; ++ return true; ++ } ++ signed_p = 0; ++ BINARY_OP_TAIL (<<); ++ BINARY_OP_HEAD (>>); ++ if (b >= sizeof (a) * CHAR_BIT) ++ { ++ *result = signed_p && (bfd_signed_vma) a < 0 ? -1 : 0; ++ return true; ++ } ++ BINARY_OP_TAIL (>>); ++ BINARY_OP (==); ++ BINARY_OP (!=); ++ BINARY_OP (<=); ++ BINARY_OP (>=); ++ BINARY_OP (&&); ++ BINARY_OP (||); ++ UNARY_OP (~); ++ UNARY_OP (!); ++ BINARY_OP (*); ++ BINARY_OP_HEAD (/); ++ if (b == 0) ++ { ++ _bfd_error_handler (_("division by zero")); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ BINARY_OP_TAIL (/); ++ BINARY_OP_HEAD (%); ++ if (b == 0) ++ { ++ _bfd_error_handler (_("division by zero")); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ BINARY_OP_TAIL (%); ++ BINARY_OP (^); ++ BINARY_OP (|); ++ BINARY_OP (&); ++ BINARY_OP (+); ++ BINARY_OP (-); ++ BINARY_OP (<); ++ BINARY_OP (>); ++#undef UNARY_OP ++#undef BINARY_OP ++ _bfd_error_handler (_("unknown operator '%c' in complex symbol"), * sym); ++ bfd_set_error (bfd_error_invalid_operation); ++ return false; ++ } ++} ++ ++static void ++put_value (bfd_vma size, ++ unsigned long chunksz, ++ bfd *input_bfd, ++ bfd_vma x, ++ bfd_byte *location) ++{ ++ location += (size - chunksz); ++ ++ for (; size; size -= chunksz, location -= chunksz) ++ { ++ switch (chunksz) ++ { ++ case 1: ++ bfd_put_8 (input_bfd, x, location); ++ x >>= 8; ++ break; ++ case 2: ++ bfd_put_16 (input_bfd, x, location); ++ x >>= 16; ++ break; ++ case 4: ++ bfd_put_32 (input_bfd, x, location); ++ /* Computed this way because x >>= 32 is undefined if x is a 32-bit value. */ ++ x >>= 16; ++ x >>= 16; ++ break; ++#ifdef BFD64 ++ case 8: ++ bfd_put_64 (input_bfd, x, location); ++ /* Computed this way because x >>= 64 is undefined if x is a 64-bit value. */ ++ x >>= 32; ++ x >>= 32; ++ break; ++#endif ++ default: ++ abort (); ++ break; ++ } ++ } ++} ++ ++static bfd_vma ++get_value (bfd_vma size, ++ unsigned long chunksz, ++ bfd *input_bfd, ++ bfd_byte *location) ++{ ++ int shift; ++ bfd_vma x = 0; ++ ++ /* Sanity checks. */ ++ BFD_ASSERT (chunksz <= sizeof (x) ++ && size >= chunksz ++ && chunksz != 0 ++ && (size % chunksz) == 0 ++ && input_bfd != NULL ++ && location != NULL); ++ ++ if (chunksz == sizeof (x)) ++ { ++ BFD_ASSERT (size == chunksz); ++ ++ /* Make sure that we do not perform an undefined shift operation. ++ We know that size == chunksz so there will only be one iteration ++ of the loop below. */ ++ shift = 0; ++ } ++ else ++ shift = 8 * chunksz; ++ ++ for (; size; size -= chunksz, location += chunksz) ++ { ++ switch (chunksz) ++ { ++ case 1: ++ x = (x << shift) | bfd_get_8 (input_bfd, location); ++ break; ++ case 2: ++ x = (x << shift) | bfd_get_16 (input_bfd, location); ++ break; ++ case 4: ++ x = (x << shift) | bfd_get_32 (input_bfd, location); ++ break; ++#ifdef BFD64 ++ case 8: ++ x = (x << shift) | bfd_get_64 (input_bfd, location); ++ break; ++#endif ++ default: ++ abort (); ++ } ++ } ++ return x; ++} ++ ++static void ++decode_complex_addend (unsigned long *start, /* in bits */ ++ unsigned long *oplen, /* in bits */ ++ unsigned long *len, /* in bits */ ++ unsigned long *wordsz, /* in bytes */ ++ unsigned long *chunksz, /* in bytes */ ++ unsigned long *lsb0_p, ++ unsigned long *signed_p, ++ unsigned long *trunc_p, ++ unsigned long encoded) ++{ ++ * start = encoded & 0x3F; ++ * len = (encoded >> 6) & 0x3F; ++ * oplen = (encoded >> 12) & 0x3F; ++ * wordsz = (encoded >> 18) & 0xF; ++ * chunksz = (encoded >> 22) & 0xF; ++ * lsb0_p = (encoded >> 27) & 1; ++ * signed_p = (encoded >> 28) & 1; ++ * trunc_p = (encoded >> 29) & 1; ++} ++ ++bfd_reloc_status_type ++bfd_elf_perform_complex_relocation (bfd *input_bfd, ++ asection *input_section, ++ bfd_byte *contents, ++ Elf_Internal_Rela *rel, ++ bfd_vma relocation) ++{ ++ bfd_vma shift, x, mask; ++ unsigned long start, oplen, len, wordsz, chunksz, lsb0_p, signed_p, trunc_p; ++ bfd_reloc_status_type r; ++ bfd_size_type octets; ++ ++ /* Perform this reloc, since it is complex. ++ (this is not to say that it necessarily refers to a complex ++ symbol; merely that it is a self-describing CGEN based reloc. ++ i.e. the addend has the complete reloc information (bit start, end, ++ word size, etc) encoded within it.). */ ++ ++ decode_complex_addend (&start, &oplen, &len, &wordsz, ++ &chunksz, &lsb0_p, &signed_p, ++ &trunc_p, rel->r_addend); ++ ++ mask = (((1L << (len - 1)) - 1) << 1) | 1; ++ ++ if (lsb0_p) ++ shift = (start + 1) - len; ++ else ++ shift = (8 * wordsz) - (start + len); ++ ++ octets = rel->r_offset * bfd_octets_per_byte (input_bfd, input_section); ++ x = get_value (wordsz, chunksz, input_bfd, contents + octets); ++ ++#ifdef DEBUG ++ printf ("Doing complex reloc: " ++ "lsb0? %ld, signed? %ld, trunc? %ld, wordsz %ld, " ++ "chunksz %ld, start %ld, len %ld, oplen %ld\n" ++ " dest: %8.8lx, mask: %8.8lx, reloc: %8.8lx\n", ++ lsb0_p, signed_p, trunc_p, wordsz, chunksz, start, len, ++ oplen, (unsigned long) x, (unsigned long) mask, ++ (unsigned long) relocation); ++#endif ++ ++ r = bfd_reloc_ok; ++ if (! trunc_p) ++ /* Now do an overflow check. */ ++ r = bfd_check_overflow ((signed_p ++ ? complain_overflow_signed ++ : complain_overflow_unsigned), ++ len, 0, (8 * wordsz), ++ relocation); ++ ++ /* Do the deed. */ ++ x = (x & ~(mask << shift)) | ((relocation & mask) << shift); ++ ++#ifdef DEBUG ++ printf (" relocation: %8.8lx\n" ++ " shifted mask: %8.8lx\n" ++ " shifted/masked reloc: %8.8lx\n" ++ " result: %8.8lx\n", ++ (unsigned long) relocation, (unsigned long) (mask << shift), ++ (unsigned long) ((relocation & mask) << shift), (unsigned long) x); ++#endif ++ put_value (wordsz, chunksz, input_bfd, x, contents + octets); ++ return r; ++} ++ ++/* Functions to read r_offset from external (target order) reloc ++ entry. Faster than bfd_getl32 et al, because we let the compiler ++ know the value is aligned. */ ++ ++static bfd_vma ++ext32l_r_offset (const void *p) ++{ ++ union aligned32 ++ { ++ uint32_t v; ++ unsigned char c[4]; ++ }; ++ const union aligned32 *a ++ = (const union aligned32 *) &((const Elf32_External_Rel *) p)->r_offset; ++ ++ uint32_t aval = ( (uint32_t) a->c[0] ++ | (uint32_t) a->c[1] << 8 ++ | (uint32_t) a->c[2] << 16 ++ | (uint32_t) a->c[3] << 24); ++ return aval; ++} ++ ++static bfd_vma ++ext32b_r_offset (const void *p) ++{ ++ union aligned32 ++ { ++ uint32_t v; ++ unsigned char c[4]; ++ }; ++ const union aligned32 *a ++ = (const union aligned32 *) &((const Elf32_External_Rel *) p)->r_offset; ++ ++ uint32_t aval = ( (uint32_t) a->c[0] << 24 ++ | (uint32_t) a->c[1] << 16 ++ | (uint32_t) a->c[2] << 8 ++ | (uint32_t) a->c[3]); ++ return aval; ++} ++ ++static bfd_vma ++ext64l_r_offset (const void *p) ++{ ++ union aligned64 ++ { ++ uint64_t v; ++ unsigned char c[8]; ++ }; ++ const union aligned64 *a ++ = (const union aligned64 *) &((const Elf64_External_Rel *) p)->r_offset; ++ ++ uint64_t aval = ( (uint64_t) a->c[0] ++ | (uint64_t) a->c[1] << 8 ++ | (uint64_t) a->c[2] << 16 ++ | (uint64_t) a->c[3] << 24 ++ | (uint64_t) a->c[4] << 32 ++ | (uint64_t) a->c[5] << 40 ++ | (uint64_t) a->c[6] << 48 ++ | (uint64_t) a->c[7] << 56); ++ return aval; ++} ++ ++static bfd_vma ++ext64b_r_offset (const void *p) ++{ ++ union aligned64 ++ { ++ uint64_t v; ++ unsigned char c[8]; ++ }; ++ const union aligned64 *a ++ = (const union aligned64 *) &((const Elf64_External_Rel *) p)->r_offset; ++ ++ uint64_t aval = ( (uint64_t) a->c[0] << 56 ++ | (uint64_t) a->c[1] << 48 ++ | (uint64_t) a->c[2] << 40 ++ | (uint64_t) a->c[3] << 32 ++ | (uint64_t) a->c[4] << 24 ++ | (uint64_t) a->c[5] << 16 ++ | (uint64_t) a->c[6] << 8 ++ | (uint64_t) a->c[7]); ++ return aval; ++} ++ ++/* When performing a relocatable link, the input relocations are ++ preserved. But, if they reference global symbols, the indices ++ referenced must be updated. Update all the relocations found in ++ RELDATA. */ ++ ++static bool ++elf_link_adjust_relocs (bfd *abfd, ++ asection *sec, ++ struct bfd_elf_section_reloc_data *reldata, ++ bool sort, ++ struct bfd_link_info *info) ++{ ++ unsigned int i; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ bfd_byte *erela; ++ void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++ bfd_vma r_type_mask; ++ int r_sym_shift; ++ unsigned int count = reldata->count; ++ struct elf_link_hash_entry **rel_hash = reldata->hashes; ++ ++ if (reldata->hdr->sh_entsize == bed->s->sizeof_rel) ++ { ++ swap_in = bed->s->swap_reloc_in; ++ swap_out = bed->s->swap_reloc_out; ++ } ++ else if (reldata->hdr->sh_entsize == bed->s->sizeof_rela) ++ { ++ swap_in = bed->s->swap_reloca_in; ++ swap_out = bed->s->swap_reloca_out; ++ } ++ else ++ abort (); ++ ++ if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL) ++ abort (); ++ ++ if (bed->s->arch_size == 32) ++ { ++ r_type_mask = 0xff; ++ r_sym_shift = 8; ++ } ++ else ++ { ++ r_type_mask = 0xffffffff; ++ r_sym_shift = 32; ++ } ++ ++ erela = reldata->hdr->contents; ++ for (i = 0; i < count; i++, rel_hash++, erela += reldata->hdr->sh_entsize) ++ { ++ Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL]; ++ unsigned int j; ++ ++ if (*rel_hash == NULL) ++ continue; ++ ++ if ((*rel_hash)->indx == -2 ++ && info->gc_sections ++ && ! info->gc_keep_exported) ++ { ++ /* PR 21524: Let the user know if a symbol was removed by garbage collection. */ ++ _bfd_error_handler (_("%pB:%pA: error: relocation references symbol %s which was removed by garbage collection"), ++ abfd, sec, ++ (*rel_hash)->root.root.string); ++ _bfd_error_handler (_("%pB:%pA: error: try relinking with --gc-keep-exported enabled"), ++ abfd, sec); ++ bfd_set_error (bfd_error_invalid_operation); ++ return false; ++ } ++ BFD_ASSERT ((*rel_hash)->indx >= 0); ++ ++ (*swap_in) (abfd, erela, irela); ++ for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) ++ irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift ++ | (irela[j].r_info & r_type_mask)); ++ (*swap_out) (abfd, irela, erela); ++ } ++ ++ if (bed->elf_backend_update_relocs) ++ (*bed->elf_backend_update_relocs) (sec, reldata); ++ ++ if (sort && count != 0) ++ { ++ bfd_vma (*ext_r_off) (const void *); ++ bfd_vma r_off; ++ size_t elt_size; ++ bfd_byte *base, *end, *p, *loc; ++ bfd_byte *buf = NULL; ++ ++ if (bed->s->arch_size == 32) ++ { ++ if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE) ++ ext_r_off = ext32l_r_offset; ++ else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG) ++ ext_r_off = ext32b_r_offset; ++ else ++ abort (); ++ } ++ else ++ { ++ if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE) ++ ext_r_off = ext64l_r_offset; ++ else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG) ++ ext_r_off = ext64b_r_offset; ++ else ++ abort (); ++ } ++ ++ /* Must use a stable sort here. A modified insertion sort, ++ since the relocs are mostly sorted already. */ ++ elt_size = reldata->hdr->sh_entsize; ++ base = reldata->hdr->contents; ++ end = base + count * elt_size; ++ if (elt_size > sizeof (Elf64_External_Rela)) ++ abort (); ++ ++ /* Ensure the first element is lowest. This acts as a sentinel, ++ speeding the main loop below. */ ++ r_off = (*ext_r_off) (base); ++ for (p = loc = base; (p += elt_size) < end; ) ++ { ++ bfd_vma r_off2 = (*ext_r_off) (p); ++ if (r_off > r_off2) ++ { ++ r_off = r_off2; ++ loc = p; ++ } ++ } ++ if (loc != base) ++ { ++ /* Don't just swap *base and *loc as that changes the order ++ of the original base[0] and base[1] if they happen to ++ have the same r_offset. */ ++ bfd_byte onebuf[sizeof (Elf64_External_Rela)]; ++ memcpy (onebuf, loc, elt_size); ++ memmove (base + elt_size, base, loc - base); ++ memcpy (base, onebuf, elt_size); ++ } ++ ++ for (p = base + elt_size; (p += elt_size) < end; ) ++ { ++ /* base to p is sorted, *p is next to insert. */ ++ r_off = (*ext_r_off) (p); ++ /* Search the sorted region for location to insert. */ ++ loc = p - elt_size; ++ while (r_off < (*ext_r_off) (loc)) ++ loc -= elt_size; ++ loc += elt_size; ++ if (loc != p) ++ { ++ /* Chances are there is a run of relocs to insert here, ++ from one of more input files. Files are not always ++ linked in order due to the way elf_link_input_bfd is ++ called. See pr17666. */ ++ size_t sortlen = p - loc; ++ bfd_vma r_off2 = (*ext_r_off) (loc); ++ size_t runlen = elt_size; ++ bfd_vma r_off_runend = r_off; ++ bfd_vma r_off_runend_next; ++ size_t buf_size = 96 * 1024; ++ while (p + runlen < end ++ && (sortlen <= buf_size ++ || runlen + elt_size <= buf_size) ++ /* run must not break the ordering of base..loc+1 */ ++ && r_off2 > (r_off_runend_next = (*ext_r_off) (p + runlen)) ++ /* run must be already sorted */ ++ && r_off_runend_next >= r_off_runend) ++ { ++ runlen += elt_size; ++ r_off_runend = r_off_runend_next; ++ } ++ if (buf == NULL) ++ { ++ buf = bfd_malloc (buf_size); ++ if (buf == NULL) ++ return false; ++ } ++ if (runlen < sortlen) ++ { ++ memcpy (buf, p, runlen); ++ memmove (loc + runlen, loc, sortlen); ++ memcpy (loc, buf, runlen); ++ } ++ else ++ { ++ memcpy (buf, loc, sortlen); ++ memmove (loc, p, runlen); ++ memcpy (loc + runlen, buf, sortlen); ++ } ++ p += runlen - elt_size; ++ } ++ } ++ /* Hashes are no longer valid. */ ++ free (reldata->hashes); ++ reldata->hashes = NULL; ++ free (buf); ++ } ++ return true; ++} ++ ++struct elf_link_sort_rela ++{ ++ union { ++ bfd_vma offset; ++ bfd_vma sym_mask; ++ } u; ++ enum elf_reloc_type_class type; ++ /* We use this as an array of size int_rels_per_ext_rel. */ ++ Elf_Internal_Rela rela[1]; ++}; ++ ++/* qsort stability here and for cmp2 is only an issue if multiple ++ dynamic relocations are emitted at the same address. But targets ++ that apply a series of dynamic relocations each operating on the ++ result of the prior relocation can't use -z combreloc as ++ implemented anyway. Such schemes tend to be broken by sorting on ++ symbol index. That leaves dynamic NONE relocs as the only other ++ case where ld might emit multiple relocs at the same address, and ++ those are only emitted due to target bugs. */ ++ ++static int ++elf_link_sort_cmp1 (const void *A, const void *B) ++{ ++ const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A; ++ const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B; ++ int relativea, relativeb; ++ ++ relativea = a->type == reloc_class_relative; ++ relativeb = b->type == reloc_class_relative; ++ ++ if (relativea < relativeb) ++ return 1; ++ if (relativea > relativeb) ++ return -1; ++ if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask)) ++ return -1; ++ if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask)) ++ return 1; ++ if (a->rela->r_offset < b->rela->r_offset) ++ return -1; ++ if (a->rela->r_offset > b->rela->r_offset) ++ return 1; ++ return 0; ++} ++ ++static int ++elf_link_sort_cmp2 (const void *A, const void *B) ++{ ++ const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A; ++ const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B; ++ ++ if (a->type < b->type) ++ return -1; ++ if (a->type > b->type) ++ return 1; ++ if (a->u.offset < b->u.offset) ++ return -1; ++ if (a->u.offset > b->u.offset) ++ return 1; ++ if (a->rela->r_offset < b->rela->r_offset) ++ return -1; ++ if (a->rela->r_offset > b->rela->r_offset) ++ return 1; ++ return 0; ++} ++ ++static size_t ++elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) ++{ ++ asection *dynamic_relocs; ++ asection *rela_dyn; ++ asection *rel_dyn; ++ bfd_size_type count, size; ++ size_t i, ret, sort_elt, ext_size; ++ bfd_byte *sort, *s_non_relative, *p; ++ struct elf_link_sort_rela *sq; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ int i2e = bed->s->int_rels_per_ext_rel; ++ unsigned int opb = bfd_octets_per_byte (abfd, NULL); ++ void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); ++ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); ++ struct bfd_link_order *lo; ++ bfd_vma r_sym_mask; ++ bool use_rela; ++ ++ /* Find a dynamic reloc section. */ ++ rela_dyn = bfd_get_section_by_name (abfd, ".rela.dyn"); ++ rel_dyn = bfd_get_section_by_name (abfd, ".rel.dyn"); ++ if (rela_dyn != NULL && rela_dyn->size > 0 ++ && rel_dyn != NULL && rel_dyn->size > 0) ++ { ++ bool use_rela_initialised = false; ++ ++ /* This is just here to stop gcc from complaining. ++ Its initialization checking code is not perfect. */ ++ use_rela = true; ++ ++ /* Both sections are present. Examine the sizes ++ of the indirect sections to help us choose. */ ++ for (lo = rela_dyn->map_head.link_order; lo != NULL; lo = lo->next) ++ if (lo->type == bfd_indirect_link_order) ++ { ++ asection *o = lo->u.indirect.section; ++ ++ if ((o->size % bed->s->sizeof_rela) == 0) ++ { ++ if ((o->size % bed->s->sizeof_rel) == 0) ++ /* Section size is divisible by both rel and rela sizes. ++ It is of no help to us. */ ++ ; ++ else ++ { ++ /* Section size is only divisible by rela. */ ++ if (use_rela_initialised && !use_rela) ++ { ++ _bfd_error_handler (_("%pB: unable to sort relocs - " ++ "they are in more than one size"), ++ abfd); ++ bfd_set_error (bfd_error_invalid_operation); ++ return 0; ++ } ++ else ++ { ++ use_rela = true; ++ use_rela_initialised = true; ++ } ++ } ++ } ++ else if ((o->size % bed->s->sizeof_rel) == 0) ++ { ++ /* Section size is only divisible by rel. */ ++ if (use_rela_initialised && use_rela) ++ { ++ _bfd_error_handler (_("%pB: unable to sort relocs - " ++ "they are in more than one size"), ++ abfd); ++ bfd_set_error (bfd_error_invalid_operation); ++ return 0; ++ } ++ else ++ { ++ use_rela = false; ++ use_rela_initialised = true; ++ } ++ } ++ else ++ { ++ /* The section size is not divisible by either - ++ something is wrong. */ ++ _bfd_error_handler (_("%pB: unable to sort relocs - " ++ "they are of an unknown size"), abfd); ++ bfd_set_error (bfd_error_invalid_operation); ++ return 0; ++ } ++ } ++ ++ for (lo = rel_dyn->map_head.link_order; lo != NULL; lo = lo->next) ++ if (lo->type == bfd_indirect_link_order) ++ { ++ asection *o = lo->u.indirect.section; ++ ++ if ((o->size % bed->s->sizeof_rela) == 0) ++ { ++ if ((o->size % bed->s->sizeof_rel) == 0) ++ /* Section size is divisible by both rel and rela sizes. ++ It is of no help to us. */ ++ ; ++ else ++ { ++ /* Section size is only divisible by rela. */ ++ if (use_rela_initialised && !use_rela) ++ { ++ _bfd_error_handler (_("%pB: unable to sort relocs - " ++ "they are in more than one size"), ++ abfd); ++ bfd_set_error (bfd_error_invalid_operation); ++ return 0; ++ } ++ else ++ { ++ use_rela = true; ++ use_rela_initialised = true; ++ } ++ } ++ } ++ else if ((o->size % bed->s->sizeof_rel) == 0) ++ { ++ /* Section size is only divisible by rel. */ ++ if (use_rela_initialised && use_rela) ++ { ++ _bfd_error_handler (_("%pB: unable to sort relocs - " ++ "they are in more than one size"), ++ abfd); ++ bfd_set_error (bfd_error_invalid_operation); ++ return 0; ++ } ++ else ++ { ++ use_rela = false; ++ use_rela_initialised = true; ++ } ++ } ++ else ++ { ++ /* The section size is not divisible by either - ++ something is wrong. */ ++ _bfd_error_handler (_("%pB: unable to sort relocs - " ++ "they are of an unknown size"), abfd); ++ bfd_set_error (bfd_error_invalid_operation); ++ return 0; ++ } ++ } ++ ++ if (! use_rela_initialised) ++ /* Make a guess. */ ++ use_rela = true; ++ } ++ else if (rela_dyn != NULL && rela_dyn->size > 0) ++ use_rela = true; ++ else if (rel_dyn != NULL && rel_dyn->size > 0) ++ use_rela = false; ++ else ++ return 0; ++ ++ if (use_rela) ++ { ++ dynamic_relocs = rela_dyn; ++ ext_size = bed->s->sizeof_rela; ++ swap_in = bed->s->swap_reloca_in; ++ swap_out = bed->s->swap_reloca_out; ++ } ++ else ++ { ++ dynamic_relocs = rel_dyn; ++ ext_size = bed->s->sizeof_rel; ++ swap_in = bed->s->swap_reloc_in; ++ swap_out = bed->s->swap_reloc_out; ++ } ++ ++ size = 0; ++ for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) ++ if (lo->type == bfd_indirect_link_order) ++ size += lo->u.indirect.section->size; ++ ++ if (size != dynamic_relocs->size) ++ return 0; ++ ++ sort_elt = (sizeof (struct elf_link_sort_rela) ++ + (i2e - 1) * sizeof (Elf_Internal_Rela)); ++ ++ count = dynamic_relocs->size / ext_size; ++ if (count == 0) ++ return 0; ++ sort = (bfd_byte *) bfd_zmalloc (sort_elt * count); ++ ++ if (sort == NULL) ++ { ++ (*info->callbacks->warning) ++ (info, _("not enough memory to sort relocations"), 0, abfd, 0, 0); ++ return 0; ++ } ++ ++ if (bed->s->arch_size == 32) ++ r_sym_mask = ~(bfd_vma) 0xff; ++ else ++ r_sym_mask = ~(bfd_vma) 0xffffffff; ++ ++ for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) ++ if (lo->type == bfd_indirect_link_order) ++ { ++ bfd_byte *erel, *erelend; ++ asection *o = lo->u.indirect.section; ++ ++ if (o->contents == NULL && o->size != 0) ++ { ++ /* This is a reloc section that is being handled as a normal ++ section. See bfd_section_from_shdr. We can't combine ++ relocs in this case. */ ++ free (sort); ++ return 0; ++ } ++ erel = o->contents; ++ erelend = o->contents + o->size; ++ p = sort + o->output_offset * opb / ext_size * sort_elt; ++ ++ while (erel < erelend) ++ { ++ struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; ++ ++ (*swap_in) (abfd, erel, s->rela); ++ s->type = (*bed->elf_backend_reloc_type_class) (info, o, s->rela); ++ s->u.sym_mask = r_sym_mask; ++ p += sort_elt; ++ erel += ext_size; ++ } ++ } ++ ++ qsort (sort, count, sort_elt, elf_link_sort_cmp1); ++ ++ for (i = 0, p = sort; i < count; i++, p += sort_elt) ++ { ++ struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; ++ if (s->type != reloc_class_relative) ++ break; ++ } ++ ret = i; ++ s_non_relative = p; ++ ++ sq = (struct elf_link_sort_rela *) s_non_relative; ++ for (; i < count; i++, p += sort_elt) ++ { ++ struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p; ++ if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0) ++ sq = sp; ++ sp->u.offset = sq->rela->r_offset; ++ } ++ ++ qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2); ++ ++ struct elf_link_hash_table *htab = elf_hash_table (info); ++ if (htab->srelplt && htab->srelplt->output_section == dynamic_relocs) ++ { ++ /* We have plt relocs in .rela.dyn. */ ++ sq = (struct elf_link_sort_rela *) sort; ++ for (i = 0; i < count; i++) ++ if (sq[count - i - 1].type != reloc_class_plt) ++ break; ++ if (i != 0 && htab->srelplt->size == i * ext_size) ++ { ++ struct bfd_link_order **plo; ++ /* Put srelplt link_order last. This is so the output_offset ++ set in the next loop is correct for DT_JMPREL. */ ++ for (plo = &dynamic_relocs->map_head.link_order; *plo != NULL; ) ++ if ((*plo)->type == bfd_indirect_link_order ++ && (*plo)->u.indirect.section == htab->srelplt) ++ { ++ lo = *plo; ++ *plo = lo->next; ++ } ++ else ++ plo = &(*plo)->next; ++ *plo = lo; ++ lo->next = NULL; ++ dynamic_relocs->map_tail.link_order = lo; ++ } ++ } ++ ++ p = sort; ++ for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) ++ if (lo->type == bfd_indirect_link_order) ++ { ++ bfd_byte *erel, *erelend; ++ asection *o = lo->u.indirect.section; ++ ++ erel = o->contents; ++ erelend = o->contents + o->size; ++ o->output_offset = (p - sort) / sort_elt * ext_size / opb; ++ while (erel < erelend) ++ { ++ struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; ++ (*swap_out) (abfd, s->rela, erel); ++ p += sort_elt; ++ erel += ext_size; ++ } ++ } ++ ++ free (sort); ++ *psec = dynamic_relocs; ++ return ret; ++} ++ ++/* Add a symbol to the output symbol string table. */ ++ ++static int ++elf_link_output_symstrtab (void *finf, ++ const char *name, ++ Elf_Internal_Sym *elfsym, ++ asection *input_sec, ++ struct elf_link_hash_entry *h) ++{ ++ struct elf_final_link_info *flinfo = finf; ++ int (*output_symbol_hook) ++ (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *, ++ struct elf_link_hash_entry *); ++ struct elf_link_hash_table *hash_table; ++ const struct elf_backend_data *bed; ++ bfd_size_type strtabsize; ++ ++ BFD_ASSERT (elf_onesymtab (flinfo->output_bfd)); ++ ++ bed = get_elf_backend_data (flinfo->output_bfd); ++ output_symbol_hook = bed->elf_backend_link_output_symbol_hook; ++ if (output_symbol_hook != NULL) ++ { ++ int ret = (*output_symbol_hook) (flinfo->info, name, elfsym, input_sec, h); ++ if (ret != 1) ++ return ret; ++ } ++ ++ if (ELF_ST_TYPE (elfsym->st_info) == STT_GNU_IFUNC) ++ elf_tdata (flinfo->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc; ++ if (ELF_ST_BIND (elfsym->st_info) == STB_GNU_UNIQUE) ++ elf_tdata (flinfo->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_unique; ++ ++ if (name == NULL || *name == '\0') ++ elfsym->st_name = (unsigned long) -1; ++ else ++ { ++ /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize ++ to get the final offset for st_name. */ ++ char *versioned_name = (char *) name; ++ if (h != NULL) ++ { ++ if (h->versioned == versioned && h->def_dynamic) ++ { ++ /* Keep only one '@' for versioned symbols defined in ++ shared objects. */ ++ char *version = strrchr (name, ELF_VER_CHR); ++ char *base_end = strchr (name, ELF_VER_CHR); ++ if (version != base_end) ++ { ++ size_t base_len; ++ size_t len = strlen (name); ++ versioned_name = bfd_alloc (flinfo->output_bfd, len); ++ if (versioned_name == NULL) ++ return 0; ++ base_len = base_end - name; ++ memcpy (versioned_name, name, base_len); ++ memcpy (versioned_name + base_len, version, ++ len - base_len); ++ } ++ } ++ } ++ else if (flinfo->info->unique_symbol ++ && ELF_ST_BIND (elfsym->st_info) == STB_LOCAL) ++ { ++ struct local_hash_entry *lh; ++ size_t count_len; ++ size_t base_len; ++ char buf[30]; ++ switch (ELF_ST_TYPE (elfsym->st_info)) ++ { ++ case STT_FILE: ++ case STT_SECTION: ++ break; ++ default: ++ lh = (struct local_hash_entry *) bfd_hash_lookup ++ (&flinfo->local_hash_table, name, true, false); ++ if (lh == NULL) ++ return 0; ++ /* Always append ".COUNT" to local symbols to avoid ++ potential conflicts with local symbol "XXX.COUNT". */ ++ sprintf (buf, "%lx", lh->count); ++ base_len = lh->size; ++ if (!base_len) ++ { ++ base_len = strlen (name); ++ lh->size = base_len; ++ } ++ count_len = strlen (buf); ++ versioned_name = bfd_alloc (flinfo->output_bfd, ++ base_len + count_len + 2); ++ if (versioned_name == NULL) ++ return 0; ++ memcpy (versioned_name, name, base_len); ++ versioned_name[base_len] = '.'; ++ memcpy (versioned_name + base_len + 1, buf, ++ count_len + 1); ++ lh->count++; ++ break; ++ } ++ } ++ elfsym->st_name ++ = (unsigned long) _bfd_elf_strtab_add (flinfo->symstrtab, ++ versioned_name, false); ++ if (elfsym->st_name == (unsigned long) -1) ++ return 0; ++ } ++ ++ hash_table = elf_hash_table (flinfo->info); ++ strtabsize = hash_table->strtabsize; ++ if (strtabsize <= flinfo->output_bfd->symcount) ++ { ++ strtabsize += strtabsize; ++ hash_table->strtabsize = strtabsize; ++ strtabsize *= sizeof (*hash_table->strtab); ++ hash_table->strtab ++ = (struct elf_sym_strtab *) bfd_realloc (hash_table->strtab, ++ strtabsize); ++ if (hash_table->strtab == NULL) ++ return 0; ++ } ++ hash_table->strtab[flinfo->output_bfd->symcount].sym = *elfsym; ++ hash_table->strtab[flinfo->output_bfd->symcount].dest_index ++ = flinfo->output_bfd->symcount; ++ flinfo->output_bfd->symcount += 1; ++ ++ return 1; ++} ++ ++/* Swap symbols out to the symbol table and flush the output symbols to ++ the file. */ ++ ++static bool ++elf_link_swap_symbols_out (struct elf_final_link_info *flinfo) ++{ ++ struct elf_link_hash_table *hash_table = elf_hash_table (flinfo->info); ++ size_t amt; ++ size_t i; ++ const struct elf_backend_data *bed; ++ bfd_byte *symbuf; ++ Elf_Internal_Shdr *hdr; ++ file_ptr pos; ++ bool ret; ++ ++ if (flinfo->output_bfd->symcount == 0) ++ return true; ++ ++ BFD_ASSERT (elf_onesymtab (flinfo->output_bfd)); ++ ++ bed = get_elf_backend_data (flinfo->output_bfd); ++ ++ amt = bed->s->sizeof_sym * flinfo->output_bfd->symcount; ++ symbuf = (bfd_byte *) bfd_malloc (amt); ++ if (symbuf == NULL) ++ return false; ++ ++ if (flinfo->symshndxbuf) ++ { ++ amt = sizeof (Elf_External_Sym_Shndx); ++ amt *= bfd_get_symcount (flinfo->output_bfd); ++ flinfo->symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt); ++ if (flinfo->symshndxbuf == NULL) ++ { ++ free (symbuf); ++ return false; ++ } ++ } ++ ++ /* Now swap out the symbols. */ ++ for (i = 0; i < flinfo->output_bfd->symcount; i++) ++ { ++ struct elf_sym_strtab *elfsym = &hash_table->strtab[i]; ++ if (elfsym->sym.st_name == (unsigned long) -1) ++ elfsym->sym.st_name = 0; ++ else ++ elfsym->sym.st_name ++ = (unsigned long) _bfd_elf_strtab_offset (flinfo->symstrtab, ++ elfsym->sym.st_name); ++ ++ /* Inform the linker of the addition of this symbol. */ ++ ++ if (flinfo->info->callbacks->ctf_new_symbol) ++ flinfo->info->callbacks->ctf_new_symbol (elfsym->dest_index, ++ &elfsym->sym); ++ ++ bed->s->swap_symbol_out (flinfo->output_bfd, &elfsym->sym, ++ ((bfd_byte *) symbuf ++ + (elfsym->dest_index ++ * bed->s->sizeof_sym)), ++ NPTR_ADD (flinfo->symshndxbuf, ++ elfsym->dest_index)); ++ } ++ ++ hdr = &elf_tdata (flinfo->output_bfd)->symtab_hdr; ++ pos = hdr->sh_offset + hdr->sh_size; ++ amt = bed->s->sizeof_sym * flinfo->output_bfd->symcount; ++ if (bfd_seek (flinfo->output_bfd, pos, SEEK_SET) == 0 ++ && bfd_bwrite (symbuf, amt, flinfo->output_bfd) == amt) ++ { ++ hdr->sh_size += amt; ++ ret = true; ++ } ++ else ++ ret = false; ++ ++ free (symbuf); ++ ++ free (hash_table->strtab); ++ hash_table->strtab = NULL; ++ ++ return ret; ++} ++ ++/* Return TRUE if the dynamic symbol SYM in ABFD is supported. */ ++ ++static bool ++check_dynsym (bfd *abfd, Elf_Internal_Sym *sym) ++{ ++ if (sym->st_shndx >= (SHN_LORESERVE & 0xffff) ++ && sym->st_shndx < SHN_LORESERVE) ++ { ++ /* The gABI doesn't support dynamic symbols in output sections ++ beyond 64k. */ ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: too many sections: %d (>= %d)"), ++ abfd, bfd_count_sections (abfd), SHN_LORESERVE & 0xffff); ++ bfd_set_error (bfd_error_nonrepresentable_section); ++ return false; ++ } ++ return true; ++} ++ ++/* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in ++ allowing an unsatisfied unversioned symbol in the DSO to match a ++ versioned symbol that would normally require an explicit version. ++ We also handle the case that a DSO references a hidden symbol ++ which may be satisfied by a versioned symbol in another DSO. */ ++ ++static bool ++elf_link_check_versioned_symbol (struct bfd_link_info *info, ++ const struct elf_backend_data *bed, ++ struct elf_link_hash_entry *h) ++{ ++ bfd *abfd; ++ struct elf_link_loaded_list *loaded; ++ ++ if (!is_elf_hash_table (info->hash)) ++ return false; ++ ++ /* Check indirect symbol. */ ++ while (h->root.type == bfd_link_hash_indirect) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ switch (h->root.type) ++ { ++ default: ++ abfd = NULL; ++ break; ++ ++ case bfd_link_hash_undefined: ++ case bfd_link_hash_undefweak: ++ abfd = h->root.u.undef.abfd; ++ if (abfd == NULL ++ || (abfd->flags & DYNAMIC) == 0 ++ || (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) == 0) ++ return false; ++ break; ++ ++ case bfd_link_hash_defined: ++ case bfd_link_hash_defweak: ++ abfd = h->root.u.def.section->owner; ++ break; ++ ++ case bfd_link_hash_common: ++ abfd = h->root.u.c.p->section->owner; ++ break; ++ } ++ BFD_ASSERT (abfd != NULL); ++ ++ for (loaded = elf_hash_table (info)->dyn_loaded; ++ loaded != NULL; ++ loaded = loaded->next) ++ { ++ bfd *input; ++ Elf_Internal_Shdr *hdr; ++ size_t symcount; ++ size_t extsymcount; ++ size_t extsymoff; ++ Elf_Internal_Shdr *versymhdr; ++ Elf_Internal_Sym *isym; ++ Elf_Internal_Sym *isymend; ++ Elf_Internal_Sym *isymbuf; ++ Elf_External_Versym *ever; ++ Elf_External_Versym *extversym; ++ ++ input = loaded->abfd; ++ ++ /* We check each DSO for a possible hidden versioned definition. */ ++ if (input == abfd ++ || elf_dynversym (input) == 0) ++ continue; ++ ++ hdr = &elf_tdata (input)->dynsymtab_hdr; ++ ++ symcount = hdr->sh_size / bed->s->sizeof_sym; ++ if (elf_bad_symtab (input)) ++ { ++ extsymcount = symcount; ++ extsymoff = 0; ++ } ++ else ++ { ++ extsymcount = symcount - hdr->sh_info; ++ extsymoff = hdr->sh_info; ++ } ++ ++ if (extsymcount == 0) ++ continue; ++ ++ isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff, ++ NULL, NULL, NULL); ++ if (isymbuf == NULL) ++ return false; ++ ++ /* Read in any version definitions. */ ++ versymhdr = &elf_tdata (input)->dynversym_hdr; ++ if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0 ++ || (extversym = (Elf_External_Versym *) ++ _bfd_malloc_and_read (input, versymhdr->sh_size, ++ versymhdr->sh_size)) == NULL) ++ { ++ free (isymbuf); ++ return false; ++ } ++ ++ ever = extversym + extsymoff; ++ isymend = isymbuf + extsymcount; ++ for (isym = isymbuf; isym < isymend; isym++, ever++) ++ { ++ const char *name; ++ Elf_Internal_Versym iver; ++ unsigned short version_index; ++ ++ if (ELF_ST_BIND (isym->st_info) == STB_LOCAL ++ || isym->st_shndx == SHN_UNDEF) ++ continue; ++ ++ name = bfd_elf_string_from_elf_section (input, ++ hdr->sh_link, ++ isym->st_name); ++ if (strcmp (name, h->root.root.string) != 0) ++ continue; ++ ++ _bfd_elf_swap_versym_in (input, ever, &iver); ++ ++ if ((iver.vs_vers & VERSYM_HIDDEN) == 0 ++ && !(h->def_regular ++ && h->forced_local)) ++ { ++ /* If we have a non-hidden versioned sym, then it should ++ have provided a definition for the undefined sym unless ++ it is defined in a non-shared object and forced local. ++ */ ++ abort (); ++ } ++ ++ version_index = iver.vs_vers & VERSYM_VERSION; ++ if (version_index == 1 || version_index == 2) ++ { ++ /* This is the base or first version. We can use it. */ ++ free (extversym); ++ free (isymbuf); ++ return true; ++ } ++ } ++ ++ free (extversym); ++ free (isymbuf); ++ } ++ ++ return false; ++} ++ ++/* Convert ELF common symbol TYPE. */ ++ ++static int ++elf_link_convert_common_type (struct bfd_link_info *info, int type) ++{ ++ /* Commom symbol can only appear in relocatable link. */ ++ if (!bfd_link_relocatable (info)) ++ abort (); ++ switch (info->elf_stt_common) ++ { ++ case unchanged: ++ break; ++ case elf_stt_common: ++ type = STT_COMMON; ++ break; ++ case no_elf_stt_common: ++ type = STT_OBJECT; ++ break; ++ } ++ return type; ++} ++ ++/* Add an external symbol to the symbol table. This is called from ++ the hash table traversal routine. When generating a shared object, ++ we go through the symbol table twice. The first time we output ++ anything that might have been forced to local scope in a version ++ script. The second time we output the symbols that are still ++ global symbols. */ ++ ++static bool ++elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) ++{ ++ struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh; ++ struct elf_outext_info *eoinfo = (struct elf_outext_info *) data; ++ struct elf_final_link_info *flinfo = eoinfo->flinfo; ++ bool strip; ++ Elf_Internal_Sym sym; ++ asection *input_sec; ++ const struct elf_backend_data *bed; ++ long indx; ++ int ret; ++ unsigned int type; ++ ++ if (h->root.type == bfd_link_hash_warning) ++ { ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ if (h->root.type == bfd_link_hash_new) ++ return true; ++ } ++ ++ /* Decide whether to output this symbol in this pass. */ ++ if (eoinfo->localsyms) ++ { ++ if (!h->forced_local) ++ return true; ++ } ++ else ++ { ++ if (h->forced_local) ++ return true; ++ } ++ ++ bed = get_elf_backend_data (flinfo->output_bfd); ++ ++ if (h->root.type == bfd_link_hash_undefined) ++ { ++ /* If we have an undefined symbol reference here then it must have ++ come from a shared library that is being linked in. (Undefined ++ references in regular files have already been handled unless ++ they are in unreferenced sections which are removed by garbage ++ collection). */ ++ bool ignore_undef = false; ++ ++ /* Some symbols may be special in that the fact that they're ++ undefined can be safely ignored - let backend determine that. */ ++ if (bed->elf_backend_ignore_undef_symbol) ++ ignore_undef = bed->elf_backend_ignore_undef_symbol (h); ++ ++ /* If we are reporting errors for this situation then do so now. */ ++ if (!ignore_undef ++ && h->ref_dynamic_nonweak ++ && (!h->ref_regular || flinfo->info->gc_sections) ++ && !elf_link_check_versioned_symbol (flinfo->info, bed, h) ++ && flinfo->info->unresolved_syms_in_shared_libs != RM_IGNORE) ++ { ++ flinfo->info->callbacks->undefined_symbol ++ (flinfo->info, h->root.root.string, ++ h->ref_regular ? NULL : h->root.u.undef.abfd, NULL, 0, ++ flinfo->info->unresolved_syms_in_shared_libs == RM_DIAGNOSE ++ && !flinfo->info->warn_unresolved_syms); ++ } ++ ++ /* Strip a global symbol defined in a discarded section. */ ++ if (h->indx == -3) ++ return true; ++ } ++ ++ /* We should also warn if a forced local symbol is referenced from ++ shared libraries. */ ++ if (bfd_link_executable (flinfo->info) ++ && h->forced_local ++ && h->ref_dynamic ++ && h->def_regular ++ && !h->dynamic_def ++ && h->ref_dynamic_nonweak ++ && !elf_link_check_versioned_symbol (flinfo->info, bed, h)) ++ { ++ bfd *def_bfd; ++ const char *msg; ++ struct elf_link_hash_entry *hi = h; ++ ++ /* Check indirect symbol. */ ++ while (hi->root.type == bfd_link_hash_indirect) ++ hi = (struct elf_link_hash_entry *) hi->root.u.i.link; ++ ++ if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL) ++ /* xgettext:c-format */ ++ msg = _("%pB: internal symbol `%s' in %pB is referenced by DSO"); ++ else if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN) ++ /* xgettext:c-format */ ++ msg = _("%pB: hidden symbol `%s' in %pB is referenced by DSO"); ++ else ++ /* xgettext:c-format */ ++ msg = _("%pB: local symbol `%s' in %pB is referenced by DSO"); ++ def_bfd = flinfo->output_bfd; ++ if (hi->root.u.def.section != bfd_abs_section_ptr) ++ def_bfd = hi->root.u.def.section->owner; ++ _bfd_error_handler (msg, flinfo->output_bfd, ++ h->root.root.string, def_bfd); ++ bfd_set_error (bfd_error_bad_value); ++ eoinfo->failed = true; ++ return false; ++ } ++ ++ /* We don't want to output symbols that have never been mentioned by ++ a regular file, or that we have been told to strip. However, if ++ h->indx is set to -2, the symbol is used by a reloc and we must ++ output it. */ ++ strip = false; ++ if (h->indx == -2) ++ ; ++ else if ((h->def_dynamic ++ || h->ref_dynamic ++ || h->root.type == bfd_link_hash_new) ++ && !h->def_regular ++ && !h->ref_regular) ++ strip = true; ++ else if (flinfo->info->strip == strip_all) ++ strip = true; ++ else if (flinfo->info->strip == strip_some ++ && bfd_hash_lookup (flinfo->info->keep_hash, ++ h->root.root.string, false, false) == NULL) ++ strip = true; ++ else if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && ((flinfo->info->strip_discarded ++ && discarded_section (h->root.u.def.section)) ++ || ((h->root.u.def.section->flags & SEC_LINKER_CREATED) == 0 ++ && h->root.u.def.section->owner != NULL ++ && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0))) ++ strip = true; ++ else if ((h->root.type == bfd_link_hash_undefined ++ || h->root.type == bfd_link_hash_undefweak) ++ && h->root.u.undef.abfd != NULL ++ && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0) ++ strip = true; ++ ++ type = h->type; ++ ++ /* If we're stripping it, and it's not a dynamic symbol, there's ++ nothing else to do. However, if it is a forced local symbol or ++ an ifunc symbol we need to give the backend finish_dynamic_symbol ++ function a chance to make it dynamic. */ ++ if (strip ++ && h->dynindx == -1 ++ && type != STT_GNU_IFUNC ++ && !h->forced_local) ++ return true; ++ ++ sym.st_value = 0; ++ sym.st_size = h->size; ++ sym.st_other = h->other; ++ switch (h->root.type) ++ { ++ default: ++ case bfd_link_hash_new: ++ case bfd_link_hash_warning: ++ abort (); ++ return false; ++ ++ case bfd_link_hash_undefined: ++ case bfd_link_hash_undefweak: ++ input_sec = bfd_und_section_ptr; ++ sym.st_shndx = SHN_UNDEF; ++ break; ++ ++ case bfd_link_hash_defined: ++ case bfd_link_hash_defweak: ++ { ++ input_sec = h->root.u.def.section; ++ if (input_sec->output_section != NULL) ++ { ++ sym.st_shndx = ++ _bfd_elf_section_from_bfd_section (flinfo->output_bfd, ++ input_sec->output_section); ++ if (sym.st_shndx == SHN_BAD) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: could not find output section %pA for input section %pA"), ++ flinfo->output_bfd, input_sec->output_section, input_sec); ++ bfd_set_error (bfd_error_nonrepresentable_section); ++ eoinfo->failed = true; ++ return false; ++ } ++ ++ /* ELF symbols in relocatable files are section relative, ++ but in nonrelocatable files they are virtual ++ addresses. */ ++ sym.st_value = h->root.u.def.value + input_sec->output_offset; ++ if (!bfd_link_relocatable (flinfo->info)) ++ { ++ sym.st_value += input_sec->output_section->vma; ++ if (h->type == STT_TLS) ++ { ++ asection *tls_sec = elf_hash_table (flinfo->info)->tls_sec; ++ if (tls_sec != NULL) ++ sym.st_value -= tls_sec->vma; ++ } ++ } ++ } ++ else ++ { ++ BFD_ASSERT (input_sec->owner == NULL ++ || (input_sec->owner->flags & DYNAMIC) != 0); ++ sym.st_shndx = SHN_UNDEF; ++ input_sec = bfd_und_section_ptr; ++ } ++ } ++ break; ++ ++ case bfd_link_hash_common: ++ input_sec = h->root.u.c.p->section; ++ sym.st_shndx = bed->common_section_index (input_sec); ++ sym.st_value = 1 << h->root.u.c.p->alignment_power; ++ break; ++ ++ case bfd_link_hash_indirect: ++ /* These symbols are created by symbol versioning. They point ++ to the decorated version of the name. For example, if the ++ symbol foo@@GNU_1.2 is the default, which should be used when ++ foo is used with no version, then we add an indirect symbol ++ foo which points to foo@@GNU_1.2. We ignore these symbols, ++ since the indirected symbol is already in the hash table. */ ++ return true; ++ } ++ ++ if (type == STT_COMMON || type == STT_OBJECT) ++ switch (h->root.type) ++ { ++ case bfd_link_hash_common: ++ type = elf_link_convert_common_type (flinfo->info, type); ++ break; ++ case bfd_link_hash_defined: ++ case bfd_link_hash_defweak: ++ if (bed->common_definition (&sym)) ++ type = elf_link_convert_common_type (flinfo->info, type); ++ else ++ type = STT_OBJECT; ++ break; ++ case bfd_link_hash_undefined: ++ case bfd_link_hash_undefweak: ++ break; ++ default: ++ abort (); ++ } ++ ++ if (h->forced_local) ++ { ++ sym.st_info = ELF_ST_INFO (STB_LOCAL, type); ++ /* Turn off visibility on local symbol. */ ++ sym.st_other &= ~ELF_ST_VISIBILITY (-1); ++ } ++ /* Set STB_GNU_UNIQUE only if symbol is defined in regular object. */ ++ else if (h->unique_global && h->def_regular) ++ sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, type); ++ else if (h->root.type == bfd_link_hash_undefweak ++ || h->root.type == bfd_link_hash_defweak) ++ sym.st_info = ELF_ST_INFO (STB_WEAK, type); ++ else ++ sym.st_info = ELF_ST_INFO (STB_GLOBAL, type); ++ sym.st_target_internal = h->target_internal; ++ ++ /* Give the processor backend a chance to tweak the symbol value, ++ and also to finish up anything that needs to be done for this ++ symbol. FIXME: Not calling elf_backend_finish_dynamic_symbol for ++ forced local syms when non-shared is due to a historical quirk. ++ STT_GNU_IFUNC symbol must go through PLT. */ ++ if ((h->type == STT_GNU_IFUNC ++ && h->def_regular ++ && !bfd_link_relocatable (flinfo->info)) ++ || ((h->dynindx != -1 ++ || h->forced_local) ++ && ((bfd_link_pic (flinfo->info) ++ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT ++ || h->root.type != bfd_link_hash_undefweak)) ++ || !h->forced_local) ++ && elf_hash_table (flinfo->info)->dynamic_sections_created)) ++ { ++ if (! ((*bed->elf_backend_finish_dynamic_symbol) ++ (flinfo->output_bfd, flinfo->info, h, &sym))) ++ { ++ eoinfo->failed = true; ++ return false; ++ } ++ } ++ ++ /* If we are marking the symbol as undefined, and there are no ++ non-weak references to this symbol from a regular object, then ++ mark the symbol as weak undefined; if there are non-weak ++ references, mark the symbol as strong. We can't do this earlier, ++ because it might not be marked as undefined until the ++ finish_dynamic_symbol routine gets through with it. */ ++ if (sym.st_shndx == SHN_UNDEF ++ && h->ref_regular ++ && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL ++ || ELF_ST_BIND (sym.st_info) == STB_WEAK)) ++ { ++ int bindtype; ++ type = ELF_ST_TYPE (sym.st_info); ++ ++ /* Turn an undefined IFUNC symbol into a normal FUNC symbol. */ ++ if (type == STT_GNU_IFUNC) ++ type = STT_FUNC; ++ ++ if (h->ref_regular_nonweak) ++ bindtype = STB_GLOBAL; ++ else ++ bindtype = STB_WEAK; ++ sym.st_info = ELF_ST_INFO (bindtype, type); ++ } ++ ++ /* If this is a symbol defined in a dynamic library, don't use the ++ symbol size from the dynamic library. Relinking an executable ++ against a new library may introduce gratuitous changes in the ++ executable's symbols if we keep the size. */ ++ if (sym.st_shndx == SHN_UNDEF ++ && !h->def_regular ++ && h->def_dynamic) ++ sym.st_size = 0; ++ ++ /* If a non-weak symbol with non-default visibility is not defined ++ locally, it is a fatal error. */ ++ if (!bfd_link_relocatable (flinfo->info) ++ && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT ++ && ELF_ST_BIND (sym.st_info) != STB_WEAK ++ && h->root.type == bfd_link_hash_undefined ++ && !h->def_regular) ++ { ++ const char *msg; ++ ++ if (ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED) ++ /* xgettext:c-format */ ++ msg = _("%pB: protected symbol `%s' isn't defined"); ++ else if (ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL) ++ /* xgettext:c-format */ ++ msg = _("%pB: internal symbol `%s' isn't defined"); ++ else ++ /* xgettext:c-format */ ++ msg = _("%pB: hidden symbol `%s' isn't defined"); ++ _bfd_error_handler (msg, flinfo->output_bfd, h->root.root.string); ++ bfd_set_error (bfd_error_bad_value); ++ eoinfo->failed = true; ++ return false; ++ } ++ ++ /* If this symbol should be put in the .dynsym section, then put it ++ there now. We already know the symbol index. We also fill in ++ the entry in the .hash section. */ ++ if (h->dynindx != -1 ++ && elf_hash_table (flinfo->info)->dynamic_sections_created ++ && elf_hash_table (flinfo->info)->dynsym != NULL ++ && !discarded_section (elf_hash_table (flinfo->info)->dynsym)) ++ { ++ bfd_byte *esym; ++ ++ /* Since there is no version information in the dynamic string, ++ if there is no version info in symbol version section, we will ++ have a run-time problem if not linking executable, referenced ++ by shared library, or not bound locally. */ ++ if (h->verinfo.verdef == NULL ++ && (!bfd_link_executable (flinfo->info) ++ || h->ref_dynamic ++ || !h->def_regular)) ++ { ++ char *p = strrchr (h->root.root.string, ELF_VER_CHR); ++ ++ if (p && p [1] != '\0') ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: no symbol version section for versioned symbol `%s'"), ++ flinfo->output_bfd, h->root.root.string); ++ eoinfo->failed = true; ++ return false; ++ } ++ } ++ ++ sym.st_name = h->dynstr_index; ++ esym = (elf_hash_table (flinfo->info)->dynsym->contents ++ + h->dynindx * bed->s->sizeof_sym); ++ if (!check_dynsym (flinfo->output_bfd, &sym)) ++ { ++ eoinfo->failed = true; ++ return false; ++ } ++ ++ /* Inform the linker of the addition of this symbol. */ ++ ++ if (flinfo->info->callbacks->ctf_new_dynsym) ++ flinfo->info->callbacks->ctf_new_dynsym (h->dynindx, &sym); ++ ++ bed->s->swap_symbol_out (flinfo->output_bfd, &sym, esym, 0); ++ ++ if (flinfo->hash_sec != NULL) ++ { ++ size_t hash_entry_size; ++ bfd_byte *bucketpos; ++ bfd_vma chain; ++ size_t bucketcount; ++ size_t bucket; ++ ++ bucketcount = elf_hash_table (flinfo->info)->bucketcount; ++ bucket = h->u.elf_hash_value % bucketcount; ++ ++ hash_entry_size ++ = elf_section_data (flinfo->hash_sec)->this_hdr.sh_entsize; ++ bucketpos = ((bfd_byte *) flinfo->hash_sec->contents ++ + (bucket + 2) * hash_entry_size); ++ chain = bfd_get (8 * hash_entry_size, flinfo->output_bfd, bucketpos); ++ bfd_put (8 * hash_entry_size, flinfo->output_bfd, h->dynindx, ++ bucketpos); ++ bfd_put (8 * hash_entry_size, flinfo->output_bfd, chain, ++ ((bfd_byte *) flinfo->hash_sec->contents ++ + (bucketcount + 2 + h->dynindx) * hash_entry_size)); ++ } ++ ++ if (flinfo->symver_sec != NULL && flinfo->symver_sec->contents != NULL) ++ { ++ Elf_Internal_Versym iversym; ++ Elf_External_Versym *eversym; ++ ++ if (!h->def_regular && !ELF_COMMON_DEF_P (h)) ++ { ++ if (h->verinfo.verdef == NULL ++ || (elf_dyn_lib_class (h->verinfo.verdef->vd_bfd) ++ & (DYN_AS_NEEDED | DYN_DT_NEEDED | DYN_NO_NEEDED))) ++ iversym.vs_vers = 1; ++ else ++ iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1; ++ } ++ else ++ { ++ if (h->verinfo.vertree == NULL) ++ iversym.vs_vers = 1; ++ else ++ iversym.vs_vers = h->verinfo.vertree->vernum + 1; ++ if (flinfo->info->create_default_symver) ++ iversym.vs_vers++; ++ } ++ ++ /* Turn on VERSYM_HIDDEN only if the hidden versioned symbol is ++ defined locally. */ ++ if (h->versioned == versioned_hidden && h->def_regular) ++ iversym.vs_vers |= VERSYM_HIDDEN; ++ ++ eversym = (Elf_External_Versym *) flinfo->symver_sec->contents; ++ eversym += h->dynindx; ++ _bfd_elf_swap_versym_out (flinfo->output_bfd, &iversym, eversym); ++ } ++ } ++ ++ /* If the symbol is undefined, and we didn't output it to .dynsym, ++ strip it from .symtab too. Obviously we can't do this for ++ relocatable output or when needed for --emit-relocs. */ ++ else if (input_sec == bfd_und_section_ptr ++ && h->indx != -2 ++ /* PR 22319 Do not strip global undefined symbols marked as being needed. */ ++ && (h->mark != 1 || ELF_ST_BIND (sym.st_info) != STB_GLOBAL) ++ && !bfd_link_relocatable (flinfo->info)) ++ return true; ++ ++ /* Also strip others that we couldn't earlier due to dynamic symbol ++ processing. */ ++ if (strip) ++ return true; ++ if ((input_sec->flags & SEC_EXCLUDE) != 0) ++ return true; ++ ++ /* Output a FILE symbol so that following locals are not associated ++ with the wrong input file. We need one for forced local symbols ++ if we've seen more than one FILE symbol or when we have exactly ++ one FILE symbol but global symbols are present in a file other ++ than the one with the FILE symbol. We also need one if linker ++ defined symbols are present. In practice these conditions are ++ always met, so just emit the FILE symbol unconditionally. */ ++ if (eoinfo->localsyms ++ && !eoinfo->file_sym_done ++ && eoinfo->flinfo->filesym_count != 0) ++ { ++ Elf_Internal_Sym fsym; ++ ++ memset (&fsym, 0, sizeof (fsym)); ++ fsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); ++ fsym.st_shndx = SHN_ABS; ++ if (!elf_link_output_symstrtab (eoinfo->flinfo, NULL, &fsym, ++ bfd_und_section_ptr, NULL)) ++ return false; ++ ++ eoinfo->file_sym_done = true; ++ } ++ ++ indx = bfd_get_symcount (flinfo->output_bfd); ++ ret = elf_link_output_symstrtab (flinfo, h->root.root.string, &sym, ++ input_sec, h); ++ if (ret == 0) ++ { ++ eoinfo->failed = true; ++ return false; ++ } ++ else if (ret == 1) ++ h->indx = indx; ++ else if (h->indx == -2) ++ abort(); ++ ++ return true; ++} ++ ++/* Return TRUE if special handling is done for relocs in SEC against ++ symbols defined in discarded sections. */ ++ ++static bool ++elf_section_ignore_discarded_relocs (asection *sec) ++{ ++ const struct elf_backend_data *bed; ++ ++ switch (sec->sec_info_type) ++ { ++ case SEC_INFO_TYPE_STABS: ++ case SEC_INFO_TYPE_EH_FRAME: ++ case SEC_INFO_TYPE_EH_FRAME_ENTRY: ++ case SEC_INFO_TYPE_SFRAME: ++ return true; ++ default: ++ break; ++ } ++ ++ bed = get_elf_backend_data (sec->owner); ++ if (bed->elf_backend_ignore_discarded_relocs != NULL ++ && (*bed->elf_backend_ignore_discarded_relocs) (sec)) ++ return true; ++ ++ return false; ++} ++ ++/* Return a mask saying how ld should treat relocations in SEC against ++ symbols defined in discarded sections. If this function returns ++ COMPLAIN set, ld will issue a warning message. If this function ++ returns PRETEND set, and the discarded section was link-once and the ++ same size as the kept link-once section, ld will pretend that the ++ symbol was actually defined in the kept section. Otherwise ld will ++ zero the reloc (at least that is the intent, but some cooperation by ++ the target dependent code is needed, particularly for REL targets). */ ++ ++unsigned int ++_bfd_elf_default_action_discarded (asection *sec) ++{ ++ const struct elf_backend_data *bed; ++ bed = get_elf_backend_data (sec->owner); ++ ++ if (sec->flags & SEC_DEBUGGING) ++ return PRETEND; ++ ++ if (strcmp (".eh_frame", sec->name) == 0) ++ return 0; ++ ++ if (bed->elf_backend_can_make_multiple_eh_frame ++ && strncmp (sec->name, ".eh_frame.", 10) == 0) ++ return 0; ++ ++ if (strcmp (".sframe", sec->name) == 0) ++ return 0; ++ ++ if (strcmp (".gcc_except_table", sec->name) == 0) ++ return 0; ++ ++ return COMPLAIN | PRETEND; ++} ++ ++/* Find a match between a section and a member of a section group. */ ++ ++static asection * ++match_group_member (asection *sec, asection *group, ++ struct bfd_link_info *info) ++{ ++ asection *first = elf_next_in_group (group); ++ asection *s = first; ++ ++ while (s != NULL) ++ { ++ if (bfd_elf_match_symbols_in_sections (s, sec, info)) ++ return s; ++ ++ s = elf_next_in_group (s); ++ if (s == first) ++ break; ++ } ++ ++ return NULL; ++} ++ ++/* Check if the kept section of a discarded section SEC can be used ++ to replace it. Return the replacement if it is OK. Otherwise return ++ NULL. */ ++ ++asection * ++_bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info) ++{ ++ asection *kept; ++ ++ kept = sec->kept_section; ++ if (kept != NULL) ++ { ++ if ((kept->flags & SEC_GROUP) != 0) ++ kept = match_group_member (sec, kept, info); ++ if (kept != NULL) ++ { ++ if ((sec->rawsize != 0 ? sec->rawsize : sec->size) ++ != (kept->rawsize != 0 ? kept->rawsize : kept->size)) ++ kept = NULL; ++ else ++ { ++ /* Get the real kept section. */ ++ asection *next; ++ for (next = kept->kept_section; ++ next != NULL; ++ next = next->kept_section) ++ kept = next; ++ } ++ } ++ sec->kept_section = kept; ++ } ++ return kept; ++} ++ ++/* Link an input file into the linker output file. This function ++ handles all the sections and relocations of the input file at once. ++ This is so that we only have to read the local symbols once, and ++ don't have to keep them in memory. */ ++ ++static bool ++elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) ++{ ++ int (*relocate_section) ++ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, ++ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); ++ bfd *output_bfd; ++ Elf_Internal_Shdr *symtab_hdr; ++ size_t locsymcount; ++ size_t extsymoff; ++ Elf_Internal_Sym *isymbuf; ++ Elf_Internal_Sym *isym; ++ Elf_Internal_Sym *isymend; ++ long *pindex; ++ asection **ppsection; ++ asection *o; ++ const struct elf_backend_data *bed; ++ struct elf_link_hash_entry **sym_hashes; ++ bfd_size_type address_size; ++ bfd_vma r_type_mask; ++ int r_sym_shift; ++ bool have_file_sym = false; ++ ++ output_bfd = flinfo->output_bfd; ++ bed = get_elf_backend_data (output_bfd); ++ relocate_section = bed->elf_backend_relocate_section; ++ ++ /* If this is a dynamic object, we don't want to do anything here: ++ we don't want the local symbols, and we don't want the section ++ contents. */ ++ if ((input_bfd->flags & DYNAMIC) != 0) ++ return true; ++ ++ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; ++ if (elf_bad_symtab (input_bfd)) ++ { ++ locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; ++ extsymoff = 0; ++ } ++ else ++ { ++ locsymcount = symtab_hdr->sh_info; ++ extsymoff = symtab_hdr->sh_info; ++ } ++ ++ /* Enable GNU OSABI features in the output BFD that are used in the input ++ BFD. */ ++ if (bed->elf_osabi == ELFOSABI_NONE ++ || bed->elf_osabi == ELFOSABI_GNU ++ || bed->elf_osabi == ELFOSABI_FREEBSD) ++ elf_tdata (output_bfd)->has_gnu_osabi ++ |= (elf_tdata (input_bfd)->has_gnu_osabi ++ & (bfd_link_relocatable (flinfo->info) ++ ? -1 : ~elf_gnu_osabi_retain)); ++ ++ /* Read the local symbols. */ ++ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; ++ if (isymbuf == NULL && locsymcount != 0) ++ { ++ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, ++ flinfo->internal_syms, ++ flinfo->external_syms, ++ flinfo->locsym_shndx); ++ if (isymbuf == NULL) ++ return false; ++ } ++ ++ /* Find local symbol sections and adjust values of symbols in ++ SEC_MERGE sections. Write out those local symbols we know are ++ going into the output file. */ ++ isymend = PTR_ADD (isymbuf, locsymcount); ++ for (isym = isymbuf, pindex = flinfo->indices, ppsection = flinfo->sections; ++ isym < isymend; ++ isym++, pindex++, ppsection++) ++ { ++ asection *isec; ++ const char *name; ++ Elf_Internal_Sym osym; ++ long indx; ++ int ret; ++ ++ *pindex = -1; ++ ++ if (elf_bad_symtab (input_bfd)) ++ { ++ if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) ++ { ++ *ppsection = NULL; ++ continue; ++ } ++ } ++ ++ if (isym->st_shndx == SHN_UNDEF) ++ isec = bfd_und_section_ptr; ++ else if (isym->st_shndx == SHN_ABS) ++ isec = bfd_abs_section_ptr; ++ else if (isym->st_shndx == SHN_COMMON) ++ isec = bfd_com_section_ptr; ++ else ++ { ++ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); ++ if (isec == NULL) ++ { ++ /* Don't attempt to output symbols with st_shnx in the ++ reserved range other than SHN_ABS and SHN_COMMON. */ ++ isec = bfd_und_section_ptr; ++ } ++ else if (isec->sec_info_type == SEC_INFO_TYPE_MERGE ++ && ELF_ST_TYPE (isym->st_info) != STT_SECTION) ++ isym->st_value = ++ _bfd_merged_section_offset (output_bfd, &isec, ++ elf_section_data (isec)->sec_info, ++ isym->st_value); ++ } ++ ++ *ppsection = isec; ++ ++ /* Don't output the first, undefined, symbol. In fact, don't ++ output any undefined local symbol. */ ++ if (isec == bfd_und_section_ptr) ++ continue; ++ ++ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) ++ { ++ /* We never output section symbols. Instead, we use the ++ section symbol of the corresponding section in the output ++ file. */ ++ continue; ++ } ++ ++ /* If we are stripping all symbols, we don't want to output this ++ one. */ ++ if (flinfo->info->strip == strip_all) ++ continue; ++ ++ /* If we are discarding all local symbols, we don't want to ++ output this one. If we are generating a relocatable output ++ file, then some of the local symbols may be required by ++ relocs; we output them below as we discover that they are ++ needed. */ ++ if (flinfo->info->discard == discard_all) ++ continue; ++ ++ /* If this symbol is defined in a section which we are ++ discarding, we don't need to keep it. */ ++ if (isym->st_shndx < SHN_LORESERVE ++ && (isec->output_section == NULL ++ || bfd_section_removed_from_list (output_bfd, ++ isec->output_section))) ++ continue; ++ ++ /* Get the name of the symbol. */ ++ name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, ++ isym->st_name); ++ if (name == NULL) ++ return false; ++ ++ /* See if we are discarding symbols with this name. */ ++ if ((flinfo->info->strip == strip_some ++ && (bfd_hash_lookup (flinfo->info->keep_hash, name, false, false) ++ == NULL)) ++ || (((flinfo->info->discard == discard_sec_merge ++ && (isec->flags & SEC_MERGE) ++ && !bfd_link_relocatable (flinfo->info)) ++ || flinfo->info->discard == discard_l) ++ && bfd_is_local_label_name (input_bfd, name))) ++ continue; ++ ++ if (ELF_ST_TYPE (isym->st_info) == STT_FILE) ++ { ++ if (input_bfd->lto_output) ++ /* -flto puts a temp file name here. This means builds ++ are not reproducible. Discard the symbol. */ ++ continue; ++ have_file_sym = true; ++ flinfo->filesym_count += 1; ++ } ++ if (!have_file_sym) ++ { ++ /* In the absence of debug info, bfd_find_nearest_line uses ++ FILE symbols to determine the source file for local ++ function symbols. Provide a FILE symbol here if input ++ files lack such, so that their symbols won't be ++ associated with a previous input file. It's not the ++ source file, but the best we can do. */ ++ const char *filename; ++ have_file_sym = true; ++ flinfo->filesym_count += 1; ++ memset (&osym, 0, sizeof (osym)); ++ osym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); ++ osym.st_shndx = SHN_ABS; ++ if (input_bfd->lto_output) ++ filename = NULL; ++ else ++ filename = lbasename (bfd_get_filename (input_bfd)); ++ if (!elf_link_output_symstrtab (flinfo, filename, &osym, ++ bfd_abs_section_ptr, NULL)) ++ return false; ++ } ++ ++ osym = *isym; ++ ++ /* Adjust the section index for the output file. */ ++ osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, ++ isec->output_section); ++ if (osym.st_shndx == SHN_BAD) ++ return false; ++ ++ /* ELF symbols in relocatable files are section relative, but ++ in executable files they are virtual addresses. Note that ++ this code assumes that all ELF sections have an associated ++ BFD section with a reasonable value for output_offset; below ++ we assume that they also have a reasonable value for ++ output_section. Any special sections must be set up to meet ++ these requirements. */ ++ osym.st_value += isec->output_offset; ++ if (!bfd_link_relocatable (flinfo->info)) ++ { ++ osym.st_value += isec->output_section->vma; ++ if (ELF_ST_TYPE (osym.st_info) == STT_TLS) ++ { ++ /* STT_TLS symbols are relative to PT_TLS segment base. */ ++ if (elf_hash_table (flinfo->info)->tls_sec != NULL) ++ osym.st_value -= elf_hash_table (flinfo->info)->tls_sec->vma; ++ else ++ osym.st_info = ELF_ST_INFO (ELF_ST_BIND (osym.st_info), ++ STT_NOTYPE); ++ } ++ } ++ ++ indx = bfd_get_symcount (output_bfd); ++ ret = elf_link_output_symstrtab (flinfo, name, &osym, isec, NULL); ++ if (ret == 0) ++ return false; ++ else if (ret == 1) ++ *pindex = indx; ++ } ++ ++ if (bed->s->arch_size == 32) ++ { ++ r_type_mask = 0xff; ++ r_sym_shift = 8; ++ address_size = 4; ++ } ++ else ++ { ++ r_type_mask = 0xffffffff; ++ r_sym_shift = 32; ++ address_size = 8; ++ } ++ ++ /* Relocate the contents of each section. */ ++ sym_hashes = elf_sym_hashes (input_bfd); ++ for (o = input_bfd->sections; o != NULL; o = o->next) ++ { ++ bfd_byte *contents; ++ ++ if (! o->linker_mark) ++ { ++ /* This section was omitted from the link. */ ++ continue; ++ } ++ ++ if (!flinfo->info->resolve_section_groups ++ && (o->flags & (SEC_LINKER_CREATED | SEC_GROUP)) == SEC_GROUP) ++ { ++ /* Deal with the group signature symbol. */ ++ struct bfd_elf_section_data *sec_data = elf_section_data (o); ++ unsigned long symndx = sec_data->this_hdr.sh_info; ++ asection *osec = o->output_section; ++ ++ BFD_ASSERT (bfd_link_relocatable (flinfo->info)); ++ if (symndx >= locsymcount ++ || (elf_bad_symtab (input_bfd) ++ && flinfo->sections[symndx] == NULL)) ++ { ++ struct elf_link_hash_entry *h = sym_hashes[symndx - extsymoff]; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ /* Arrange for symbol to be output. */ ++ h->indx = -2; ++ elf_section_data (osec)->this_hdr.sh_info = -2; ++ } ++ else if (ELF_ST_TYPE (isymbuf[symndx].st_info) == STT_SECTION) ++ { ++ /* We'll use the output section target_index. */ ++ asection *sec = flinfo->sections[symndx]->output_section; ++ elf_section_data (osec)->this_hdr.sh_info = sec->target_index; ++ } ++ else ++ { ++ if (flinfo->indices[symndx] == -1) ++ { ++ /* Otherwise output the local symbol now. */ ++ Elf_Internal_Sym sym = isymbuf[symndx]; ++ asection *sec = flinfo->sections[symndx]->output_section; ++ const char *name; ++ long indx; ++ int ret; ++ ++ name = bfd_elf_string_from_elf_section (input_bfd, ++ symtab_hdr->sh_link, ++ sym.st_name); ++ if (name == NULL) ++ return false; ++ ++ sym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, ++ sec); ++ if (sym.st_shndx == SHN_BAD) ++ return false; ++ ++ sym.st_value += o->output_offset; ++ ++ indx = bfd_get_symcount (output_bfd); ++ ret = elf_link_output_symstrtab (flinfo, name, &sym, o, ++ NULL); ++ if (ret == 0) ++ return false; ++ else if (ret == 1) ++ flinfo->indices[symndx] = indx; ++ else ++ abort (); ++ } ++ elf_section_data (osec)->this_hdr.sh_info ++ = flinfo->indices[symndx]; ++ } ++ } ++ ++ if ((o->flags & SEC_HAS_CONTENTS) == 0 ++ || (o->size == 0 && (o->flags & SEC_RELOC) == 0)) ++ continue; ++ ++ if ((o->flags & SEC_LINKER_CREATED) != 0) ++ { ++ /* Section was created by _bfd_elf_link_create_dynamic_sections ++ or somesuch. */ ++ continue; ++ } ++ ++ /* Get the contents of the section. They have been cached by a ++ relaxation routine. Note that o is a section in an input ++ file, so the contents field will not have been set by any of ++ the routines which work on output files. */ ++ if (elf_section_data (o)->this_hdr.contents != NULL) ++ { ++ contents = elf_section_data (o)->this_hdr.contents; ++ if (bed->caches_rawsize ++ && o->rawsize != 0 ++ && o->rawsize < o->size) ++ { ++ memcpy (flinfo->contents, contents, o->rawsize); ++ contents = flinfo->contents; ++ } ++ } ++ else if (!(o->flags & SEC_RELOC) ++ && !bed->elf_backend_write_section ++ && o->sec_info_type == SEC_INFO_TYPE_MERGE) ++ /* A MERGE section that has no relocations doesn't need the ++ contents anymore, they have been recorded earlier. Except ++ if the backend has special provisions for writing sections. */ ++ contents = NULL; ++ else ++ { ++ contents = flinfo->contents; ++ if (! bfd_get_full_section_contents (input_bfd, o, &contents)) ++ return false; ++ } ++ ++ if ((o->flags & SEC_RELOC) != 0) ++ { ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *rel, *relend; ++ int action_discarded; ++ int ret; ++ ++ /* Get the swapped relocs. */ ++ internal_relocs ++ = _bfd_elf_link_info_read_relocs (input_bfd, flinfo->info, o, ++ flinfo->external_relocs, ++ flinfo->internal_relocs, ++ false); ++ if (internal_relocs == NULL ++ && o->reloc_count > 0) ++ return false; ++ ++ action_discarded = -1; ++ if (!elf_section_ignore_discarded_relocs (o)) ++ action_discarded = (*bed->action_discarded) (o); ++ ++ /* Run through the relocs evaluating complex reloc symbols and ++ looking for relocs against symbols from discarded sections ++ or section symbols from removed link-once sections. ++ Complain about relocs against discarded sections. Zero ++ relocs against removed link-once sections. */ ++ ++ rel = internal_relocs; ++ relend = rel + o->reloc_count; ++ for ( ; rel < relend; rel++) ++ { ++ unsigned long r_symndx = rel->r_info >> r_sym_shift; ++ unsigned int s_type; ++ asection **ps, *sec; ++ struct elf_link_hash_entry *h = NULL; ++ const char *sym_name; ++ ++ if (r_symndx == STN_UNDEF) ++ continue; ++ ++ if (r_symndx >= locsymcount ++ || (elf_bad_symtab (input_bfd) ++ && flinfo->sections[r_symndx] == NULL)) ++ { ++ h = sym_hashes[r_symndx - extsymoff]; ++ ++ /* Badly formatted input files can contain relocs that ++ reference non-existant symbols. Check here so that ++ we do not seg fault. */ ++ if (h == NULL) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("error: %pB contains a reloc (%#" PRIx64 ") for section %pA " ++ "that references a non-existent global symbol"), ++ input_bfd, (uint64_t) rel->r_info, o); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ s_type = h->type; ++ ++ /* If a plugin symbol is referenced from a non-IR file, ++ mark the symbol as undefined. Note that the ++ linker may attach linker created dynamic sections ++ to the plugin bfd. Symbols defined in linker ++ created sections are not plugin symbols. */ ++ if ((h->root.non_ir_ref_regular ++ || h->root.non_ir_ref_dynamic) ++ && (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && (h->root.u.def.section->flags ++ & SEC_LINKER_CREATED) == 0 ++ && h->root.u.def.section->owner != NULL ++ && (h->root.u.def.section->owner->flags ++ & BFD_PLUGIN) != 0) ++ { ++ h->root.type = bfd_link_hash_undefined; ++ h->root.u.undef.abfd = h->root.u.def.section->owner; ++ } ++ ++ ps = NULL; ++ if (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ ps = &h->root.u.def.section; ++ ++ sym_name = h->root.root.string; ++ } ++ else ++ { ++ Elf_Internal_Sym *sym = isymbuf + r_symndx; ++ ++ s_type = ELF_ST_TYPE (sym->st_info); ++ ps = &flinfo->sections[r_symndx]; ++ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, ++ sym, *ps); ++ } ++ ++ if ((s_type == STT_RELC || s_type == STT_SRELC) ++ && !bfd_link_relocatable (flinfo->info)) ++ { ++ bfd_vma val; ++ bfd_vma dot = (rel->r_offset ++ + o->output_offset + o->output_section->vma); ++#ifdef DEBUG ++ printf ("Encountered a complex symbol!"); ++ printf (" (input_bfd %s, section %s, reloc %ld\n", ++ bfd_get_filename (input_bfd), o->name, ++ (long) (rel - internal_relocs)); ++ printf (" symbol: idx %8.8lx, name %s\n", ++ r_symndx, sym_name); ++ printf (" reloc : info %8.8lx, addr %8.8lx\n", ++ (unsigned long) rel->r_info, ++ (unsigned long) rel->r_offset); ++#endif ++ if (!eval_symbol (&val, &sym_name, input_bfd, flinfo, dot, ++ isymbuf, locsymcount, s_type == STT_SRELC)) ++ return false; ++ ++ /* Symbol evaluated OK. Update to absolute value. */ ++ set_symbol_value (input_bfd, isymbuf, locsymcount, ++ r_symndx, val); ++ continue; ++ } ++ ++ if (action_discarded != -1 && ps != NULL) ++ { ++ /* Complain if the definition comes from a ++ discarded section. */ ++ if ((sec = *ps) != NULL && discarded_section (sec)) ++ { ++ BFD_ASSERT (r_symndx != STN_UNDEF); ++ if (action_discarded & COMPLAIN) ++ (*flinfo->info->callbacks->einfo) ++ /* xgettext:c-format */ ++ (_("%X`%s' referenced in section `%pA' of %pB: " ++ "defined in discarded section `%pA' of %pB\n"), ++ sym_name, o, input_bfd, sec, sec->owner); ++ ++ /* Try to do the best we can to support buggy old ++ versions of gcc. Pretend that the symbol is ++ really defined in the kept linkonce section. ++ FIXME: This is quite broken. Modifying the ++ symbol here means we will be changing all later ++ uses of the symbol, not just in this section. */ ++ if (action_discarded & PRETEND) ++ { ++ asection *kept; ++ ++ kept = _bfd_elf_check_kept_section (sec, ++ flinfo->info); ++ if (kept != NULL) ++ { ++ *ps = kept; ++ continue; ++ } ++ } ++ } ++ } ++ } ++ ++ /* Relocate the section by invoking a back end routine. ++ ++ The back end routine is responsible for adjusting the ++ section contents as necessary, and (if using Rela relocs ++ and generating a relocatable output file) adjusting the ++ reloc addend as necessary. ++ ++ The back end routine does not have to worry about setting ++ the reloc address or the reloc symbol index. ++ ++ The back end routine is given a pointer to the swapped in ++ internal symbols, and can access the hash table entries ++ for the external symbols via elf_sym_hashes (input_bfd). ++ ++ When generating relocatable output, the back end routine ++ must handle STB_LOCAL/STT_SECTION symbols specially. The ++ output symbol is going to be a section symbol ++ corresponding to the output section, which will require ++ the addend to be adjusted. */ ++ ++ ret = (*relocate_section) (output_bfd, flinfo->info, ++ input_bfd, o, contents, ++ internal_relocs, ++ isymbuf, ++ flinfo->sections); ++ if (!ret) ++ return false; ++ ++ if (ret == 2 ++ || bfd_link_relocatable (flinfo->info) ++ || flinfo->info->emitrelocations) ++ { ++ Elf_Internal_Rela *irela; ++ Elf_Internal_Rela *irelaend, *irelamid; ++ bfd_vma last_offset; ++ struct elf_link_hash_entry **rel_hash; ++ struct elf_link_hash_entry **rel_hash_list, **rela_hash_list; ++ Elf_Internal_Shdr *input_rel_hdr, *input_rela_hdr; ++ unsigned int next_erel; ++ bool rela_normal; ++ struct bfd_elf_section_data *esdi, *esdo; ++ ++ esdi = elf_section_data (o); ++ esdo = elf_section_data (o->output_section); ++ rela_normal = false; ++ ++ /* Adjust the reloc addresses and symbol indices. */ ++ ++ irela = internal_relocs; ++ irelaend = irela + o->reloc_count; ++ rel_hash = PTR_ADD (esdo->rel.hashes, esdo->rel.count); ++ /* We start processing the REL relocs, if any. When we reach ++ IRELAMID in the loop, we switch to the RELA relocs. */ ++ irelamid = irela; ++ if (esdi->rel.hdr != NULL) ++ irelamid += (NUM_SHDR_ENTRIES (esdi->rel.hdr) ++ * bed->s->int_rels_per_ext_rel); ++ rel_hash_list = rel_hash; ++ rela_hash_list = NULL; ++ last_offset = o->output_offset; ++ if (!bfd_link_relocatable (flinfo->info)) ++ last_offset += o->output_section->vma; ++ for (next_erel = 0; irela < irelaend; irela++, next_erel++) ++ { ++ unsigned long r_symndx; ++ asection *sec; ++ Elf_Internal_Sym sym; ++ ++ if (next_erel == bed->s->int_rels_per_ext_rel) ++ { ++ rel_hash++; ++ next_erel = 0; ++ } ++ ++ if (irela == irelamid) ++ { ++ rel_hash = PTR_ADD (esdo->rela.hashes, esdo->rela.count); ++ rela_hash_list = rel_hash; ++ rela_normal = bed->rela_normal; ++ } ++ ++ irela->r_offset = _bfd_elf_section_offset (output_bfd, ++ flinfo->info, o, ++ irela->r_offset); ++ if (irela->r_offset >= (bfd_vma) -2) ++ { ++ /* This is a reloc for a deleted entry or somesuch. ++ Turn it into an R_*_NONE reloc, at the same ++ offset as the last reloc. elf_eh_frame.c and ++ bfd_elf_discard_info rely on reloc offsets ++ being ordered. */ ++ irela->r_offset = last_offset; ++ irela->r_info = 0; ++ irela->r_addend = 0; ++ continue; ++ } ++ ++ irela->r_offset += o->output_offset; ++ ++ /* Relocs in an executable have to be virtual addresses. */ ++ if (!bfd_link_relocatable (flinfo->info)) ++ irela->r_offset += o->output_section->vma; ++ ++ last_offset = irela->r_offset; ++ ++ r_symndx = irela->r_info >> r_sym_shift; ++ if (r_symndx == STN_UNDEF) ++ continue; ++ ++ if (r_symndx >= locsymcount ++ || (elf_bad_symtab (input_bfd) ++ && flinfo->sections[r_symndx] == NULL)) ++ { ++ struct elf_link_hash_entry *rh; ++ unsigned long indx; ++ ++ /* This is a reloc against a global symbol. We ++ have not yet output all the local symbols, so ++ we do not know the symbol index of any global ++ symbol. We set the rel_hash entry for this ++ reloc to point to the global hash table entry ++ for this symbol. The symbol index is then ++ set at the end of bfd_elf_final_link. */ ++ indx = r_symndx - extsymoff; ++ rh = elf_sym_hashes (input_bfd)[indx]; ++ while (rh->root.type == bfd_link_hash_indirect ++ || rh->root.type == bfd_link_hash_warning) ++ rh = (struct elf_link_hash_entry *) rh->root.u.i.link; ++ ++ /* Setting the index to -2 tells ++ elf_link_output_extsym that this symbol is ++ used by a reloc. */ ++ BFD_ASSERT (rh->indx < 0); ++ rh->indx = -2; ++ *rel_hash = rh; ++ ++ continue; ++ } ++ ++ /* This is a reloc against a local symbol. */ ++ ++ *rel_hash = NULL; ++ sym = isymbuf[r_symndx]; ++ sec = flinfo->sections[r_symndx]; ++ if (ELF_ST_TYPE (sym.st_info) == STT_SECTION) ++ { ++ /* I suppose the backend ought to fill in the ++ section of any STT_SECTION symbol against a ++ processor specific section. */ ++ r_symndx = STN_UNDEF; ++ if (bfd_is_abs_section (sec)) ++ ; ++ else if (sec == NULL || sec->owner == NULL) ++ { ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ else ++ { ++ asection *osec = sec->output_section; ++ ++ /* If we have discarded a section, the output ++ section will be the absolute section. In ++ case of discarded SEC_MERGE sections, use ++ the kept section. relocate_section should ++ have already handled discarded linkonce ++ sections. */ ++ if (bfd_is_abs_section (osec) ++ && sec->kept_section != NULL ++ && sec->kept_section->output_section != NULL) ++ { ++ osec = sec->kept_section->output_section; ++ irela->r_addend -= osec->vma; ++ } ++ ++ if (!bfd_is_abs_section (osec)) ++ { ++ r_symndx = osec->target_index; ++ if (r_symndx == STN_UNDEF) ++ { ++ irela->r_addend += osec->vma; ++ osec = _bfd_nearby_section (output_bfd, osec, ++ osec->vma); ++ irela->r_addend -= osec->vma; ++ r_symndx = osec->target_index; ++ } ++ } ++ } ++ ++ /* Adjust the addend according to where the ++ section winds up in the output section. */ ++ if (rela_normal) ++ irela->r_addend += sec->output_offset; ++ } ++ else ++ { ++ if (flinfo->indices[r_symndx] == -1) ++ { ++ unsigned long shlink; ++ const char *name; ++ asection *osec; ++ long indx; ++ ++ if (flinfo->info->strip == strip_all) ++ { ++ /* You can't do ld -r -s. */ ++ bfd_set_error (bfd_error_invalid_operation); ++ return false; ++ } ++ ++ /* This symbol was skipped earlier, but ++ since it is needed by a reloc, we ++ must output it now. */ ++ shlink = symtab_hdr->sh_link; ++ name = (bfd_elf_string_from_elf_section ++ (input_bfd, shlink, sym.st_name)); ++ if (name == NULL) ++ return false; ++ ++ osec = sec->output_section; ++ sym.st_shndx = ++ _bfd_elf_section_from_bfd_section (output_bfd, ++ osec); ++ if (sym.st_shndx == SHN_BAD) ++ return false; ++ ++ sym.st_value += sec->output_offset; ++ if (!bfd_link_relocatable (flinfo->info)) ++ { ++ sym.st_value += osec->vma; ++ if (ELF_ST_TYPE (sym.st_info) == STT_TLS) ++ { ++ struct elf_link_hash_table *htab ++ = elf_hash_table (flinfo->info); ++ ++ /* STT_TLS symbols are relative to PT_TLS ++ segment base. */ ++ if (htab->tls_sec != NULL) ++ sym.st_value -= htab->tls_sec->vma; ++ else ++ sym.st_info ++ = ELF_ST_INFO (ELF_ST_BIND (sym.st_info), ++ STT_NOTYPE); ++ } ++ } ++ ++ indx = bfd_get_symcount (output_bfd); ++ ret = elf_link_output_symstrtab (flinfo, name, ++ &sym, sec, ++ NULL); ++ if (ret == 0) ++ return false; ++ else if (ret == 1) ++ flinfo->indices[r_symndx] = indx; ++ else ++ abort (); ++ } ++ ++ r_symndx = flinfo->indices[r_symndx]; ++ } ++ ++ irela->r_info = ((bfd_vma) r_symndx << r_sym_shift ++ | (irela->r_info & r_type_mask)); ++ } ++ ++ /* Swap out the relocs. */ ++ input_rel_hdr = esdi->rel.hdr; ++ if (input_rel_hdr && input_rel_hdr->sh_size != 0) ++ { ++ if (!bed->elf_backend_emit_relocs (output_bfd, o, ++ input_rel_hdr, ++ internal_relocs, ++ rel_hash_list)) ++ return false; ++ internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr) ++ * bed->s->int_rels_per_ext_rel); ++ rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr); ++ } ++ ++ input_rela_hdr = esdi->rela.hdr; ++ if (input_rela_hdr && input_rela_hdr->sh_size != 0) ++ { ++ if (!bed->elf_backend_emit_relocs (output_bfd, o, ++ input_rela_hdr, ++ internal_relocs, ++ rela_hash_list)) ++ return false; ++ } ++ } ++ } ++ ++ /* Write out the modified section contents. */ ++ if (bed->elf_backend_write_section ++ && (*bed->elf_backend_write_section) (output_bfd, flinfo->info, o, ++ contents)) ++ { ++ /* Section written out. */ ++ } ++ else switch (o->sec_info_type) ++ { ++ case SEC_INFO_TYPE_STABS: ++ if (! (_bfd_write_section_stabs ++ (output_bfd, ++ &elf_hash_table (flinfo->info)->stab_info, ++ o, &elf_section_data (o)->sec_info, contents))) ++ return false; ++ break; ++ case SEC_INFO_TYPE_MERGE: ++ if (! _bfd_write_merged_section (output_bfd, o, ++ elf_section_data (o)->sec_info)) ++ return false; ++ break; ++ case SEC_INFO_TYPE_EH_FRAME: ++ { ++ if (! _bfd_elf_write_section_eh_frame (output_bfd, flinfo->info, ++ o, contents)) ++ return false; ++ } ++ break; ++ case SEC_INFO_TYPE_EH_FRAME_ENTRY: ++ { ++ if (! _bfd_elf_write_section_eh_frame_entry (output_bfd, ++ flinfo->info, ++ o, contents)) ++ return false; ++ } ++ break; ++ case SEC_INFO_TYPE_SFRAME: ++ { ++ /* Merge .sframe sections into the ctf frame encoder ++ context of the output_bfd's section. The final .sframe ++ output section will be written out later. */ ++ if (!_bfd_elf_merge_section_sframe (output_bfd, flinfo->info, ++ o, contents)) ++ return false; ++ } ++ break; ++ default: ++ { ++ if (! (o->flags & SEC_EXCLUDE)) ++ { ++ file_ptr offset = (file_ptr) o->output_offset; ++ bfd_size_type todo = o->size; ++ ++ offset *= bfd_octets_per_byte (output_bfd, o); ++ ++ if ((o->flags & SEC_ELF_REVERSE_COPY) ++ && o->size > address_size) ++ { ++ /* Reverse-copy input section to output. */ ++ ++ if ((o->size & (address_size - 1)) != 0 ++ || (o->reloc_count != 0 ++ && (o->size * bed->s->int_rels_per_ext_rel ++ != o->reloc_count * address_size))) ++ { ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("error: %pB: size of section %pA is not " ++ "multiple of address size"), ++ input_bfd, o); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ ++ do ++ { ++ todo -= address_size; ++ if (! bfd_set_section_contents (output_bfd, ++ o->output_section, ++ contents + todo, ++ offset, ++ address_size)) ++ return false; ++ if (todo == 0) ++ break; ++ offset += address_size; ++ } ++ while (1); ++ } ++ else if (! bfd_set_section_contents (output_bfd, ++ o->output_section, ++ contents, ++ offset, todo)) ++ return false; ++ } ++ } ++ break; ++ } ++ } ++ ++ return true; ++} ++ ++/* Generate a reloc when linking an ELF file. This is a reloc ++ requested by the linker, and does not come from any input file. This ++ is used to build constructor and destructor tables when linking ++ with -Ur. */ ++ ++static bool ++elf_reloc_link_order (bfd *output_bfd, ++ struct bfd_link_info *info, ++ asection *output_section, ++ struct bfd_link_order *link_order) ++{ ++ reloc_howto_type *howto; ++ long indx; ++ bfd_vma offset; ++ bfd_vma addend; ++ struct bfd_elf_section_reloc_data *reldata; ++ struct elf_link_hash_entry **rel_hash_ptr; ++ Elf_Internal_Shdr *rel_hdr; ++ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); ++ Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL]; ++ bfd_byte *erel; ++ unsigned int i; ++ struct bfd_elf_section_data *esdo = elf_section_data (output_section); ++ ++ howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); ++ if (howto == NULL) ++ { ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ ++ addend = link_order->u.reloc.p->addend; ++ ++ if (esdo->rel.hdr) ++ reldata = &esdo->rel; ++ else if (esdo->rela.hdr) ++ reldata = &esdo->rela; ++ else ++ { ++ reldata = NULL; ++ BFD_ASSERT (0); ++ } ++ ++ /* Figure out the symbol index. */ ++ rel_hash_ptr = reldata->hashes + reldata->count; ++ if (link_order->type == bfd_section_reloc_link_order) ++ { ++ indx = link_order->u.reloc.p->u.section->target_index; ++ BFD_ASSERT (indx != 0); ++ *rel_hash_ptr = NULL; ++ } ++ else ++ { ++ struct elf_link_hash_entry *h; ++ ++ /* Treat a reloc against a defined symbol as though it were ++ actually against the section. */ ++ h = ((struct elf_link_hash_entry *) ++ bfd_wrapped_link_hash_lookup (output_bfd, info, ++ link_order->u.reloc.p->u.name, ++ false, false, true)); ++ if (h != NULL ++ && (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak)) ++ { ++ asection *section; ++ ++ section = h->root.u.def.section; ++ indx = section->output_section->target_index; ++ *rel_hash_ptr = NULL; ++ /* It seems that we ought to add the symbol value to the ++ addend here, but in practice it has already been added ++ because it was passed to constructor_callback. */ ++ addend += section->output_section->vma + section->output_offset; ++ } ++ else if (h != NULL) ++ { ++ /* Setting the index to -2 tells elf_link_output_extsym that ++ this symbol is used by a reloc. */ ++ h->indx = -2; ++ *rel_hash_ptr = h; ++ indx = 0; ++ } ++ else ++ { ++ (*info->callbacks->unattached_reloc) ++ (info, link_order->u.reloc.p->u.name, NULL, NULL, 0); ++ indx = 0; ++ } ++ } ++ ++ /* If this is an inplace reloc, we must write the addend into the ++ object file. */ ++ if (howto->partial_inplace && addend != 0) ++ { ++ bfd_size_type size; ++ bfd_reloc_status_type rstat; ++ bfd_byte *buf; ++ bool ok; ++ const char *sym_name; ++ bfd_size_type octets; ++ ++ size = (bfd_size_type) bfd_get_reloc_size (howto); ++ buf = (bfd_byte *) bfd_zmalloc (size); ++ if (buf == NULL && size != 0) ++ return false; ++ rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); ++ switch (rstat) ++ { ++ case bfd_reloc_ok: ++ break; ++ ++ default: ++ case bfd_reloc_outofrange: ++ abort (); ++ ++ case bfd_reloc_overflow: ++ if (link_order->type == bfd_section_reloc_link_order) ++ sym_name = bfd_section_name (link_order->u.reloc.p->u.section); ++ else ++ sym_name = link_order->u.reloc.p->u.name; ++ (*info->callbacks->reloc_overflow) (info, NULL, sym_name, ++ howto->name, addend, NULL, NULL, ++ (bfd_vma) 0); ++ break; ++ } ++ ++ octets = link_order->offset * bfd_octets_per_byte (output_bfd, ++ output_section); ++ ok = bfd_set_section_contents (output_bfd, output_section, buf, ++ octets, size); ++ free (buf); ++ if (! ok) ++ return false; ++ } ++ ++ /* The address of a reloc is relative to the section in a ++ relocatable file, and is a virtual address in an executable ++ file. */ ++ offset = link_order->offset; ++ if (! bfd_link_relocatable (info)) ++ offset += output_section->vma; ++ ++ for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) ++ { ++ irel[i].r_offset = offset; ++ irel[i].r_info = 0; ++ irel[i].r_addend = 0; ++ } ++ if (bed->s->arch_size == 32) ++ irel[0].r_info = ELF32_R_INFO (indx, howto->type); ++ else ++ irel[0].r_info = ELF64_R_INFO (indx, howto->type); ++ ++ rel_hdr = reldata->hdr; ++ erel = rel_hdr->contents; ++ if (rel_hdr->sh_type == SHT_REL) ++ { ++ erel += reldata->count * bed->s->sizeof_rel; ++ (*bed->s->swap_reloc_out) (output_bfd, irel, erel); ++ } ++ else ++ { ++ irel[0].r_addend = addend; ++ erel += reldata->count * bed->s->sizeof_rela; ++ (*bed->s->swap_reloca_out) (output_bfd, irel, erel); ++ } ++ ++ ++reldata->count; ++ ++ return true; ++} ++ ++/* Generate an import library in INFO->implib_bfd from symbols in ABFD. ++ Returns TRUE upon success, FALSE otherwise. */ ++ ++static bool ++elf_output_implib (bfd *abfd, struct bfd_link_info *info) ++{ ++ bool ret = false; ++ bfd *implib_bfd; ++ const struct elf_backend_data *bed; ++ flagword flags; ++ enum bfd_architecture arch; ++ unsigned int mach; ++ asymbol **sympp = NULL; ++ long symsize; ++ long symcount; ++ long src_count; ++ elf_symbol_type *osymbuf; ++ size_t amt; ++ ++ implib_bfd = info->out_implib_bfd; ++ bed = get_elf_backend_data (abfd); ++ ++ if (!bfd_set_format (implib_bfd, bfd_object)) ++ return false; ++ ++ /* Use flag from executable but make it a relocatable object. */ ++ flags = bfd_get_file_flags (abfd); ++ flags &= ~HAS_RELOC; ++ if (!bfd_set_start_address (implib_bfd, 0) ++ || !bfd_set_file_flags (implib_bfd, flags & ~EXEC_P)) ++ return false; ++ ++ /* Copy architecture of output file to import library file. */ ++ arch = bfd_get_arch (abfd); ++ mach = bfd_get_mach (abfd); ++ if (!bfd_set_arch_mach (implib_bfd, arch, mach) ++ && (abfd->target_defaulted ++ || bfd_get_arch (abfd) != bfd_get_arch (implib_bfd))) ++ return false; ++ ++ /* Get symbol table size. */ ++ symsize = bfd_get_symtab_upper_bound (abfd); ++ if (symsize < 0) ++ return false; ++ ++ /* Read in the symbol table. */ ++ sympp = (asymbol **) bfd_malloc (symsize); ++ if (sympp == NULL) ++ return false; ++ ++ symcount = bfd_canonicalize_symtab (abfd, sympp); ++ if (symcount < 0) ++ goto free_sym_buf; ++ ++ /* Allow the BFD backend to copy any private header data it ++ understands from the output BFD to the import library BFD. */ ++ if (! bfd_copy_private_header_data (abfd, implib_bfd)) ++ goto free_sym_buf; ++ ++ /* Filter symbols to appear in the import library. */ ++ if (bed->elf_backend_filter_implib_symbols) ++ symcount = bed->elf_backend_filter_implib_symbols (abfd, info, sympp, ++ symcount); ++ else ++ symcount = _bfd_elf_filter_global_symbols (abfd, info, sympp, symcount); ++ if (symcount == 0) ++ { ++ bfd_set_error (bfd_error_no_symbols); ++ _bfd_error_handler (_("%pB: no symbol found for import library"), ++ implib_bfd); ++ goto free_sym_buf; ++ } ++ ++ ++ /* Make symbols absolute. */ ++ amt = symcount * sizeof (*osymbuf); ++ osymbuf = (elf_symbol_type *) bfd_alloc (implib_bfd, amt); ++ if (osymbuf == NULL) ++ goto free_sym_buf; ++ ++ for (src_count = 0; src_count < symcount; src_count++) ++ { ++ memcpy (&osymbuf[src_count], (elf_symbol_type *) sympp[src_count], ++ sizeof (*osymbuf)); ++ osymbuf[src_count].symbol.section = bfd_abs_section_ptr; ++ osymbuf[src_count].internal_elf_sym.st_shndx = SHN_ABS; ++ osymbuf[src_count].symbol.value += sympp[src_count]->section->vma; ++ osymbuf[src_count].internal_elf_sym.st_value = ++ osymbuf[src_count].symbol.value; ++ sympp[src_count] = &osymbuf[src_count].symbol; ++ } ++ ++ bfd_set_symtab (implib_bfd, sympp, symcount); ++ ++ /* Allow the BFD backend to copy any private data it understands ++ from the output BFD to the import library BFD. This is done last ++ to permit the routine to look at the filtered symbol table. */ ++ if (! bfd_copy_private_bfd_data (abfd, implib_bfd)) ++ goto free_sym_buf; ++ ++ if (!bfd_close (implib_bfd)) ++ goto free_sym_buf; ++ ++ ret = true; ++ ++ free_sym_buf: ++ free (sympp); ++ return ret; ++} ++ ++static void ++elf_final_link_free (bfd *obfd, struct elf_final_link_info *flinfo) ++{ ++ asection *o; ++ ++ if (flinfo->symstrtab != NULL) ++ _bfd_elf_strtab_free (flinfo->symstrtab); ++ free (flinfo->contents); ++ free (flinfo->external_relocs); ++ free (flinfo->internal_relocs); ++ free (flinfo->external_syms); ++ free (flinfo->locsym_shndx); ++ free (flinfo->internal_syms); ++ free (flinfo->indices); ++ free (flinfo->sections); ++ if (flinfo->symshndxbuf != (Elf_External_Sym_Shndx *) -1) ++ free (flinfo->symshndxbuf); ++ for (o = obfd->sections; o != NULL; o = o->next) ++ { ++ struct bfd_elf_section_data *esdo = elf_section_data (o); ++ free (esdo->rel.hashes); ++ free (esdo->rela.hashes); ++ } ++} ++ ++/* Do the final step of an ELF link. */ ++ ++bool ++bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) ++{ ++ bool dynamic; ++ bool emit_relocs; ++ bfd *dynobj; ++ struct elf_final_link_info flinfo; ++ asection *o; ++ struct bfd_link_order *p; ++ bfd *sub; ++ bfd_size_type max_contents_size; ++ bfd_size_type max_external_reloc_size; ++ bfd_size_type max_internal_reloc_count; ++ bfd_size_type max_sym_count; ++ bfd_size_type max_sym_shndx_count; ++ Elf_Internal_Sym elfsym; ++ unsigned int i; ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Shdr *symtab_shndx_hdr; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct elf_outext_info eoinfo; ++ bool merged; ++ size_t relativecount; ++ size_t relr_entsize; ++ asection *reldyn = 0; ++ bfd_size_type amt; ++ asection *attr_section = NULL; ++ bfd_vma attr_size = 0; ++ const char *std_attrs_section; ++ struct elf_link_hash_table *htab = elf_hash_table (info); ++ bool sections_removed; ++ bool ret; ++ ++ if (!is_elf_hash_table (&htab->root)) ++ return false; ++ ++ if (bfd_link_pic (info)) ++ abfd->flags |= DYNAMIC; ++ ++ dynamic = htab->dynamic_sections_created; ++ dynobj = htab->dynobj; ++ ++ emit_relocs = (bfd_link_relocatable (info) ++ || info->emitrelocations); ++ ++ memset (&flinfo, 0, sizeof (flinfo)); ++ flinfo.info = info; ++ flinfo.output_bfd = abfd; ++ flinfo.symstrtab = _bfd_elf_strtab_init (); ++ if (flinfo.symstrtab == NULL) ++ return false; ++ ++ if (! dynamic) ++ { ++ flinfo.hash_sec = NULL; ++ flinfo.symver_sec = NULL; ++ } ++ else ++ { ++ flinfo.hash_sec = bfd_get_linker_section (dynobj, ".hash"); ++ /* Note that dynsym_sec can be NULL (on VMS). */ ++ flinfo.symver_sec = bfd_get_linker_section (dynobj, ".gnu.version"); ++ /* Note that it is OK if symver_sec is NULL. */ ++ } ++ ++ if (info->unique_symbol ++ && !bfd_hash_table_init (&flinfo.local_hash_table, ++ local_hash_newfunc, ++ sizeof (struct local_hash_entry))) ++ return false; ++ ++ /* The object attributes have been merged. Remove the input ++ sections from the link, and set the contents of the output ++ section. */ ++ sections_removed = false; ++ std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section; ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ bool remove_section = false; ++ ++ if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0) ++ || strcmp (o->name, ".gnu.attributes") == 0) ++ { ++ for (p = o->map_head.link_order; p != NULL; p = p->next) ++ { ++ asection *input_section; ++ ++ if (p->type != bfd_indirect_link_order) ++ continue; ++ input_section = p->u.indirect.section; ++ /* Hack: reset the SEC_HAS_CONTENTS flag so that ++ elf_link_input_bfd ignores this section. */ ++ input_section->flags &= ~SEC_HAS_CONTENTS; ++ } ++ ++ attr_size = bfd_elf_obj_attr_size (abfd); ++ bfd_set_section_size (o, attr_size); ++ /* Skip this section later on. */ ++ o->map_head.link_order = NULL; ++ if (attr_size) ++ attr_section = o; ++ else ++ remove_section = true; ++ } ++ else if ((o->flags & SEC_GROUP) != 0 && o->size == 0) ++ { ++ /* Remove empty group section from linker output. */ ++ remove_section = true; ++ } ++ if (remove_section) ++ { ++ o->flags |= SEC_EXCLUDE; ++ bfd_section_list_remove (abfd, o); ++ abfd->section_count--; ++ sections_removed = true; ++ } ++ } ++ if (sections_removed) ++ _bfd_fix_excluded_sec_syms (abfd, info); ++ ++ /* Count up the number of relocations we will output for each output ++ section, so that we know the sizes of the reloc sections. We ++ also figure out some maximum sizes. */ ++ max_contents_size = 0; ++ max_external_reloc_size = 0; ++ max_internal_reloc_count = 0; ++ max_sym_count = 0; ++ max_sym_shndx_count = 0; ++ merged = false; ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ struct bfd_elf_section_data *esdo = elf_section_data (o); ++ o->reloc_count = 0; ++ ++ for (p = o->map_head.link_order; p != NULL; p = p->next) ++ { ++ unsigned int reloc_count = 0; ++ unsigned int additional_reloc_count = 0; ++ struct bfd_elf_section_data *esdi = NULL; ++ ++ if (p->type == bfd_section_reloc_link_order ++ || p->type == bfd_symbol_reloc_link_order) ++ reloc_count = 1; ++ else if (p->type == bfd_indirect_link_order) ++ { ++ asection *sec; ++ ++ sec = p->u.indirect.section; ++ ++ /* Mark all sections which are to be included in the ++ link. This will normally be every section. We need ++ to do this so that we can identify any sections which ++ the linker has decided to not include. */ ++ sec->linker_mark = true; ++ ++ if (sec->flags & SEC_MERGE) ++ merged = true; ++ ++ if (sec->rawsize > max_contents_size) ++ max_contents_size = sec->rawsize; ++ if (sec->size > max_contents_size) ++ max_contents_size = sec->size; ++ ++ if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour ++ && (sec->owner->flags & DYNAMIC) == 0) ++ { ++ size_t sym_count; ++ ++ /* We are interested in just local symbols, not all ++ symbols. */ ++ if (elf_bad_symtab (sec->owner)) ++ sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size ++ / bed->s->sizeof_sym); ++ else ++ sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; ++ ++ if (sym_count > max_sym_count) ++ max_sym_count = sym_count; ++ ++ if (sym_count > max_sym_shndx_count ++ && elf_symtab_shndx_list (sec->owner) != NULL) ++ max_sym_shndx_count = sym_count; ++ ++ esdi = elf_section_data (sec); ++ ++ if (esdi->this_hdr.sh_type == SHT_REL ++ || esdi->this_hdr.sh_type == SHT_RELA) ++ /* Some backends use reloc_count in relocation sections ++ to count particular types of relocs. Of course, ++ reloc sections themselves can't have relocations. */ ++ ; ++ else if (emit_relocs) ++ { ++ reloc_count = sec->reloc_count; ++ if (bed->elf_backend_count_additional_relocs) ++ { ++ int c; ++ c = (*bed->elf_backend_count_additional_relocs) (sec); ++ additional_reloc_count += c; ++ } ++ } ++ else if (bed->elf_backend_count_relocs) ++ reloc_count = (*bed->elf_backend_count_relocs) (info, sec); ++ ++ if ((sec->flags & SEC_RELOC) != 0) ++ { ++ size_t ext_size = 0; ++ ++ if (esdi->rel.hdr != NULL) ++ ext_size = esdi->rel.hdr->sh_size; ++ if (esdi->rela.hdr != NULL) ++ ext_size += esdi->rela.hdr->sh_size; ++ ++ if (ext_size > max_external_reloc_size) ++ max_external_reloc_size = ext_size; ++ if (sec->reloc_count > max_internal_reloc_count) ++ max_internal_reloc_count = sec->reloc_count; ++ } ++ } ++ } ++ ++ if (reloc_count == 0) ++ continue; ++ ++ reloc_count += additional_reloc_count; ++ o->reloc_count += reloc_count; ++ ++ if (p->type == bfd_indirect_link_order && emit_relocs) ++ { ++ if (esdi->rel.hdr) ++ { ++ esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr); ++ esdo->rel.count += additional_reloc_count; ++ } ++ if (esdi->rela.hdr) ++ { ++ esdo->rela.count += NUM_SHDR_ENTRIES (esdi->rela.hdr); ++ esdo->rela.count += additional_reloc_count; ++ } ++ } ++ else ++ { ++ if (o->use_rela_p) ++ esdo->rela.count += reloc_count; ++ else ++ esdo->rel.count += reloc_count; ++ } ++ } ++ ++ if (o->reloc_count > 0) ++ o->flags |= SEC_RELOC; ++ else ++ { ++ /* Explicitly clear the SEC_RELOC flag. The linker tends to ++ set it (this is probably a bug) and if it is set ++ assign_section_numbers will create a reloc section. */ ++ o->flags &=~ SEC_RELOC; ++ } ++ ++ /* If the SEC_ALLOC flag is not set, force the section VMA to ++ zero. This is done in elf_fake_sections as well, but forcing ++ the VMA to 0 here will ensure that relocs against these ++ sections are handled correctly. */ ++ if ((o->flags & SEC_ALLOC) == 0 ++ && ! o->user_set_vma) ++ o->vma = 0; ++ } ++ ++ if (! bfd_link_relocatable (info) && merged) ++ elf_link_hash_traverse (htab, _bfd_elf_link_sec_merge_syms, abfd); ++ ++ /* Figure out the file positions for everything but the symbol table ++ and the relocs. We set symcount to force assign_section_numbers ++ to create a symbol table. */ ++ abfd->symcount = info->strip != strip_all || emit_relocs; ++ BFD_ASSERT (! abfd->output_has_begun); ++ if (! _bfd_elf_compute_section_file_positions (abfd, info)) ++ goto error_return; ++ ++ /* Set sizes, and assign file positions for reloc sections. */ ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ struct bfd_elf_section_data *esdo = elf_section_data (o); ++ if ((o->flags & SEC_RELOC) != 0) ++ { ++ if (esdo->rel.hdr ++ && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rel))) ++ goto error_return; ++ ++ if (esdo->rela.hdr ++ && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rela))) ++ goto error_return; ++ } ++ ++ /* _bfd_elf_compute_section_file_positions makes temporary use ++ of target_index. Reset it. */ ++ o->target_index = 0; ++ ++ /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them ++ to count upwards while actually outputting the relocations. */ ++ esdo->rel.count = 0; ++ esdo->rela.count = 0; ++ ++ if ((esdo->this_hdr.sh_offset == (file_ptr) -1) ++ && !bfd_section_is_ctf (o)) ++ { ++ /* Cache the section contents so that they can be compressed ++ later. Use bfd_malloc since it will be freed by ++ bfd_compress_section_contents. */ ++ unsigned char *contents = esdo->this_hdr.contents; ++ if (contents != NULL) ++ abort (); ++ contents ++ = (unsigned char *) bfd_malloc (esdo->this_hdr.sh_size); ++ if (contents == NULL) ++ goto error_return; ++ esdo->this_hdr.contents = contents; ++ } ++ } ++ ++ /* We have now assigned file positions for all the sections except .symtab, ++ .strtab, and non-loaded reloc and compressed debugging sections. We start ++ the .symtab section at the current file position, and write directly to it. ++ We build the .strtab section in memory. */ ++ abfd->symcount = 0; ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ /* sh_name is set in prep_headers. */ ++ symtab_hdr->sh_type = SHT_SYMTAB; ++ /* sh_flags, sh_addr and sh_size all start off zero. */ ++ symtab_hdr->sh_entsize = bed->s->sizeof_sym; ++ /* sh_link is set in assign_section_numbers. */ ++ /* sh_info is set below. */ ++ /* sh_offset is set just below. */ ++ symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; ++ ++ if (max_sym_count < 20) ++ max_sym_count = 20; ++ htab->strtabsize = max_sym_count; ++ amt = max_sym_count * sizeof (struct elf_sym_strtab); ++ htab->strtab = (struct elf_sym_strtab *) bfd_malloc (amt); ++ if (htab->strtab == NULL) ++ goto error_return; ++ /* The real buffer will be allocated in elf_link_swap_symbols_out. */ ++ flinfo.symshndxbuf ++ = (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF) ++ ? (Elf_External_Sym_Shndx *) -1 : NULL); ++ ++ if (info->strip != strip_all || emit_relocs) ++ { ++ file_ptr off = elf_next_file_pos (abfd); ++ ++ _bfd_elf_assign_file_position_for_section (symtab_hdr, off, true); ++ ++ /* Note that at this point elf_next_file_pos (abfd) is ++ incorrect. We do not yet know the size of the .symtab section. ++ We correct next_file_pos below, after we do know the size. */ ++ ++ /* Start writing out the symbol table. The first symbol is always a ++ dummy symbol. */ ++ elfsym.st_value = 0; ++ elfsym.st_size = 0; ++ elfsym.st_info = 0; ++ elfsym.st_other = 0; ++ elfsym.st_shndx = SHN_UNDEF; ++ elfsym.st_target_internal = 0; ++ if (elf_link_output_symstrtab (&flinfo, NULL, &elfsym, ++ bfd_und_section_ptr, NULL) != 1) ++ goto error_return; ++ ++ /* Output a symbol for each section if asked or they are used for ++ relocs. These symbols usually have no names. We store the ++ index of each one in the index field of the section, so that ++ we can find it again when outputting relocs. */ ++ ++ if (bfd_keep_unused_section_symbols (abfd) || emit_relocs) ++ { ++ bool name_local_sections ++ = (bed->elf_backend_name_local_section_symbols ++ && bed->elf_backend_name_local_section_symbols (abfd)); ++ const char *name = NULL; ++ ++ elfsym.st_size = 0; ++ elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); ++ elfsym.st_other = 0; ++ elfsym.st_value = 0; ++ elfsym.st_target_internal = 0; ++ for (i = 1; i < elf_numsections (abfd); i++) ++ { ++ o = bfd_section_from_elf_index (abfd, i); ++ if (o != NULL) ++ { ++ o->target_index = bfd_get_symcount (abfd); ++ elfsym.st_shndx = i; ++ if (!bfd_link_relocatable (info)) ++ elfsym.st_value = o->vma; ++ if (name_local_sections) ++ name = o->name; ++ if (elf_link_output_symstrtab (&flinfo, name, &elfsym, o, ++ NULL) != 1) ++ goto error_return; ++ } ++ } ++ } ++ } ++ ++ /* On some targets like Irix 5 the symbol split between local and global ++ ones recorded in the sh_info field needs to be done between section ++ and all other symbols. */ ++ if (bed->elf_backend_elfsym_local_is_section ++ && bed->elf_backend_elfsym_local_is_section (abfd)) ++ symtab_hdr->sh_info = bfd_get_symcount (abfd); ++ ++ /* Allocate some memory to hold information read in from the input ++ files. */ ++ if (max_contents_size != 0) ++ { ++ flinfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); ++ if (flinfo.contents == NULL) ++ goto error_return; ++ } ++ ++ if (max_external_reloc_size != 0) ++ { ++ flinfo.external_relocs = bfd_malloc (max_external_reloc_size); ++ if (flinfo.external_relocs == NULL) ++ goto error_return; ++ } ++ ++ if (max_internal_reloc_count != 0) ++ { ++ amt = max_internal_reloc_count * sizeof (Elf_Internal_Rela); ++ flinfo.internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt); ++ if (flinfo.internal_relocs == NULL) ++ goto error_return; ++ } ++ ++ if (max_sym_count != 0) ++ { ++ amt = max_sym_count * bed->s->sizeof_sym; ++ flinfo.external_syms = (bfd_byte *) bfd_malloc (amt); ++ if (flinfo.external_syms == NULL) ++ goto error_return; ++ ++ amt = max_sym_count * sizeof (Elf_Internal_Sym); ++ flinfo.internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt); ++ if (flinfo.internal_syms == NULL) ++ goto error_return; ++ ++ amt = max_sym_count * sizeof (long); ++ flinfo.indices = (long int *) bfd_malloc (amt); ++ if (flinfo.indices == NULL) ++ goto error_return; ++ ++ amt = max_sym_count * sizeof (asection *); ++ flinfo.sections = (asection **) bfd_malloc (amt); ++ if (flinfo.sections == NULL) ++ goto error_return; ++ } ++ ++ if (max_sym_shndx_count != 0) ++ { ++ amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx); ++ flinfo.locsym_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt); ++ if (flinfo.locsym_shndx == NULL) ++ goto error_return; ++ } ++ ++ if (htab->tls_sec) ++ { ++ bfd_vma base, end = 0; /* Both bytes. */ ++ asection *sec; ++ ++ for (sec = htab->tls_sec; ++ sec && (sec->flags & SEC_THREAD_LOCAL); ++ sec = sec->next) ++ { ++ bfd_size_type size = sec->size; ++ unsigned int opb = bfd_octets_per_byte (abfd, sec); ++ ++ if (size == 0 ++ && (sec->flags & SEC_HAS_CONTENTS) == 0) ++ { ++ struct bfd_link_order *ord = sec->map_tail.link_order; ++ ++ if (ord != NULL) ++ size = ord->offset * opb + ord->size; ++ } ++ end = sec->vma + size / opb; ++ } ++ base = htab->tls_sec->vma; ++ /* Only align end of TLS section if static TLS doesn't have special ++ alignment requirements. */ ++ if (bed->static_tls_alignment == 1) ++ end = align_power (end, htab->tls_sec->alignment_power); ++ htab->tls_size = end - base; ++ } ++ ++ if (!_bfd_elf_fixup_eh_frame_hdr (info)) ++ return false; ++ ++ /* Finish relative relocations here after regular symbol processing ++ is finished if DT_RELR is enabled. */ ++ if (info->enable_dt_relr ++ && bed->finish_relative_relocs ++ && !bed->finish_relative_relocs (info)) ++ info->callbacks->einfo ++ (_("%F%P: %pB: failed to finish relative relocations\n"), abfd); ++ ++ /* Since ELF permits relocations to be against local symbols, we ++ must have the local symbols available when we do the relocations. ++ Since we would rather only read the local symbols once, and we ++ would rather not keep them in memory, we handle all the ++ relocations for a single input file at the same time. ++ ++ Unfortunately, there is no way to know the total number of local ++ symbols until we have seen all of them, and the local symbol ++ indices precede the global symbol indices. This means that when ++ we are generating relocatable output, and we see a reloc against ++ a global symbol, we can not know the symbol index until we have ++ finished examining all the local symbols to see which ones we are ++ going to output. To deal with this, we keep the relocations in ++ memory, and don't output them until the end of the link. This is ++ an unfortunate waste of memory, but I don't see a good way around ++ it. Fortunately, it only happens when performing a relocatable ++ link, which is not the common case. FIXME: If keep_memory is set ++ we could write the relocs out and then read them again; I don't ++ know how bad the memory loss will be. */ ++ ++ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) ++ sub->output_has_begun = false; ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ for (p = o->map_head.link_order; p != NULL; p = p->next) ++ { ++ if (p->type == bfd_indirect_link_order ++ && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) ++ == bfd_target_elf_flavour) ++ && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass) ++ { ++ if (! sub->output_has_begun) ++ { ++ if (! elf_link_input_bfd (&flinfo, sub)) ++ goto error_return; ++ sub->output_has_begun = true; ++ } ++ } ++ else if (p->type == bfd_section_reloc_link_order ++ || p->type == bfd_symbol_reloc_link_order) ++ { ++ if (! elf_reloc_link_order (abfd, info, o, p)) ++ goto error_return; ++ } ++ else ++ { ++ if (! _bfd_default_link_order (abfd, info, o, p)) ++ { ++ if (p->type == bfd_indirect_link_order ++ && (bfd_get_flavour (sub) ++ == bfd_target_elf_flavour) ++ && (elf_elfheader (sub)->e_ident[EI_CLASS] ++ != bed->s->elfclass)) ++ { ++ const char *iclass, *oclass; ++ ++ switch (bed->s->elfclass) ++ { ++ case ELFCLASS64: oclass = "ELFCLASS64"; break; ++ case ELFCLASS32: oclass = "ELFCLASS32"; break; ++ case ELFCLASSNONE: oclass = "ELFCLASSNONE"; break; ++ default: abort (); ++ } ++ ++ switch (elf_elfheader (sub)->e_ident[EI_CLASS]) ++ { ++ case ELFCLASS64: iclass = "ELFCLASS64"; break; ++ case ELFCLASS32: iclass = "ELFCLASS32"; break; ++ case ELFCLASSNONE: iclass = "ELFCLASSNONE"; break; ++ default: abort (); ++ } ++ ++ bfd_set_error (bfd_error_wrong_format); ++ _bfd_error_handler ++ /* xgettext:c-format */ ++ (_("%pB: file class %s incompatible with %s"), ++ sub, iclass, oclass); ++ } ++ ++ goto error_return; ++ } ++ } ++ } ++ } ++ ++ /* Free symbol buffer if needed. */ ++ if (!info->reduce_memory_overheads) ++ { ++ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) ++ if (bfd_get_flavour (sub) == bfd_target_elf_flavour) ++ { ++ free (elf_tdata (sub)->symbuf); ++ elf_tdata (sub)->symbuf = NULL; ++ } ++ } ++ ++ ret = true; ++ ++ /* Output any global symbols that got converted to local in a ++ version script or due to symbol visibility. We do this in a ++ separate step since ELF requires all local symbols to appear ++ prior to any global symbols. FIXME: We should only do this if ++ some global symbols were, in fact, converted to become local. ++ FIXME: Will this work correctly with the Irix 5 linker? */ ++ eoinfo.failed = false; ++ eoinfo.flinfo = &flinfo; ++ eoinfo.localsyms = true; ++ eoinfo.file_sym_done = false; ++ bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo); ++ if (eoinfo.failed) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ ++ /* If backend needs to output some local symbols not present in the hash ++ table, do it now. */ ++ if (bed->elf_backend_output_arch_local_syms) ++ { ++ if (! ((*bed->elf_backend_output_arch_local_syms) ++ (abfd, info, &flinfo, elf_link_output_symstrtab))) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ } ++ ++ /* That wrote out all the local symbols. Finish up the symbol table ++ with the global symbols. Even if we want to strip everything we ++ can, we still need to deal with those global symbols that got ++ converted to local in a version script. */ ++ ++ /* The sh_info field records the index of the first non local symbol. */ ++ if (!symtab_hdr->sh_info) ++ symtab_hdr->sh_info = bfd_get_symcount (abfd); ++ ++ if (dynamic ++ && htab->dynsym != NULL ++ && htab->dynsym->output_section != bfd_abs_section_ptr) ++ { ++ Elf_Internal_Sym sym; ++ bfd_byte *dynsym = htab->dynsym->contents; ++ ++ o = htab->dynsym->output_section; ++ elf_section_data (o)->this_hdr.sh_info = htab->local_dynsymcount + 1; ++ ++ /* Write out the section symbols for the output sections. */ ++ if (bfd_link_pic (info) ++ || htab->is_relocatable_executable) ++ { ++ asection *s; ++ ++ sym.st_size = 0; ++ sym.st_name = 0; ++ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); ++ sym.st_other = 0; ++ sym.st_target_internal = 0; ++ ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ int indx; ++ bfd_byte *dest; ++ long dynindx; ++ ++ dynindx = elf_section_data (s)->dynindx; ++ if (dynindx <= 0) ++ continue; ++ indx = elf_section_data (s)->this_idx; ++ BFD_ASSERT (indx > 0); ++ sym.st_shndx = indx; ++ if (! check_dynsym (abfd, &sym)) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ sym.st_value = s->vma; ++ dest = dynsym + dynindx * bed->s->sizeof_sym; ++ ++ /* Inform the linker of the addition of this symbol. */ ++ ++ if (info->callbacks->ctf_new_dynsym) ++ info->callbacks->ctf_new_dynsym (dynindx, &sym); ++ ++ bed->s->swap_symbol_out (abfd, &sym, dest, 0); ++ } ++ } ++ ++ /* Write out the local dynsyms. */ ++ if (htab->dynlocal) ++ { ++ struct elf_link_local_dynamic_entry *e; ++ for (e = htab->dynlocal; e ; e = e->next) ++ { ++ asection *s; ++ bfd_byte *dest; ++ ++ /* Copy the internal symbol and turn off visibility. ++ Note that we saved a word of storage and overwrote ++ the original st_name with the dynstr_index. */ ++ sym = e->isym; ++ sym.st_other &= ~ELF_ST_VISIBILITY (-1); ++ sym.st_shndx = SHN_UNDEF; ++ ++ s = bfd_section_from_elf_index (e->input_bfd, ++ e->isym.st_shndx); ++ if (s != NULL ++ && s->output_section != NULL ++ && elf_section_data (s->output_section) != NULL) ++ { ++ sym.st_shndx = ++ elf_section_data (s->output_section)->this_idx; ++ if (! check_dynsym (abfd, &sym)) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ sym.st_value = (s->output_section->vma ++ + s->output_offset ++ + e->isym.st_value); ++ } ++ ++ /* Inform the linker of the addition of this symbol. */ ++ ++ if (info->callbacks->ctf_new_dynsym) ++ info->callbacks->ctf_new_dynsym (e->dynindx, &sym); ++ ++ dest = dynsym + e->dynindx * bed->s->sizeof_sym; ++ bed->s->swap_symbol_out (abfd, &sym, dest, 0); ++ } ++ } ++ } ++ ++ /* We get the global symbols from the hash table. */ ++ eoinfo.failed = false; ++ eoinfo.localsyms = false; ++ eoinfo.flinfo = &flinfo; ++ bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo); ++ if (eoinfo.failed) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ ++ /* If backend needs to output some symbols not present in the hash ++ table, do it now. */ ++ if (bed->elf_backend_output_arch_syms ++ && (info->strip != strip_all || emit_relocs)) ++ { ++ if (! ((*bed->elf_backend_output_arch_syms) ++ (abfd, info, &flinfo, elf_link_output_symstrtab))) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ } ++ ++ /* Finalize the .strtab section. */ ++ _bfd_elf_strtab_finalize (flinfo.symstrtab); ++ ++ /* Swap out the .strtab section. */ ++ if (!elf_link_swap_symbols_out (&flinfo)) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ ++ /* Now we know the size of the symtab section. */ ++ if (bfd_get_symcount (abfd) > 0) ++ { ++ /* Finish up and write out the symbol string table (.strtab) ++ section. */ ++ Elf_Internal_Shdr *symstrtab_hdr = NULL; ++ file_ptr off = symtab_hdr->sh_offset + symtab_hdr->sh_size; ++ ++ if (elf_symtab_shndx_list (abfd)) ++ { ++ symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr; ++ ++ if (symtab_shndx_hdr != NULL && symtab_shndx_hdr->sh_name != 0) ++ { ++ symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; ++ symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); ++ symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); ++ amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx); ++ symtab_shndx_hdr->sh_size = amt; ++ ++ off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, ++ off, true); ++ ++ if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 ++ || (bfd_bwrite (flinfo.symshndxbuf, amt, abfd) != amt)) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ } ++ } ++ ++ symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; ++ /* sh_name was set in prep_headers. */ ++ symstrtab_hdr->sh_type = SHT_STRTAB; ++ symstrtab_hdr->sh_flags = bed->elf_strtab_flags; ++ symstrtab_hdr->sh_addr = 0; ++ symstrtab_hdr->sh_size = _bfd_elf_strtab_size (flinfo.symstrtab); ++ symstrtab_hdr->sh_entsize = 0; ++ symstrtab_hdr->sh_link = 0; ++ symstrtab_hdr->sh_info = 0; ++ /* sh_offset is set just below. */ ++ symstrtab_hdr->sh_addralign = 1; ++ ++ off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, ++ off, true); ++ elf_next_file_pos (abfd) = off; ++ ++ if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 ++ || ! _bfd_elf_strtab_emit (abfd, flinfo.symstrtab)) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ } ++ ++ if (info->out_implib_bfd && !elf_output_implib (abfd, info)) ++ { ++ _bfd_error_handler (_("%pB: failed to generate import library"), ++ info->out_implib_bfd); ++ ret = false; ++ goto return_local_hash_table; ++ } ++ ++ /* Adjust the relocs to have the correct symbol indices. */ ++ for (o = abfd->sections; o != NULL; o = o->next) ++ { ++ struct bfd_elf_section_data *esdo = elf_section_data (o); ++ bool sort; ++ ++ if ((o->flags & SEC_RELOC) == 0) ++ continue; ++ ++ sort = bed->sort_relocs_p == NULL || (*bed->sort_relocs_p) (o); ++ if (esdo->rel.hdr != NULL ++ && !elf_link_adjust_relocs (abfd, o, &esdo->rel, sort, info)) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ if (esdo->rela.hdr != NULL ++ && !elf_link_adjust_relocs (abfd, o, &esdo->rela, sort, info)) ++ { ++ ret = false; ++ goto return_local_hash_table; ++ } ++ ++ /* Set the reloc_count field to 0 to prevent write_relocs from ++ trying to swap the relocs out itself. */ ++ o->reloc_count = 0; ++ } ++ ++ relativecount = 0; ++ if (dynamic && info->combreloc && dynobj != NULL) ++ relativecount = elf_link_sort_relocs (abfd, info, &reldyn); ++ ++ relr_entsize = 0; ++ if (htab->srelrdyn != NULL ++ && htab->srelrdyn->output_section != NULL ++ && htab->srelrdyn->size != 0) ++ { ++ asection *s = htab->srelrdyn->output_section; ++ relr_entsize = elf_section_data (s)->this_hdr.sh_entsize; ++ if (relr_entsize == 0) ++ { ++ relr_entsize = bed->s->arch_size / 8; ++ elf_section_data (s)->this_hdr.sh_entsize = relr_entsize; ++ } ++ } ++ ++ /* If we are linking against a dynamic object, or generating a ++ shared library, finish up the dynamic linking information. */ ++ if (dynamic) ++ { ++ bfd_byte *dyncon, *dynconend; ++ ++ /* Fix up .dynamic entries. */ ++ o = bfd_get_linker_section (dynobj, ".dynamic"); ++ BFD_ASSERT (o != NULL); ++ ++ dyncon = o->contents; ++ dynconend = PTR_ADD (o->contents, o->size); ++ for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) ++ { ++ Elf_Internal_Dyn dyn; ++ const char *name; ++ unsigned int type; ++ bfd_size_type sh_size; ++ bfd_vma sh_addr; ++ ++ bed->s->swap_dyn_in (dynobj, dyncon, &dyn); ++ ++ switch (dyn.d_tag) ++ { ++ default: ++ continue; ++ case DT_NULL: ++ if (relativecount != 0) ++ { ++ switch (elf_section_data (reldyn)->this_hdr.sh_type) ++ { ++ case SHT_REL: dyn.d_tag = DT_RELCOUNT; break; ++ case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break; ++ } ++ if (dyn.d_tag != DT_NULL ++ && dynconend - dyncon >= bed->s->sizeof_dyn) ++ { ++ dyn.d_un.d_val = relativecount; ++ relativecount = 0; ++ break; ++ } ++ relativecount = 0; ++ } ++ if (relr_entsize != 0) ++ { ++ if (dynconend - dyncon >= 3 * bed->s->sizeof_dyn) ++ { ++ asection *s = htab->srelrdyn; ++ dyn.d_tag = DT_RELR; ++ dyn.d_un.d_ptr ++ = s->output_section->vma + s->output_offset; ++ bed->s->swap_dyn_out (dynobj, &dyn, dyncon); ++ dyncon += bed->s->sizeof_dyn; ++ ++ dyn.d_tag = DT_RELRSZ; ++ dyn.d_un.d_val = s->size; ++ bed->s->swap_dyn_out (dynobj, &dyn, dyncon); ++ dyncon += bed->s->sizeof_dyn; ++ ++ dyn.d_tag = DT_RELRENT; ++ dyn.d_un.d_val = relr_entsize; ++ relr_entsize = 0; ++ break; ++ } ++ relr_entsize = 0; ++ } ++ continue; ++ ++ case DT_INIT: ++ name = info->init_function; ++ goto get_sym; ++ case DT_FINI: ++ name = info->fini_function; ++ get_sym: ++ { ++ struct elf_link_hash_entry *h; ++ ++ h = elf_link_hash_lookup (htab, name, false, false, true); ++ if (h != NULL ++ && (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak)) ++ { ++ dyn.d_un.d_ptr = h->root.u.def.value; ++ o = h->root.u.def.section; ++ if (o->output_section != NULL) ++ dyn.d_un.d_ptr += (o->output_section->vma ++ + o->output_offset); ++ else ++ { ++ /* The symbol is imported from another shared ++ library and does not apply to this one. */ ++ dyn.d_un.d_ptr = 0; ++ } ++ break; ++ } ++ } ++ continue; ++ ++ case DT_PREINIT_ARRAYSZ: ++ name = ".preinit_array"; ++ goto get_out_size; ++ case DT_INIT_ARRAYSZ: ++ name = ".init_array"; ++ goto get_out_size; ++ case DT_FINI_ARRAYSZ: ++ name = ".fini_array"; ++ get_out_size: ++ o = bfd_get_section_by_name (abfd, name); ++ if (o == NULL) ++ { ++ _bfd_error_handler ++ (_("could not find section %s"), name); ++ goto error_return; ++ } ++ if (o->size == 0) ++ _bfd_error_handler ++ (_("warning: %s section has zero size"), name); ++ dyn.d_un.d_val = o->size; ++ break; ++ ++ case DT_PREINIT_ARRAY: ++ name = ".preinit_array"; ++ goto get_out_vma; ++ case DT_INIT_ARRAY: ++ name = ".init_array"; ++ goto get_out_vma; ++ case DT_FINI_ARRAY: ++ name = ".fini_array"; ++ get_out_vma: ++ o = bfd_get_section_by_name (abfd, name); ++ goto do_vma; ++ ++ case DT_HASH: ++ name = ".hash"; ++ goto get_vma; ++ case DT_GNU_HASH: ++ name = ".gnu.hash"; ++ goto get_vma; ++ case DT_STRTAB: ++ name = ".dynstr"; ++ goto get_vma; ++ case DT_SYMTAB: ++ name = ".dynsym"; ++ goto get_vma; ++ case DT_VERDEF: ++ name = ".gnu.version_d"; ++ goto get_vma; ++ case DT_VERNEED: ++ name = ".gnu.version_r"; ++ goto get_vma; ++ case DT_VERSYM: ++ name = ".gnu.version"; ++ get_vma: ++ o = bfd_get_linker_section (dynobj, name); ++ do_vma: ++ if (o == NULL || bfd_is_abs_section (o->output_section)) ++ { ++ _bfd_error_handler ++ (_("could not find section %s"), name); ++ goto error_return; ++ } ++ if (elf_section_data (o->output_section)->this_hdr.sh_type == SHT_NOTE) ++ { ++ _bfd_error_handler ++ (_("warning: section '%s' is being made into a note"), name); ++ bfd_set_error (bfd_error_nonrepresentable_section); ++ goto error_return; ++ } ++ dyn.d_un.d_ptr = o->output_section->vma + o->output_offset; ++ break; ++ ++ case DT_REL: ++ case DT_RELA: ++ case DT_RELSZ: ++ case DT_RELASZ: ++ if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) ++ type = SHT_REL; ++ else ++ type = SHT_RELA; ++ sh_size = 0; ++ sh_addr = 0; ++ for (i = 1; i < elf_numsections (abfd); i++) ++ { ++ Elf_Internal_Shdr *hdr; ++ ++ hdr = elf_elfsections (abfd)[i]; ++ if (hdr->sh_type == type ++ && (hdr->sh_flags & SHF_ALLOC) != 0) ++ { ++ sh_size += hdr->sh_size; ++ if (sh_addr == 0 ++ || sh_addr > hdr->sh_addr) ++ sh_addr = hdr->sh_addr; ++ } ++ } ++ ++ if (bed->dtrel_excludes_plt && htab->srelplt != NULL) ++ { ++ unsigned int opb = bfd_octets_per_byte (abfd, o); ++ ++ /* Don't count procedure linkage table relocs in the ++ overall reloc count. */ ++ sh_size -= htab->srelplt->size; ++ if (sh_size == 0) ++ /* If the size is zero, make the address zero too. ++ This is to avoid a glibc bug. If the backend ++ emits DT_RELA/DT_RELASZ even when DT_RELASZ is ++ zero, then we'll put DT_RELA at the end of ++ DT_JMPREL. glibc will interpret the end of ++ DT_RELA matching the end of DT_JMPREL as the ++ case where DT_RELA includes DT_JMPREL, and for ++ LD_BIND_NOW will decide that processing DT_RELA ++ will process the PLT relocs too. Net result: ++ No PLT relocs applied. */ ++ sh_addr = 0; ++ ++ /* If .rela.plt is the first .rela section, exclude ++ it from DT_RELA. */ ++ else if (sh_addr == (htab->srelplt->output_section->vma ++ + htab->srelplt->output_offset) * opb) ++ sh_addr += htab->srelplt->size; ++ } ++ ++ if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) ++ dyn.d_un.d_val = sh_size; ++ else ++ dyn.d_un.d_ptr = sh_addr; ++ break; ++ } ++ bed->s->swap_dyn_out (dynobj, &dyn, dyncon); ++ } ++ } ++ ++ /* If we have created any dynamic sections, then output them. */ ++ if (dynobj != NULL) ++ { ++ if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) ++ goto error_return; ++ ++ /* Check for DT_TEXTREL (late, in case the backend removes it). */ ++ if (bfd_link_textrel_check (info) ++ && (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL ++ && o->size != 0) ++ { ++ bfd_byte *dyncon, *dynconend; ++ ++ dyncon = o->contents; ++ dynconend = o->contents + o->size; ++ for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) ++ { ++ Elf_Internal_Dyn dyn; ++ ++ bed->s->swap_dyn_in (dynobj, dyncon, &dyn); ++ ++ if (dyn.d_tag == DT_TEXTREL) ++ { ++ if (info->textrel_check == textrel_check_error) ++ info->callbacks->einfo ++ (_("%P%X: read-only segment has dynamic relocations\n")); ++ else if (bfd_link_dll (info)) ++ info->callbacks->einfo ++ (_("%P: warning: creating DT_TEXTREL in a shared object\n")); ++ else if (bfd_link_pde (info)) ++ info->callbacks->einfo ++ (_("%P: warning: creating DT_TEXTREL in a PDE\n")); ++ else ++ info->callbacks->einfo ++ (_("%P: warning: creating DT_TEXTREL in a PIE\n")); ++ break; ++ } ++ } ++ } ++ ++ for (o = dynobj->sections; o != NULL; o = o->next) ++ { ++ if ((o->flags & SEC_HAS_CONTENTS) == 0 ++ || o->size == 0 ++ || o->output_section == bfd_abs_section_ptr) ++ continue; ++ if ((o->flags & SEC_LINKER_CREATED) == 0) ++ { ++ /* At this point, we are only interested in sections ++ created by _bfd_elf_link_create_dynamic_sections. */ ++ continue; ++ } ++ if (htab->stab_info.stabstr == o) ++ continue; ++ if (htab->eh_info.hdr_sec == o) ++ continue; ++ if (strcmp (o->name, ".dynstr") != 0) ++ { ++ bfd_size_type octets = ((file_ptr) o->output_offset ++ * bfd_octets_per_byte (abfd, o)); ++ if (!bfd_set_section_contents (abfd, o->output_section, ++ o->contents, octets, o->size)) ++ goto error_return; ++ } ++ else ++ { ++ /* The contents of the .dynstr section are actually in a ++ stringtab. */ ++ file_ptr off; ++ ++ off = elf_section_data (o->output_section)->this_hdr.sh_offset; ++ if (bfd_seek (abfd, off, SEEK_SET) != 0 ++ || !_bfd_elf_strtab_emit (abfd, htab->dynstr)) ++ goto error_return; ++ } ++ } ++ } ++ ++ if (!info->resolve_section_groups) ++ { ++ bool failed = false; ++ ++ BFD_ASSERT (bfd_link_relocatable (info)); ++ bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); ++ if (failed) ++ goto error_return; ++ } ++ ++ /* If we have optimized stabs strings, output them. */ ++ if (htab->stab_info.stabstr != NULL) ++ { ++ if (!_bfd_write_stab_strings (abfd, &htab->stab_info)) ++ goto error_return; ++ } ++ ++ if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) ++ goto error_return; ++ ++ if (! _bfd_elf_write_section_sframe (abfd, info)) ++ goto error_return; ++ ++ if (info->callbacks->emit_ctf) ++ info->callbacks->emit_ctf (); ++ ++ elf_final_link_free (abfd, &flinfo); ++ ++ if (attr_section) ++ { ++ bfd_byte *contents = (bfd_byte *) bfd_malloc (attr_size); ++ if (contents == NULL) ++ { ++ /* Bail out and fail. */ ++ ret = false; ++ goto return_local_hash_table; ++ } ++ bfd_elf_set_obj_attr_contents (abfd, contents, attr_size); ++ bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size); ++ free (contents); ++ } ++ ++ return_local_hash_table: ++ if (info->unique_symbol) ++ bfd_hash_table_free (&flinfo.local_hash_table); ++ return ret; ++ ++ error_return: ++ elf_final_link_free (abfd, &flinfo); ++ ret = false; ++ goto return_local_hash_table; ++} ++ ++/* Initialize COOKIE for input bfd ABFD. */ ++ ++static bool ++init_reloc_cookie (struct elf_reloc_cookie *cookie, ++ struct bfd_link_info *info, bfd *abfd) ++{ ++ Elf_Internal_Shdr *symtab_hdr; ++ const struct elf_backend_data *bed; ++ ++ bed = get_elf_backend_data (abfd); ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ ++ cookie->abfd = abfd; ++ cookie->sym_hashes = elf_sym_hashes (abfd); ++ cookie->bad_symtab = elf_bad_symtab (abfd); ++ if (cookie->bad_symtab) ++ { ++ cookie->locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; ++ cookie->extsymoff = 0; ++ } ++ else ++ { ++ cookie->locsymcount = symtab_hdr->sh_info; ++ cookie->extsymoff = symtab_hdr->sh_info; ++ } ++ ++ if (bed->s->arch_size == 32) ++ cookie->r_sym_shift = 8; ++ else ++ cookie->r_sym_shift = 32; ++ ++ cookie->locsyms = (Elf_Internal_Sym *) symtab_hdr->contents; ++ if (cookie->locsyms == NULL && cookie->locsymcount != 0) ++ { ++ cookie->locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, ++ cookie->locsymcount, 0, ++ NULL, NULL, NULL); ++ if (cookie->locsyms == NULL) ++ { ++ info->callbacks->einfo (_("%P%X: can not read symbols: %E\n")); ++ return false; ++ } ++ if (_bfd_link_keep_memory (info) ) ++ { ++ symtab_hdr->contents = (bfd_byte *) cookie->locsyms; ++ info->cache_size += (cookie->locsymcount ++ * sizeof (Elf_External_Sym_Shndx)); ++ } ++ } ++ return true; ++} ++ ++/* Free the memory allocated by init_reloc_cookie, if appropriate. */ ++ ++static void ++fini_reloc_cookie (struct elf_reloc_cookie *cookie, bfd *abfd) ++{ ++ Elf_Internal_Shdr *symtab_hdr; ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ if (symtab_hdr->contents != (unsigned char *) cookie->locsyms) ++ free (cookie->locsyms); ++} ++ ++/* Initialize the relocation information in COOKIE for input section SEC ++ of input bfd ABFD. */ ++ ++static bool ++init_reloc_cookie_rels (struct elf_reloc_cookie *cookie, ++ struct bfd_link_info *info, bfd *abfd, ++ asection *sec) ++{ ++ if (sec->reloc_count == 0) ++ { ++ cookie->rels = NULL; ++ cookie->relend = NULL; ++ } ++ else ++ { ++ cookie->rels = _bfd_elf_link_info_read_relocs (abfd, info, sec, ++ NULL, NULL, ++ _bfd_link_keep_memory (info)); ++ if (cookie->rels == NULL) ++ return false; ++ cookie->rel = cookie->rels; ++ cookie->relend = cookie->rels + sec->reloc_count; ++ } ++ cookie->rel = cookie->rels; ++ return true; ++} ++ ++/* Free the memory allocated by init_reloc_cookie_rels, ++ if appropriate. */ ++ ++static void ++fini_reloc_cookie_rels (struct elf_reloc_cookie *cookie, ++ asection *sec) ++{ ++ if (elf_section_data (sec)->relocs != cookie->rels) ++ free (cookie->rels); ++} ++ ++/* Initialize the whole of COOKIE for input section SEC. */ ++ ++static bool ++init_reloc_cookie_for_section (struct elf_reloc_cookie *cookie, ++ struct bfd_link_info *info, ++ asection *sec) ++{ ++ if (!init_reloc_cookie (cookie, info, sec->owner)) ++ goto error1; ++ if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec)) ++ goto error2; ++ return true; ++ ++ error2: ++ fini_reloc_cookie (cookie, sec->owner); ++ error1: ++ return false; ++} ++ ++/* Free the memory allocated by init_reloc_cookie_for_section, ++ if appropriate. */ ++ ++static void ++fini_reloc_cookie_for_section (struct elf_reloc_cookie *cookie, ++ asection *sec) ++{ ++ fini_reloc_cookie_rels (cookie, sec); ++ fini_reloc_cookie (cookie, sec->owner); ++} ++ ++/* Garbage collect unused sections. */ ++ ++/* Default gc_mark_hook. */ ++ ++asection * ++_bfd_elf_gc_mark_hook (asection *sec, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, ++ struct elf_link_hash_entry *h, ++ Elf_Internal_Sym *sym) ++{ ++ if (h != NULL) ++ { ++ switch (h->root.type) ++ { ++ case bfd_link_hash_defined: ++ case bfd_link_hash_defweak: ++ return h->root.u.def.section; ++ ++ case bfd_link_hash_common: ++ return h->root.u.c.p->section; ++ ++ default: ++ break; ++ } ++ } ++ else ++ return bfd_section_from_elf_index (sec->owner, sym->st_shndx); ++ ++ return NULL; ++} ++ ++/* Return the debug definition section. */ ++ ++static asection * ++elf_gc_mark_debug_section (asection *sec ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, ++ struct elf_link_hash_entry *h, ++ Elf_Internal_Sym *sym) ++{ ++ if (h != NULL) ++ { ++ /* Return the global debug definition section. */ ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && (h->root.u.def.section->flags & SEC_DEBUGGING) != 0) ++ return h->root.u.def.section; ++ } ++ else ++ { ++ /* Return the local debug definition section. */ ++ asection *isec = bfd_section_from_elf_index (sec->owner, ++ sym->st_shndx); ++ if ((isec->flags & SEC_DEBUGGING) != 0) ++ return isec; ++ } ++ ++ return NULL; ++} ++ ++/* COOKIE->rel describes a relocation against section SEC, which is ++ a section we've decided to keep. Return the section that contains ++ the relocation symbol, or NULL if no section contains it. */ ++ ++asection * ++_bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec, ++ elf_gc_mark_hook_fn gc_mark_hook, ++ struct elf_reloc_cookie *cookie, ++ bool *start_stop) ++{ ++ unsigned long r_symndx; ++ struct elf_link_hash_entry *h, *hw; ++ ++ r_symndx = cookie->rel->r_info >> cookie->r_sym_shift; ++ if (r_symndx == STN_UNDEF) ++ return NULL; ++ ++ if (r_symndx >= cookie->locsymcount ++ || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL) ++ { ++ bool was_marked; ++ ++ h = cookie->sym_hashes[r_symndx - cookie->extsymoff]; ++ if (h == NULL) ++ { ++ info->callbacks->einfo (_("%F%P: corrupt input: %pB\n"), ++ sec->owner); ++ return NULL; ++ } ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ was_marked = h->mark; ++ h->mark = 1; ++ /* Keep all aliases of the symbol too. If an object symbol ++ needs to be copied into .dynbss then all of its aliases ++ should be present as dynamic symbols, not just the one used ++ on the copy relocation. */ ++ hw = h; ++ while (hw->is_weakalias) ++ { ++ hw = hw->u.alias; ++ hw->mark = 1; ++ } ++ ++ if (!was_marked && h->start_stop && !h->root.ldscript_def) ++ { ++ if (info->start_stop_gc) ++ return NULL; ++ ++ /* To work around a glibc bug, mark XXX input sections ++ when there is a reference to __start_XXX or __stop_XXX ++ symbols. */ ++ else if (start_stop != NULL) ++ { ++ asection *s = h->u2.start_stop_section; ++ *start_stop = true; ++ return s; ++ } ++ } ++ ++ return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL); ++ } ++ ++ return (*gc_mark_hook) (sec, info, cookie->rel, NULL, ++ &cookie->locsyms[r_symndx]); ++} ++ ++/* COOKIE->rel describes a relocation against section SEC, which is ++ a section we've decided to keep. Mark the section that contains ++ the relocation symbol. */ ++ ++bool ++_bfd_elf_gc_mark_reloc (struct bfd_link_info *info, ++ asection *sec, ++ elf_gc_mark_hook_fn gc_mark_hook, ++ struct elf_reloc_cookie *cookie) ++{ ++ asection *rsec; ++ bool start_stop = false; ++ ++ rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie, &start_stop); ++ while (rsec != NULL) ++ { ++ if (!rsec->gc_mark) ++ { ++ if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour ++ || (rsec->owner->flags & DYNAMIC) != 0) ++ rsec->gc_mark = 1; ++ else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook)) ++ return false; ++ } ++ if (!start_stop) ++ break; ++ rsec = bfd_get_next_section_by_name (rsec->owner, rsec); ++ } ++ return true; ++} ++ ++/* The mark phase of garbage collection. For a given section, mark ++ it and any sections in this section's group, and all the sections ++ which define symbols to which it refers. */ ++ ++bool ++_bfd_elf_gc_mark (struct bfd_link_info *info, ++ asection *sec, ++ elf_gc_mark_hook_fn gc_mark_hook) ++{ ++ bool ret; ++ asection *group_sec, *eh_frame; ++ ++ sec->gc_mark = 1; ++ ++ /* Mark all the sections in the group. */ ++ group_sec = elf_section_data (sec)->next_in_group; ++ if (group_sec && !group_sec->gc_mark) ++ if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook)) ++ return false; ++ ++ /* Look through the section relocs. */ ++ ret = true; ++ eh_frame = elf_eh_frame_section (sec->owner); ++ if ((sec->flags & SEC_RELOC) != 0 ++ && sec->reloc_count > 0 ++ && sec != eh_frame) ++ { ++ struct elf_reloc_cookie cookie; ++ ++ if (!init_reloc_cookie_for_section (&cookie, info, sec)) ++ ret = false; ++ else ++ { ++ for (; cookie.rel < cookie.relend; cookie.rel++) ++ if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, &cookie)) ++ { ++ ret = false; ++ break; ++ } ++ fini_reloc_cookie_for_section (&cookie, sec); ++ } ++ } ++ ++ if (ret && eh_frame && elf_fde_list (sec)) ++ { ++ struct elf_reloc_cookie cookie; ++ ++ if (!init_reloc_cookie_for_section (&cookie, info, eh_frame)) ++ ret = false; ++ else ++ { ++ if (!_bfd_elf_gc_mark_fdes (info, sec, eh_frame, ++ gc_mark_hook, &cookie)) ++ ret = false; ++ fini_reloc_cookie_for_section (&cookie, eh_frame); ++ } ++ } ++ ++ eh_frame = elf_section_eh_frame_entry (sec); ++ if (ret && eh_frame && !eh_frame->gc_mark) ++ if (!_bfd_elf_gc_mark (info, eh_frame, gc_mark_hook)) ++ ret = false; ++ ++ return ret; ++} ++ ++/* Scan and mark sections in a special or debug section group. */ ++ ++static void ++_bfd_elf_gc_mark_debug_special_section_group (asection *grp) ++{ ++ /* Point to first section of section group. */ ++ asection *ssec; ++ /* Used to iterate the section group. */ ++ asection *msec; ++ ++ bool is_special_grp = true; ++ bool is_debug_grp = true; ++ ++ /* First scan to see if group contains any section other than debug ++ and special section. */ ++ ssec = msec = elf_next_in_group (grp); ++ do ++ { ++ if ((msec->flags & SEC_DEBUGGING) == 0) ++ is_debug_grp = false; ++ ++ if ((msec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) != 0) ++ is_special_grp = false; ++ ++ msec = elf_next_in_group (msec); ++ } ++ while (msec != ssec); ++ ++ /* If this is a pure debug section group or pure special section group, ++ keep all sections in this group. */ ++ if (is_debug_grp || is_special_grp) ++ { ++ do ++ { ++ msec->gc_mark = 1; ++ msec = elf_next_in_group (msec); ++ } ++ while (msec != ssec); ++ } ++} ++ ++/* Keep debug and special sections. */ ++ ++bool ++_bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, ++ elf_gc_mark_hook_fn mark_hook) ++{ ++ bfd *ibfd; ++ ++ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) ++ { ++ asection *isec; ++ bool some_kept; ++ bool debug_frag_seen; ++ bool has_kept_debug_info; ++ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) ++ continue; ++ isec = ibfd->sections; ++ if (isec == NULL || isec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ continue; ++ ++ /* Ensure all linker created sections are kept, ++ see if any other section is already marked, ++ and note if we have any fragmented debug sections. */ ++ debug_frag_seen = some_kept = has_kept_debug_info = false; ++ for (isec = ibfd->sections; isec != NULL; isec = isec->next) ++ { ++ if ((isec->flags & SEC_LINKER_CREATED) != 0) ++ isec->gc_mark = 1; ++ else if (isec->gc_mark ++ && (isec->flags & SEC_ALLOC) != 0 ++ && elf_section_type (isec) != SHT_NOTE) ++ some_kept = true; ++ else ++ { ++ /* Since all sections, except for backend specific ones, ++ have been garbage collected, call mark_hook on this ++ section if any of its linked-to sections is marked. */ ++ asection *linked_to_sec; ++ for (linked_to_sec = elf_linked_to_section (isec); ++ linked_to_sec != NULL && !linked_to_sec->linker_mark; ++ linked_to_sec = elf_linked_to_section (linked_to_sec)) ++ { ++ if (linked_to_sec->gc_mark) ++ { ++ if (!_bfd_elf_gc_mark (info, isec, mark_hook)) ++ return false; ++ break; ++ } ++ linked_to_sec->linker_mark = 1; ++ } ++ for (linked_to_sec = elf_linked_to_section (isec); ++ linked_to_sec != NULL && linked_to_sec->linker_mark; ++ linked_to_sec = elf_linked_to_section (linked_to_sec)) ++ linked_to_sec->linker_mark = 0; ++ } ++ ++ if (!debug_frag_seen ++ && (isec->flags & SEC_DEBUGGING) ++ && startswith (isec->name, ".debug_line.")) ++ debug_frag_seen = true; ++ else if (strcmp (bfd_section_name (isec), ++ "__patchable_function_entries") == 0 ++ && elf_linked_to_section (isec) == NULL) ++ info->callbacks->einfo (_("%F%P: %pB(%pA): error: " ++ "need linked-to section " ++ "for --gc-sections\n"), ++ isec->owner, isec); ++ } ++ ++ /* If no non-note alloc section in this file will be kept, then ++ we can toss out the debug and special sections. */ ++ if (!some_kept) ++ continue; ++ ++ /* Keep debug and special sections like .comment when they are ++ not part of a group. Also keep section groups that contain ++ just debug sections or special sections. NB: Sections with ++ linked-to section has been handled above. */ ++ for (isec = ibfd->sections; isec != NULL; isec = isec->next) ++ { ++ if ((isec->flags & SEC_GROUP) != 0) ++ _bfd_elf_gc_mark_debug_special_section_group (isec); ++ else if (((isec->flags & SEC_DEBUGGING) != 0 ++ || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) ++ && elf_next_in_group (isec) == NULL ++ && elf_linked_to_section (isec) == NULL) ++ isec->gc_mark = 1; ++ if (isec->gc_mark && (isec->flags & SEC_DEBUGGING) != 0) ++ has_kept_debug_info = true; ++ } ++ ++ /* Look for CODE sections which are going to be discarded, ++ and find and discard any fragmented debug sections which ++ are associated with that code section. */ ++ if (debug_frag_seen) ++ for (isec = ibfd->sections; isec != NULL; isec = isec->next) ++ if ((isec->flags & SEC_CODE) != 0 ++ && isec->gc_mark == 0) ++ { ++ unsigned int ilen; ++ asection *dsec; ++ ++ ilen = strlen (isec->name); ++ ++ /* Association is determined by the name of the debug ++ section containing the name of the code section as ++ a suffix. For example .debug_line.text.foo is a ++ debug section associated with .text.foo. */ ++ for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next) ++ { ++ unsigned int dlen; ++ ++ if (dsec->gc_mark == 0 ++ || (dsec->flags & SEC_DEBUGGING) == 0) ++ continue; ++ ++ dlen = strlen (dsec->name); ++ ++ if (dlen > ilen ++ && strncmp (dsec->name + (dlen - ilen), ++ isec->name, ilen) == 0) ++ dsec->gc_mark = 0; ++ } ++ } ++ ++ /* Mark debug sections referenced by kept debug sections. */ ++ if (has_kept_debug_info) ++ for (isec = ibfd->sections; isec != NULL; isec = isec->next) ++ if (isec->gc_mark ++ && (isec->flags & SEC_DEBUGGING) != 0) ++ if (!_bfd_elf_gc_mark (info, isec, ++ elf_gc_mark_debug_section)) ++ return false; ++ } ++ return true; ++} ++ ++static bool ++elf_gc_sweep (bfd *abfd, struct bfd_link_info *info) ++{ ++ bfd *sub; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) ++ { ++ asection *o; ++ ++ if (bfd_get_flavour (sub) != bfd_target_elf_flavour ++ || elf_object_id (sub) != elf_hash_table_id (elf_hash_table (info)) ++ || !(*bed->relocs_compatible) (sub->xvec, abfd->xvec)) ++ continue; ++ o = sub->sections; ++ if (o == NULL || o->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ continue; ++ ++ for (o = sub->sections; o != NULL; o = o->next) ++ { ++ /* When any section in a section group is kept, we keep all ++ sections in the section group. If the first member of ++ the section group is excluded, we will also exclude the ++ group section. */ ++ if (o->flags & SEC_GROUP) ++ { ++ asection *first = elf_next_in_group (o); ++ o->gc_mark = first->gc_mark; ++ } ++ ++ if (o->gc_mark) ++ continue; ++ ++ /* Skip sweeping sections already excluded. */ ++ if (o->flags & SEC_EXCLUDE) ++ continue; ++ ++ /* Since this is early in the link process, it is simple ++ to remove a section from the output. */ ++ o->flags |= SEC_EXCLUDE; ++ ++ if (info->print_gc_sections && o->size != 0) ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("removing unused section '%pA' in file '%pB'"), ++ o, sub); ++ } ++ } ++ ++ return true; ++} ++ ++/* Propagate collected vtable information. This is called through ++ elf_link_hash_traverse. */ ++ ++static bool ++elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp) ++{ ++ /* Those that are not vtables. */ ++ if (h->start_stop ++ || h->u2.vtable == NULL ++ || h->u2.vtable->parent == NULL) ++ return true; ++ ++ /* Those vtables that do not have parents, we cannot merge. */ ++ if (h->u2.vtable->parent == (struct elf_link_hash_entry *) -1) ++ return true; ++ ++ /* If we've already been done, exit. */ ++ if (h->u2.vtable->used && h->u2.vtable->used[-1]) ++ return true; ++ ++ /* Make sure the parent's table is up to date. */ ++ elf_gc_propagate_vtable_entries_used (h->u2.vtable->parent, okp); ++ ++ if (h->u2.vtable->used == NULL) ++ { ++ /* None of this table's entries were referenced. Re-use the ++ parent's table. */ ++ h->u2.vtable->used = h->u2.vtable->parent->u2.vtable->used; ++ h->u2.vtable->size = h->u2.vtable->parent->u2.vtable->size; ++ } ++ else ++ { ++ size_t n; ++ bool *cu, *pu; ++ ++ /* Or the parent's entries into ours. */ ++ cu = h->u2.vtable->used; ++ cu[-1] = true; ++ pu = h->u2.vtable->parent->u2.vtable->used; ++ if (pu != NULL) ++ { ++ const struct elf_backend_data *bed; ++ unsigned int log_file_align; ++ ++ bed = get_elf_backend_data (h->root.u.def.section->owner); ++ log_file_align = bed->s->log_file_align; ++ n = h->u2.vtable->parent->u2.vtable->size >> log_file_align; ++ while (n--) ++ { ++ if (*pu) ++ *cu = true; ++ pu++; ++ cu++; ++ } ++ } ++ } ++ ++ return true; ++} ++ ++struct link_info_ok ++{ ++ struct bfd_link_info *info; ++ bool ok; ++}; ++ ++static bool ++elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, ++ void *ptr) ++{ ++ asection *sec; ++ bfd_vma hstart, hend; ++ Elf_Internal_Rela *relstart, *relend, *rel; ++ const struct elf_backend_data *bed; ++ unsigned int log_file_align; ++ struct link_info_ok *info = (struct link_info_ok *) ptr; ++ ++ /* Take care of both those symbols that do not describe vtables as ++ well as those that are not loaded. */ ++ if (h->start_stop ++ || h->u2.vtable == NULL ++ || h->u2.vtable->parent == NULL) ++ return true; ++ ++ BFD_ASSERT (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak); ++ ++ sec = h->root.u.def.section; ++ hstart = h->root.u.def.value; ++ hend = hstart + h->size; ++ ++ relstart = _bfd_elf_link_info_read_relocs (sec->owner, info->info, ++ sec, NULL, NULL, true); ++ if (!relstart) ++ return info->ok = false; ++ bed = get_elf_backend_data (sec->owner); ++ log_file_align = bed->s->log_file_align; ++ ++ relend = relstart + sec->reloc_count; ++ ++ for (rel = relstart; rel < relend; ++rel) ++ if (rel->r_offset >= hstart && rel->r_offset < hend) ++ { ++ /* If the entry is in use, do nothing. */ ++ if (h->u2.vtable->used ++ && (rel->r_offset - hstart) < h->u2.vtable->size) ++ { ++ bfd_vma entry = (rel->r_offset - hstart) >> log_file_align; ++ if (h->u2.vtable->used[entry]) ++ continue; ++ } ++ /* Otherwise, kill it. */ ++ rel->r_offset = rel->r_info = rel->r_addend = 0; ++ } ++ ++ return true; ++} ++ ++/* Mark sections containing dynamically referenced symbols. When ++ building shared libraries, we must assume that any visible symbol is ++ referenced. */ ++ ++bool ++bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf) ++{ ++ struct bfd_link_info *info = (struct bfd_link_info *) inf; ++ struct bfd_elf_dynamic_list *d = info->dynamic_list; ++ ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && (!h->start_stop ++ || h->root.ldscript_def ++ || !info->start_stop_gc) ++ && ((h->ref_dynamic && !h->forced_local) ++ || ((h->def_regular || ELF_COMMON_DEF_P (h)) ++ && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL ++ && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN ++ && (!bfd_link_executable (info) ++ || info->gc_keep_exported ++ || info->export_dynamic ++ || (h->dynamic ++ && d != NULL ++ && (*d->match) (&d->head, NULL, h->root.root.string))) ++ && (h->versioned >= versioned ++ || !bfd_hide_sym_by_version (info->version_info, ++ h->root.root.string))))) ++ h->root.u.def.section->flags |= SEC_KEEP; ++ ++ return true; ++} ++ ++/* Keep all sections containing symbols undefined on the command-line, ++ and the section containing the entry symbol. */ ++ ++void ++_bfd_elf_gc_keep (struct bfd_link_info *info) ++{ ++ struct bfd_sym_chain *sym; ++ ++ for (sym = info->gc_sym_list; sym != NULL; sym = sym->next) ++ { ++ struct elf_link_hash_entry *h; ++ ++ h = elf_link_hash_lookup (elf_hash_table (info), sym->name, ++ false, false, false); ++ ++ if (h != NULL ++ && (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && !bfd_is_const_section (h->root.u.def.section)) ++ h->root.u.def.section->flags |= SEC_KEEP; ++ } ++} ++ ++bool ++bfd_elf_parse_eh_frame_entries (bfd *abfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info) ++{ ++ bfd *ibfd = info->input_bfds; ++ ++ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) ++ { ++ asection *sec; ++ struct elf_reloc_cookie cookie; ++ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) ++ continue; ++ sec = ibfd->sections; ++ if (sec == NULL || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ continue; ++ ++ if (!init_reloc_cookie (&cookie, info, ibfd)) ++ return false; ++ ++ for (sec = ibfd->sections; sec; sec = sec->next) ++ { ++ if (startswith (bfd_section_name (sec), ".eh_frame_entry") ++ && init_reloc_cookie_rels (&cookie, info, ibfd, sec)) ++ { ++ _bfd_elf_parse_eh_frame_entry (info, sec, &cookie); ++ fini_reloc_cookie_rels (&cookie, sec); ++ } ++ } ++ } ++ return true; ++} ++ ++/* Do mark and sweep of unused sections. */ ++ ++bool ++bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) ++{ ++ bool ok = true; ++ bfd *sub; ++ elf_gc_mark_hook_fn gc_mark_hook; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct elf_link_hash_table *htab; ++ struct link_info_ok info_ok; ++ ++ if (!bed->can_gc_sections ++ || !is_elf_hash_table (info->hash)) ++ { ++ _bfd_error_handler(_("warning: gc-sections option ignored")); ++ return true; ++ } ++ ++ bed->gc_keep (info); ++ htab = elf_hash_table (info); ++ ++ /* Try to parse each bfd's .eh_frame section. Point elf_eh_frame_section ++ at the .eh_frame section if we can mark the FDEs individually. */ ++ for (sub = info->input_bfds; ++ info->eh_frame_hdr_type != COMPACT_EH_HDR && sub != NULL; ++ sub = sub->link.next) ++ { ++ asection *sec; ++ struct elf_reloc_cookie cookie; ++ ++ sec = sub->sections; ++ if (sec == NULL || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ continue; ++ sec = bfd_get_section_by_name (sub, ".eh_frame"); ++ while (sec && init_reloc_cookie_for_section (&cookie, info, sec)) ++ { ++ _bfd_elf_parse_eh_frame (sub, info, sec, &cookie); ++ if (elf_section_data (sec)->sec_info ++ && (sec->flags & SEC_LINKER_CREATED) == 0) ++ elf_eh_frame_section (sub) = sec; ++ fini_reloc_cookie_for_section (&cookie, sec); ++ sec = bfd_get_next_section_by_name (NULL, sec); ++ } ++ } ++ ++ /* Apply transitive closure to the vtable entry usage info. */ ++ elf_link_hash_traverse (htab, elf_gc_propagate_vtable_entries_used, &ok); ++ if (!ok) ++ return false; ++ ++ /* Kill the vtable relocations that were not used. */ ++ info_ok.info = info; ++ info_ok.ok = true; ++ elf_link_hash_traverse (htab, elf_gc_smash_unused_vtentry_relocs, &info_ok); ++ if (!info_ok.ok) ++ return false; ++ ++ /* Mark dynamically referenced symbols. */ ++ if (htab->dynamic_sections_created || info->gc_keep_exported) ++ elf_link_hash_traverse (htab, bed->gc_mark_dynamic_ref, info); ++ ++ /* Grovel through relocs to find out who stays ... */ ++ gc_mark_hook = bed->gc_mark_hook; ++ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) ++ { ++ asection *o; ++ ++ if (bfd_get_flavour (sub) != bfd_target_elf_flavour ++ || elf_object_id (sub) != elf_hash_table_id (htab) ++ || !(*bed->relocs_compatible) (sub->xvec, abfd->xvec)) ++ continue; ++ ++ o = sub->sections; ++ if (o == NULL || o->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ continue; ++ ++ /* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep). ++ Also treat note sections as a root, if the section is not part ++ of a group. We must keep all PREINIT_ARRAY, INIT_ARRAY as ++ well as FINI_ARRAY sections for ld -r. */ ++ for (o = sub->sections; o != NULL; o = o->next) ++ if (!o->gc_mark ++ && (o->flags & SEC_EXCLUDE) == 0 ++ && ((o->flags & SEC_KEEP) != 0 ++ || (bfd_link_relocatable (info) ++ && ((elf_section_data (o)->this_hdr.sh_type ++ == SHT_PREINIT_ARRAY) ++ || (elf_section_data (o)->this_hdr.sh_type ++ == SHT_INIT_ARRAY) ++ || (elf_section_data (o)->this_hdr.sh_type ++ == SHT_FINI_ARRAY))) ++ || (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE ++ && elf_next_in_group (o) == NULL ++ && elf_linked_to_section (o) == NULL) ++ || ((elf_tdata (sub)->has_gnu_osabi & elf_gnu_osabi_retain) ++ && (elf_section_flags (o) & SHF_GNU_RETAIN)))) ++ { ++ if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) ++ return false; ++ } ++ } ++ ++ /* Allow the backend to mark additional target specific sections. */ ++ bed->gc_mark_extra_sections (info, gc_mark_hook); ++ ++ /* ... and mark SEC_EXCLUDE for those that go. */ ++ return elf_gc_sweep (abfd, info); ++} ++ ++/* Called from check_relocs to record the existence of a VTINHERIT reloc. */ ++ ++bool ++bfd_elf_gc_record_vtinherit (bfd *abfd, ++ asection *sec, ++ struct elf_link_hash_entry *h, ++ bfd_vma offset) ++{ ++ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; ++ struct elf_link_hash_entry **search, *child; ++ size_t extsymcount; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ ++ /* The sh_info field of the symtab header tells us where the ++ external symbols start. We don't care about the local symbols at ++ this point. */ ++ extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym; ++ if (!elf_bad_symtab (abfd)) ++ extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info; ++ ++ sym_hashes = elf_sym_hashes (abfd); ++ sym_hashes_end = PTR_ADD (sym_hashes, extsymcount); ++ ++ /* Hunt down the child symbol, which is in this section at the same ++ offset as the relocation. */ ++ for (search = sym_hashes; search != sym_hashes_end; ++search) ++ { ++ if ((child = *search) != NULL ++ && (child->root.type == bfd_link_hash_defined ++ || child->root.type == bfd_link_hash_defweak) ++ && child->root.u.def.section == sec ++ && child->root.u.def.value == offset) ++ goto win; ++ } ++ ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: %pA+%#" PRIx64 ": no symbol found for INHERIT"), ++ abfd, sec, (uint64_t) offset); ++ bfd_set_error (bfd_error_invalid_operation); ++ return false; ++ ++ win: ++ if (!child->u2.vtable) ++ { ++ child->u2.vtable = ((struct elf_link_virtual_table_entry *) ++ bfd_zalloc (abfd, sizeof (*child->u2.vtable))); ++ if (!child->u2.vtable) ++ return false; ++ } ++ if (!h) ++ { ++ /* This *should* only be the absolute section. It could potentially ++ be that someone has defined a non-global vtable though, which ++ would be bad. It isn't worth paging in the local symbols to be ++ sure though; that case should simply be handled by the assembler. */ ++ ++ child->u2.vtable->parent = (struct elf_link_hash_entry *) -1; ++ } ++ else ++ child->u2.vtable->parent = h; ++ ++ return true; ++} ++ ++/* Called from check_relocs to record the existence of a VTENTRY reloc. */ ++ ++bool ++bfd_elf_gc_record_vtentry (bfd *abfd, asection *sec, ++ struct elf_link_hash_entry *h, ++ bfd_vma addend) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ unsigned int log_file_align = bed->s->log_file_align; ++ ++ if (!h) ++ { ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: section '%pA': corrupt VTENTRY entry"), ++ abfd, sec); ++ bfd_set_error (bfd_error_bad_value); ++ return false; ++ } ++ ++ if (!h->u2.vtable) ++ { ++ h->u2.vtable = ((struct elf_link_virtual_table_entry *) ++ bfd_zalloc (abfd, sizeof (*h->u2.vtable))); ++ if (!h->u2.vtable) ++ return false; ++ } ++ ++ if (addend >= h->u2.vtable->size) ++ { ++ size_t size, bytes, file_align; ++ bool *ptr = h->u2.vtable->used; ++ ++ /* While the symbol is undefined, we have to be prepared to handle ++ a zero size. */ ++ file_align = 1 << log_file_align; ++ if (h->root.type == bfd_link_hash_undefined) ++ size = addend + file_align; ++ else ++ { ++ size = h->size; ++ if (addend >= size) ++ { ++ /* Oops! We've got a reference past the defined end of ++ the table. This is probably a bug -- shall we warn? */ ++ size = addend + file_align; ++ } ++ } ++ size = (size + file_align - 1) & -file_align; ++ ++ /* Allocate one extra entry for use as a "done" flag for the ++ consolidation pass. */ ++ bytes = ((size >> log_file_align) + 1) * sizeof (bool); ++ ++ if (ptr) ++ { ++ ptr = (bool *) bfd_realloc (ptr - 1, bytes); ++ ++ if (ptr != NULL) ++ { ++ size_t oldbytes; ++ ++ oldbytes = (((h->u2.vtable->size >> log_file_align) + 1) ++ * sizeof (bool)); ++ memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes); ++ } ++ } ++ else ++ ptr = (bool *) bfd_zmalloc (bytes); ++ ++ if (ptr == NULL) ++ return false; ++ ++ /* And arrange for that done flag to be at index -1. */ ++ h->u2.vtable->used = ptr + 1; ++ h->u2.vtable->size = size; ++ } ++ ++ h->u2.vtable->used[addend >> log_file_align] = true; ++ ++ return true; ++} ++ ++/* Map an ELF section header flag to its corresponding string. */ ++typedef struct ++{ ++ char *flag_name; ++ flagword flag_value; ++} elf_flags_to_name_table; ++ ++static const elf_flags_to_name_table elf_flags_to_names [] = ++{ ++ { "SHF_WRITE", SHF_WRITE }, ++ { "SHF_ALLOC", SHF_ALLOC }, ++ { "SHF_EXECINSTR", SHF_EXECINSTR }, ++ { "SHF_MERGE", SHF_MERGE }, ++ { "SHF_STRINGS", SHF_STRINGS }, ++ { "SHF_INFO_LINK", SHF_INFO_LINK}, ++ { "SHF_LINK_ORDER", SHF_LINK_ORDER}, ++ { "SHF_OS_NONCONFORMING", SHF_OS_NONCONFORMING}, ++ { "SHF_GROUP", SHF_GROUP }, ++ { "SHF_TLS", SHF_TLS }, ++ { "SHF_MASKOS", SHF_MASKOS }, ++ { "SHF_EXCLUDE", SHF_EXCLUDE }, ++}; ++ ++/* Returns TRUE if the section is to be included, otherwise FALSE. */ ++bool ++bfd_elf_lookup_section_flags (struct bfd_link_info *info, ++ struct flag_info *flaginfo, ++ asection *section) ++{ ++ const bfd_vma sh_flags = elf_section_flags (section); ++ ++ if (!flaginfo->flags_initialized) ++ { ++ bfd *obfd = info->output_bfd; ++ const struct elf_backend_data *bed = get_elf_backend_data (obfd); ++ struct flag_info_list *tf = flaginfo->flag_list; ++ int with_hex = 0; ++ int without_hex = 0; ++ ++ for (tf = flaginfo->flag_list; tf != NULL; tf = tf->next) ++ { ++ unsigned i; ++ flagword (*lookup) (char *); ++ ++ lookup = bed->elf_backend_lookup_section_flags_hook; ++ if (lookup != NULL) ++ { ++ flagword hexval = (*lookup) ((char *) tf->name); ++ ++ if (hexval != 0) ++ { ++ if (tf->with == with_flags) ++ with_hex |= hexval; ++ else if (tf->with == without_flags) ++ without_hex |= hexval; ++ tf->valid = true; ++ continue; ++ } ++ } ++ for (i = 0; i < ARRAY_SIZE (elf_flags_to_names); ++i) ++ { ++ if (strcmp (tf->name, elf_flags_to_names[i].flag_name) == 0) ++ { ++ if (tf->with == with_flags) ++ with_hex |= elf_flags_to_names[i].flag_value; ++ else if (tf->with == without_flags) ++ without_hex |= elf_flags_to_names[i].flag_value; ++ tf->valid = true; ++ break; ++ } ++ } ++ if (!tf->valid) ++ { ++ info->callbacks->einfo ++ (_("unrecognized INPUT_SECTION_FLAG %s\n"), tf->name); ++ return false; ++ } ++ } ++ flaginfo->flags_initialized = true; ++ flaginfo->only_with_flags |= with_hex; ++ flaginfo->not_with_flags |= without_hex; ++ } ++ ++ if ((flaginfo->only_with_flags & sh_flags) != flaginfo->only_with_flags) ++ return false; ++ ++ if ((flaginfo->not_with_flags & sh_flags) != 0) ++ return false; ++ ++ return true; ++} ++ ++struct alloc_got_off_arg { ++ bfd_vma gotoff; ++ struct bfd_link_info *info; ++}; ++ ++/* We need a special top-level link routine to convert got reference counts ++ to real got offsets. */ ++ ++static bool ++elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) ++{ ++ struct alloc_got_off_arg *gofarg = (struct alloc_got_off_arg *) arg; ++ bfd *obfd = gofarg->info->output_bfd; ++ const struct elf_backend_data *bed = get_elf_backend_data (obfd); ++ ++ if (h->got.refcount > 0) ++ { ++ h->got.offset = gofarg->gotoff; ++ gofarg->gotoff += bed->got_elt_size (obfd, gofarg->info, h, NULL, 0); ++ } ++ else ++ h->got.offset = (bfd_vma) -1; ++ ++ return true; ++} ++ ++/* And an accompanying bit to work out final got entry offsets once ++ we're done. Should be called from final_link. */ ++ ++bool ++bfd_elf_gc_common_finalize_got_offsets (bfd *abfd, ++ struct bfd_link_info *info) ++{ ++ bfd *i; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ bfd_vma gotoff; ++ struct alloc_got_off_arg gofarg; ++ ++ BFD_ASSERT (abfd == info->output_bfd); ++ ++ if (! is_elf_hash_table (info->hash)) ++ return false; ++ ++ /* The GOT offset is relative to the .got section, but the GOT header is ++ put into the .got.plt section, if the backend uses it. */ ++ if (bed->want_got_plt) ++ gotoff = 0; ++ else ++ gotoff = bed->got_header_size; ++ ++ /* Do the local .got entries first. */ ++ for (i = info->input_bfds; i; i = i->link.next) ++ { ++ bfd_signed_vma *local_got; ++ size_t j, locsymcount; ++ Elf_Internal_Shdr *symtab_hdr; ++ ++ if (bfd_get_flavour (i) != bfd_target_elf_flavour) ++ continue; ++ ++ local_got = elf_local_got_refcounts (i); ++ if (!local_got) ++ continue; ++ ++ symtab_hdr = &elf_tdata (i)->symtab_hdr; ++ if (elf_bad_symtab (i)) ++ locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; ++ else ++ locsymcount = symtab_hdr->sh_info; ++ ++ for (j = 0; j < locsymcount; ++j) ++ { ++ if (local_got[j] > 0) ++ { ++ local_got[j] = gotoff; ++ gotoff += bed->got_elt_size (abfd, info, NULL, i, j); ++ } ++ else ++ local_got[j] = (bfd_vma) -1; ++ } ++ } ++ ++ /* Then the global .got entries. .plt refcounts are handled by ++ adjust_dynamic_symbol */ ++ gofarg.gotoff = gotoff; ++ gofarg.info = info; ++ elf_link_hash_traverse (elf_hash_table (info), ++ elf_gc_allocate_got_offsets, ++ &gofarg); ++ return true; ++} ++ ++/* Many folk need no more in the way of final link than this, once ++ got entry reference counting is enabled. */ ++ ++bool ++bfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info) ++{ ++ if (!bfd_elf_gc_common_finalize_got_offsets (abfd, info)) ++ return false; ++ ++ /* Invoke the regular ELF backend linker to do all the work. */ ++ return bfd_elf_final_link (abfd, info); ++} ++ ++bool ++bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) ++{ ++ struct elf_reloc_cookie *rcookie = (struct elf_reloc_cookie *) cookie; ++ ++ if (rcookie->bad_symtab) ++ rcookie->rel = rcookie->rels; ++ ++ for (; rcookie->rel < rcookie->relend; rcookie->rel++) ++ { ++ unsigned long r_symndx; ++ ++ if (! rcookie->bad_symtab) ++ if (rcookie->rel->r_offset > offset) ++ return false; ++ if (rcookie->rel->r_offset != offset) ++ continue; ++ ++ r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift; ++ if (r_symndx == STN_UNDEF) ++ return true; ++ ++ if (r_symndx >= rcookie->locsymcount ++ || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL) ++ { ++ struct elf_link_hash_entry *h; ++ ++ h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff]; ++ ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && (h->root.u.def.section->owner != rcookie->abfd ++ || h->root.u.def.section->kept_section != NULL ++ || discarded_section (h->root.u.def.section))) ++ return true; ++ } ++ else ++ { ++ /* It's not a relocation against a global symbol, ++ but it could be a relocation against a local ++ symbol for a discarded section. */ ++ asection *isec; ++ Elf_Internal_Sym *isym; ++ ++ /* Need to: get the symbol; get the section. */ ++ isym = &rcookie->locsyms[r_symndx]; ++ isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx); ++ if (isec != NULL ++ && (isec->kept_section != NULL ++ || discarded_section (isec))) ++ return true; ++ } ++ return false; ++ } ++ return false; ++} ++ ++/* Discard unneeded references to discarded sections. ++ Returns -1 on error, 1 if any section's size was changed, 0 if ++ nothing changed. This function assumes that the relocations are in ++ sorted order, which is true for all known assemblers. */ ++ ++int ++bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) ++{ ++ struct elf_reloc_cookie cookie; ++ asection *o; ++ bfd *abfd; ++ int changed = 0; ++ ++ if (info->traditional_format ++ || !is_elf_hash_table (info->hash)) ++ return 0; ++ ++ o = bfd_get_section_by_name (output_bfd, ".stab"); ++ if (o != NULL) ++ { ++ asection *i; ++ ++ for (i = o->map_head.s; i != NULL; i = i->map_head.s) ++ { ++ if (i->size == 0 ++ || i->reloc_count == 0 ++ || i->sec_info_type != SEC_INFO_TYPE_STABS) ++ continue; ++ ++ abfd = i->owner; ++ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) ++ continue; ++ ++ if (!init_reloc_cookie_for_section (&cookie, info, i)) ++ return -1; ++ ++ if (_bfd_discard_section_stabs (abfd, i, ++ elf_section_data (i)->sec_info, ++ bfd_elf_reloc_symbol_deleted_p, ++ &cookie)) ++ changed = 1; ++ ++ fini_reloc_cookie_for_section (&cookie, i); ++ } ++ } ++ ++ o = NULL; ++ if (info->eh_frame_hdr_type != COMPACT_EH_HDR) ++ o = bfd_get_section_by_name (output_bfd, ".eh_frame"); ++ if (o != NULL) ++ { ++ asection *i; ++ int eh_changed = 0; ++ unsigned int eh_alignment; /* Octets. */ ++ ++ for (i = o->map_head.s; i != NULL; i = i->map_head.s) ++ { ++ if (i->size == 0) ++ continue; ++ ++ abfd = i->owner; ++ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) ++ continue; ++ ++ if (!init_reloc_cookie_for_section (&cookie, info, i)) ++ return -1; ++ ++ _bfd_elf_parse_eh_frame (abfd, info, i, &cookie); ++ if (_bfd_elf_discard_section_eh_frame (abfd, info, i, ++ bfd_elf_reloc_symbol_deleted_p, ++ &cookie)) ++ { ++ eh_changed = 1; ++ if (i->size != i->rawsize) ++ changed = 1; ++ } ++ ++ fini_reloc_cookie_for_section (&cookie, i); ++ } ++ ++ eh_alignment = ((1 << o->alignment_power) ++ * bfd_octets_per_byte (output_bfd, o)); ++ /* Skip over zero terminator, and prevent empty sections from ++ adding alignment padding at the end. */ ++ for (i = o->map_tail.s; i != NULL; i = i->map_tail.s) ++ if (i->size == 0) ++ i->flags |= SEC_EXCLUDE; ++ else if (i->size > 4) ++ break; ++ /* The last non-empty eh_frame section doesn't need padding. */ ++ if (i != NULL) ++ i = i->map_tail.s; ++ /* Any prior sections must pad the last FDE out to the output ++ section alignment. Otherwise we might have zero padding ++ between sections, which would be seen as a terminator. */ ++ for (; i != NULL; i = i->map_tail.s) ++ if (i->size == 4) ++ /* All but the last zero terminator should have been removed. */ ++ BFD_FAIL (); ++ else ++ { ++ bfd_size_type size ++ = (i->size + eh_alignment - 1) & -eh_alignment; ++ if (i->size != size) ++ { ++ i->size = size; ++ changed = 1; ++ eh_changed = 1; ++ } ++ } ++ if (eh_changed) ++ elf_link_hash_traverse (elf_hash_table (info), ++ _bfd_elf_adjust_eh_frame_global_symbol, NULL); ++ } ++ ++ o = bfd_get_section_by_name (output_bfd, ".sframe"); ++ if (o != NULL) ++ { ++ asection *i; ++ ++ for (i = o->map_head.s; i != NULL; i = i->map_head.s) ++ { ++ if (i->size == 0) ++ continue; ++ ++ abfd = i->owner; ++ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) ++ continue; ++ ++ if (!init_reloc_cookie_for_section (&cookie, info, i)) ++ return -1; ++ ++ if (_bfd_elf_parse_sframe (abfd, info, i, &cookie)) ++ { ++ if (_bfd_elf_discard_section_sframe (i, ++ bfd_elf_reloc_symbol_deleted_p, ++ &cookie)) ++ { ++ if (i->size != i->rawsize) ++ changed = 1; ++ } ++ } ++ fini_reloc_cookie_for_section (&cookie, i); ++ } ++ /* Update the reference to the output .sframe section. Used to ++ determine later if PT_GNU_SFRAME segment is to be generated. */ ++ if (!_bfd_elf_set_section_sframe (output_bfd, info)) ++ return -1; ++ } ++ ++ for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next) ++ { ++ const struct elf_backend_data *bed; ++ asection *s; ++ ++ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) ++ continue; ++ s = abfd->sections; ++ if (s == NULL || s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ continue; ++ ++ bed = get_elf_backend_data (abfd); ++ ++ if (bed->elf_backend_discard_info != NULL) ++ { ++ if (!init_reloc_cookie (&cookie, info, abfd)) ++ return -1; ++ ++ if ((*bed->elf_backend_discard_info) (abfd, &cookie, info)) ++ changed = 1; ++ ++ fini_reloc_cookie (&cookie, abfd); ++ } ++ } ++ ++ if (info->eh_frame_hdr_type == COMPACT_EH_HDR) ++ _bfd_elf_end_eh_frame_parsing (info); ++ ++ if (info->eh_frame_hdr_type ++ && !bfd_link_relocatable (info) ++ && _bfd_elf_discard_section_eh_frame_hdr (info)) ++ changed = 1; ++ ++ return changed; ++} ++ ++bool ++_bfd_elf_section_already_linked (bfd *abfd, ++ asection *sec, ++ struct bfd_link_info *info) ++{ ++ flagword flags; ++ const char *name, *key; ++ struct bfd_section_already_linked *l; ++ struct bfd_section_already_linked_hash_entry *already_linked_list; ++ ++ if (sec->output_section == bfd_abs_section_ptr) ++ return false; ++ ++ flags = sec->flags; ++ ++ /* Return if it isn't a linkonce section. A comdat group section ++ also has SEC_LINK_ONCE set. */ ++ if ((flags & SEC_LINK_ONCE) == 0) ++ return false; ++ ++ /* Don't put group member sections on our list of already linked ++ sections. They are handled as a group via their group section. */ ++ if (elf_sec_group (sec) != NULL) ++ return false; ++ ++ /* For a SHT_GROUP section, use the group signature as the key. */ ++ name = sec->name; ++ if ((flags & SEC_GROUP) != 0 ++ && elf_next_in_group (sec) != NULL ++ && elf_group_name (elf_next_in_group (sec)) != NULL) ++ key = elf_group_name (elf_next_in_group (sec)); ++ else ++ { ++ /* Otherwise we should have a .gnu.linkonce.. section. */ ++ if (startswith (name, ".gnu.linkonce.") ++ && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL) ++ key++; ++ else ++ /* Must be a user linkonce section that doesn't follow gcc's ++ naming convention. In this case we won't be matching ++ single member groups. */ ++ key = name; ++ } ++ ++ already_linked_list = bfd_section_already_linked_table_lookup (key); ++ ++ for (l = already_linked_list->entry; l != NULL; l = l->next) ++ { ++ /* We may have 2 different types of sections on the list: group ++ sections with a signature of ( is some string), ++ and linkonce sections named .gnu.linkonce... ++ Match like sections. LTO plugin sections are an exception. ++ They are always named .gnu.linkonce.t. and match either ++ type of section. */ ++ if (((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP) ++ && ((flags & SEC_GROUP) != 0 ++ || strcmp (name, l->sec->name) == 0)) ++ || (l->sec->owner->flags & BFD_PLUGIN) != 0 ++ || (sec->owner->flags & BFD_PLUGIN) != 0) ++ { ++ /* The section has already been linked. See if we should ++ issue a warning. */ ++ if (!_bfd_handle_already_linked (sec, l, info)) ++ return false; ++ ++ if (flags & SEC_GROUP) ++ { ++ asection *first = elf_next_in_group (sec); ++ asection *s = first; ++ ++ while (s != NULL) ++ { ++ s->output_section = bfd_abs_section_ptr; ++ /* Record which group discards it. */ ++ s->kept_section = l->sec; ++ s = elf_next_in_group (s); ++ /* These lists are circular. */ ++ if (s == first) ++ break; ++ } ++ } ++ ++ return true; ++ } ++ } ++ ++ /* A single member comdat group section may be discarded by a ++ linkonce section and vice versa. */ ++ if ((flags & SEC_GROUP) != 0) ++ { ++ asection *first = elf_next_in_group (sec); ++ ++ if (first != NULL && elf_next_in_group (first) == first) ++ /* Check this single member group against linkonce sections. */ ++ for (l = already_linked_list->entry; l != NULL; l = l->next) ++ if ((l->sec->flags & SEC_GROUP) == 0 ++ && bfd_elf_match_symbols_in_sections (l->sec, first, info)) ++ { ++ first->output_section = bfd_abs_section_ptr; ++ first->kept_section = l->sec; ++ sec->output_section = bfd_abs_section_ptr; ++ break; ++ } ++ } ++ else ++ /* Check this linkonce section against single member groups. */ ++ for (l = already_linked_list->entry; l != NULL; l = l->next) ++ if (l->sec->flags & SEC_GROUP) ++ { ++ asection *first = elf_next_in_group (l->sec); ++ ++ if (first != NULL ++ && elf_next_in_group (first) == first ++ && bfd_elf_match_symbols_in_sections (first, sec, info)) ++ { ++ sec->output_section = bfd_abs_section_ptr; ++ sec->kept_section = first; ++ break; ++ } ++ } ++ ++ /* Do not complain on unresolved relocations in `.gnu.linkonce.r.F' ++ referencing its discarded `.gnu.linkonce.t.F' counterpart - g++-3.4 ++ specific as g++-4.x is using COMDAT groups (without the `.gnu.linkonce' ++ prefix) instead. `.gnu.linkonce.r.*' were the `.rodata' part of its ++ matching `.gnu.linkonce.t.*'. If `.gnu.linkonce.r.F' is not discarded ++ but its `.gnu.linkonce.t.F' is discarded means we chose one-only ++ `.gnu.linkonce.t.F' section from a different bfd not requiring any ++ `.gnu.linkonce.r.F'. Thus `.gnu.linkonce.r.F' should be discarded. ++ The reverse order cannot happen as there is never a bfd with only the ++ `.gnu.linkonce.r.F' section. The order of sections in a bfd does not ++ matter as here were are looking only for cross-bfd sections. */ ++ ++ if ((flags & SEC_GROUP) == 0 && startswith (name, ".gnu.linkonce.r.")) ++ for (l = already_linked_list->entry; l != NULL; l = l->next) ++ if ((l->sec->flags & SEC_GROUP) == 0 ++ && startswith (l->sec->name, ".gnu.linkonce.t.")) ++ { ++ if (abfd != l->sec->owner) ++ sec->output_section = bfd_abs_section_ptr; ++ break; ++ } ++ ++ /* This is the first section with this name. Record it. */ ++ if (!bfd_section_already_linked_table_insert (already_linked_list, sec)) ++ info->callbacks->einfo (_("%F%P: already_linked_table: %E\n")); ++ return sec->output_section == bfd_abs_section_ptr; ++} ++ ++bool ++_bfd_elf_common_definition (Elf_Internal_Sym *sym) ++{ ++ return sym->st_shndx == SHN_COMMON; ++} ++ ++unsigned int ++_bfd_elf_common_section_index (asection *sec ATTRIBUTE_UNUSED) ++{ ++ return SHN_COMMON; ++} ++ ++asection * ++_bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED) ++{ ++ return bfd_com_section_ptr; ++} ++ ++bfd_vma ++_bfd_elf_default_got_elt_size (bfd *abfd, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED, ++ bfd *ibfd ATTRIBUTE_UNUSED, ++ unsigned long symndx ATTRIBUTE_UNUSED) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ return bed->s->arch_size / 8; ++} ++ ++/* Routines to support the creation of dynamic relocs. */ ++ ++/* Returns the name of the dynamic reloc section associated with SEC. */ ++ ++static const char * ++get_dynamic_reloc_section_name (bfd * abfd, ++ asection * sec, ++ bool is_rela) ++{ ++ char *name; ++ const char *old_name = bfd_section_name (sec); ++ const char *prefix = is_rela ? ".rela" : ".rel"; ++ ++ if (old_name == NULL) ++ return NULL; ++ ++ name = bfd_alloc (abfd, strlen (prefix) + strlen (old_name) + 1); ++ sprintf (name, "%s%s", prefix, old_name); ++ ++ return name; ++} ++ ++/* Returns the dynamic reloc section associated with SEC. ++ If necessary compute the name of the dynamic reloc section based ++ on SEC's name (looked up in ABFD's string table) and the setting ++ of IS_RELA. */ ++ ++asection * ++_bfd_elf_get_dynamic_reloc_section (bfd *abfd, ++ asection *sec, ++ bool is_rela) ++{ ++ asection *reloc_sec = elf_section_data (sec)->sreloc; ++ ++ if (reloc_sec == NULL) ++ { ++ const char *name = get_dynamic_reloc_section_name (abfd, sec, is_rela); ++ ++ if (name != NULL) ++ { ++ reloc_sec = bfd_get_linker_section (abfd, name); ++ ++ if (reloc_sec != NULL) ++ elf_section_data (sec)->sreloc = reloc_sec; ++ } ++ } ++ ++ return reloc_sec; ++} ++ ++/* Returns the dynamic reloc section associated with SEC. If the ++ section does not exist it is created and attached to the DYNOBJ ++ bfd and stored in the SRELOC field of SEC's elf_section_data ++ structure. ++ ++ ALIGNMENT is the alignment for the newly created section and ++ IS_RELA defines whether the name should be .rela. ++ or .rel.. The section name is looked up in the ++ string table associated with ABFD. */ ++ ++asection * ++_bfd_elf_make_dynamic_reloc_section (asection *sec, ++ bfd *dynobj, ++ unsigned int alignment, ++ bfd *abfd, ++ bool is_rela) ++{ ++ asection * reloc_sec = elf_section_data (sec)->sreloc; ++ ++ if (reloc_sec == NULL) ++ { ++ const char * name = get_dynamic_reloc_section_name (abfd, sec, is_rela); ++ ++ if (name == NULL) ++ return NULL; ++ ++ reloc_sec = bfd_get_linker_section (dynobj, name); ++ ++ if (reloc_sec == NULL) ++ { ++ flagword flags = (SEC_HAS_CONTENTS | SEC_READONLY ++ | SEC_IN_MEMORY | SEC_LINKER_CREATED); ++ if ((sec->flags & SEC_ALLOC) != 0) ++ flags |= SEC_ALLOC | SEC_LOAD; ++ ++ reloc_sec = bfd_make_section_anyway_with_flags (dynobj, name, flags); ++ if (reloc_sec != NULL) ++ { ++ /* _bfd_elf_get_sec_type_attr chooses a section type by ++ name. Override as it may be wrong, eg. for a user ++ section named "auto" we'll get ".relauto" which is ++ seen to be a .rela section. */ ++ elf_section_type (reloc_sec) = is_rela ? SHT_RELA : SHT_REL; ++ if (!bfd_set_section_alignment (reloc_sec, alignment)) ++ reloc_sec = NULL; ++ } ++ } ++ ++ elf_section_data (sec)->sreloc = reloc_sec; ++ } ++ ++ return reloc_sec; ++} ++ ++/* Copy the ELF symbol type and other attributes for a linker script ++ assignment from HSRC to HDEST. Generally this should be treated as ++ if we found a strong non-dynamic definition for HDEST (except that ++ ld ignores multiple definition errors). */ ++void ++_bfd_elf_copy_link_hash_symbol_type (bfd *abfd, ++ struct bfd_link_hash_entry *hdest, ++ struct bfd_link_hash_entry *hsrc) ++{ ++ struct elf_link_hash_entry *ehdest = (struct elf_link_hash_entry *) hdest; ++ struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *) hsrc; ++ Elf_Internal_Sym isym; ++ ++ ehdest->type = ehsrc->type; ++ ehdest->target_internal = ehsrc->target_internal; ++ ++ isym.st_other = ehsrc->other; ++ elf_merge_st_other (abfd, ehdest, isym.st_other, NULL, true, false); ++} ++ ++/* Append a RELA relocation REL to section S in BFD. */ ++ ++void ++elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ bfd_byte *loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela); ++ BFD_ASSERT (loc + bed->s->sizeof_rela <= s->contents + s->size); ++ bed->s->swap_reloca_out (abfd, rel, loc); ++} ++ ++/* Append a REL relocation REL to section S in BFD. */ ++ ++void ++elf_append_rel (bfd *abfd, asection *s, Elf_Internal_Rela *rel) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ bfd_byte *loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rel); ++ BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size); ++ bed->s->swap_reloc_out (abfd, rel, loc); ++} ++ ++/* Define __start, __stop, .startof. or .sizeof. symbol. */ ++ ++struct bfd_link_hash_entry * ++bfd_elf_define_start_stop (struct bfd_link_info *info, ++ const char *symbol, asection *sec) ++{ ++ struct elf_link_hash_entry *h; ++ ++ h = elf_link_hash_lookup (elf_hash_table (info), symbol, ++ false, false, true); ++ /* NB: Common symbols will be turned into definition later. */ ++ if (h != NULL ++ && !h->root.ldscript_def ++ && (h->root.type == bfd_link_hash_undefined ++ || h->root.type == bfd_link_hash_undefweak ++ || ((h->ref_regular || h->def_dynamic) ++ && !h->def_regular ++ && h->root.type != bfd_link_hash_common))) ++ { ++ bool was_dynamic = h->ref_dynamic || h->def_dynamic; ++ h->verinfo.verdef = NULL; ++ h->root.type = bfd_link_hash_defined; ++ h->root.u.def.section = sec; ++ h->root.u.def.value = 0; ++ h->def_regular = 1; ++ h->def_dynamic = 0; ++ h->start_stop = 1; ++ h->u2.start_stop_section = sec; ++ if (symbol[0] == '.') ++ { ++ /* .startof. and .sizeof. symbols are local. */ ++ const struct elf_backend_data *bed; ++ bed = get_elf_backend_data (info->output_bfd); ++ (*bed->elf_backend_hide_symbol) (info, h, true); ++ } ++ else ++ { ++ if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) ++ h->other = ((h->other & ~ELF_ST_VISIBILITY (-1)) ++ | info->start_stop_visibility); ++ if (was_dynamic) ++ bfd_elf_link_record_dynamic_symbol (info, h); ++ } ++ return &h->root; ++ } ++ return NULL; ++} ++ ++/* Find dynamic relocs for H that apply to read-only sections. */ ++ ++asection * ++_bfd_elf_readonly_dynrelocs (struct elf_link_hash_entry *h) ++{ ++ struct elf_dyn_relocs *p; ++ ++ for (p = h->dyn_relocs; p != NULL; p = p->next) ++ { ++ asection *s = p->sec->output_section; ++ ++ if (s != NULL && (s->flags & SEC_READONLY) != 0) ++ return p->sec; ++ } ++ return NULL; ++} ++ ++/* Set DF_TEXTREL if we find any dynamic relocs that apply to ++ read-only sections. */ ++ ++bool ++_bfd_elf_maybe_set_textrel (struct elf_link_hash_entry *h, void *inf) ++{ ++ asection *sec; ++ ++ if (h->root.type == bfd_link_hash_indirect) ++ return true; ++ ++ sec = _bfd_elf_readonly_dynrelocs (h); ++ if (sec != NULL) ++ { ++ struct bfd_link_info *info = (struct bfd_link_info *) inf; ++ ++ info->flags |= DF_TEXTREL; ++ /* xgettext:c-format */ ++ info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' " ++ "in read-only section `%pA'\n"), ++ sec->owner, h->root.root.string, sec); ++ ++ if (bfd_link_textrel_check (info)) ++ /* xgettext:c-format */ ++ info->callbacks->einfo (_("%P: %pB: warning: relocation against `%s' " ++ "in read-only section `%pA'\n"), ++ sec->owner, h->root.root.string, sec); ++ ++ /* Not an error, just cut short the traversal. */ ++ return false; ++ } ++ return true; ++} ++ ++/* Add dynamic tags. */ ++ ++bool ++_bfd_elf_add_dynamic_tags (bfd *output_bfd, struct bfd_link_info *info, ++ bool need_dynamic_reloc) ++{ ++ struct elf_link_hash_table *htab = elf_hash_table (info); ++ ++ if (htab->dynamic_sections_created) ++ { ++ /* Add some entries to the .dynamic section. We fill in the ++ values later, in finish_dynamic_sections, but we must add ++ the entries now so that we get the correct size for the ++ .dynamic section. The DT_DEBUG entry is filled in by the ++ dynamic linker and used by the debugger. */ ++#define add_dynamic_entry(TAG, VAL) \ ++ _bfd_elf_add_dynamic_entry (info, TAG, VAL) ++ ++ const struct elf_backend_data *bed ++ = get_elf_backend_data (output_bfd); ++ ++ if (bfd_link_executable (info)) ++ { ++ if (!add_dynamic_entry (DT_DEBUG, 0)) ++ return false; ++ } ++ ++ if (htab->dt_pltgot_required || htab->splt->size != 0) ++ { ++ /* DT_PLTGOT is used by prelink even if there is no PLT ++ relocation. */ ++ if (!add_dynamic_entry (DT_PLTGOT, 0)) ++ return false; ++ } ++ ++ if (htab->dt_jmprel_required || htab->srelplt->size != 0) ++ { ++ if (!add_dynamic_entry (DT_PLTRELSZ, 0) ++ || !add_dynamic_entry (DT_PLTREL, ++ (bed->rela_plts_and_copies_p ++ ? DT_RELA : DT_REL)) ++ || !add_dynamic_entry (DT_JMPREL, 0)) ++ return false; ++ } ++ ++ if (htab->tlsdesc_plt ++ && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) ++ || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) ++ return false; ++ ++ if (need_dynamic_reloc) ++ { ++ if (bed->rela_plts_and_copies_p) ++ { ++ if (!add_dynamic_entry (DT_RELA, 0) ++ || !add_dynamic_entry (DT_RELASZ, 0) ++ || !add_dynamic_entry (DT_RELAENT, ++ bed->s->sizeof_rela)) ++ return false; ++ } ++ else ++ { ++ if (!add_dynamic_entry (DT_REL, 0) ++ || !add_dynamic_entry (DT_RELSZ, 0) ++ || !add_dynamic_entry (DT_RELENT, ++ bed->s->sizeof_rel)) ++ return false; ++ } ++ ++ /* If any dynamic relocs apply to a read-only section, ++ then we need a DT_TEXTREL entry. */ ++ if ((info->flags & DF_TEXTREL) == 0) ++ elf_link_hash_traverse (htab, _bfd_elf_maybe_set_textrel, ++ info); ++ ++ if ((info->flags & DF_TEXTREL) != 0) ++ { ++ if (htab->ifunc_resolvers) ++ info->callbacks->einfo ++ (_("%P: warning: GNU indirect functions with DT_TEXTREL " ++ "may result in a segfault at runtime; recompile with %s\n"), ++ bfd_link_dll (info) ? "-fPIC" : "-fPIE"); ++ ++ if (!add_dynamic_entry (DT_TEXTREL, 0)) ++ return false; ++ } ++ } ++ } ++#undef add_dynamic_entry ++ ++ return true; ++} +diff -rupN binutils.orig/include/bfdlink.h binutils-2.41/include/bfdlink.h +--- binutils.orig/include/bfdlink.h 2023-10-19 12:11:47.238940495 +0100 ++++ binutils-2.41/include/bfdlink.h 2023-10-19 12:11:56.515949625 +0100 +@@ -484,26 +484,49 @@ struct bfd_link_info + --dynamic-list command line options. */ + unsigned int dynamic: 1; + +- /* TRUE if PT_GNU_STACK segment should be created with PF_R|PF_W|PF_X +- flags. */ ++ /* Set if the "-z execstack" option has been used to request that a ++ PT_GNU_STACK segment should be created with PF_R, PF_W and PF_X ++ flags set. ++ ++ Note - if performing a relocatable link then a .note.GNU-stack ++ section will be created instead, if one does not exist already. ++ The section will have the SHF_EXECINSTR flag bit set. */ + unsigned int execstack: 1; + +- /* TRUE if PT_GNU_STACK segment should be created with PF_R|PF_W +- flags. */ ++ /* Set if the "-z noexecstack" option has been used to request that a ++ PT_GNU_STACK segment should be created with PF_R and PF_W flags. Or ++ a non-executable .note.GNU-stack section for relocateable links. ++ ++ Note - this flag is not quite orthogonal to execstack, since both ++ of these flags can be 0. In this case a stack segment can still ++ be created, but it will only have the PF_X flag bit set if one or ++ more of the input files contains a .note.GNU-stack section with the ++ SHF_EXECINSTR flag bit set, or if the default behaviour for the ++ architecture is to create executable stacks. ++ ++ The execstack and noexecstack flags should never both be 1. */ + unsigned int noexecstack: 1; + + /* Tri-state variable: + 0 => do not warn when creating an executable stack. +- 1 => always warn when creating an executable stack. +- >1 => warn when creating an executable stack if execstack is 0. */ ++ 1 => always warn when creating an executable stack (for any reason). ++ 2 => only warn when an executable stack has been requested an object ++ file and execstack is 0 or noexecstack is 1. ++ 3 => not used. */ + unsigned int warn_execstack: 2; ++ /* TRUE if a warning generated because of warn_execstack should be instead ++ be treated as an error. */ ++ unsigned int error_execstack: 1; + +- /* TRUE if warnings should not be generated for TLS segments with eXecute ++ /* TRUE if warnings should NOT be generated for TLS segments with eXecute + permission or LOAD segments with RWX permissions. */ + unsigned int no_warn_rwx_segments: 1; + /* TRUE if the user gave either --warn-rwx-segments or +- --no-warn-rwx-segments. */ ++ --no-warn-rwx-segments on the linker command line. */ + unsigned int user_warn_rwx_segments: 1; ++ /* TRUE if warnings generated when no_warn_rwx_segements is 0 should ++ instead be treated as errors. */ ++ unsigned int warn_is_error_for_rwx_segments: 1; + + /* TRUE if the stack can be made executable because of the absence of a + .note.GNU-stack section in an input file. Note - even if this field +diff -rupN binutils.orig/ld/NEWS binutils-2.41/ld/NEWS +--- binutils.orig/ld/NEWS 2023-10-19 12:11:47.274940530 +0100 ++++ binutils-2.41/ld/NEWS 2023-10-19 12:11:56.515949625 +0100 +@@ -1,5 +1,14 @@ + -*- text -*- + ++* Added --warn-execstack-objects to warn about executable stacks only when an ++ input object file requests one. Also added --error-execstack and ++ --error-rxw-segments options to convert warnings about executable stacks and ++ segments into errors. ++ ++ Also added --enable-error-execstack=[yes|no] and ++ --enable-error-rwx-segments=[yes|no] configure options to set the default for ++ converting warnings into errors. ++ + Changes in 2.41: + + * The linker now accepts a command line option of --remap-inputs +diff -rupN binutils.orig/ld/NEWS.orig binutils-2.41/ld/NEWS.orig +--- binutils.orig/ld/NEWS.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/NEWS.orig 2023-07-03 00:00:00.000000000 +0100 +@@ -0,0 +1,977 @@ ++-*- text -*- ++ ++Changes in 2.41: ++ ++* The linker now accepts a command line option of --remap-inputs ++ = to relace any input file that matches with ++ . In addition the option --remap-inputs-file= can be used to ++ specify a file containing any number of these remapping directives. ++ ++* The linker command line option --print-map-locals can be used to include ++ local symbols in a linker map. (ELF targets only). ++ ++* For most ELF based targets, if the --enable-linker-version option is used ++ then the version of the linker will be inserted as a string into the .comment ++ section. ++ ++* The linker script syntax has a new command for output sections: ASCIZ "string" ++ This will insert a zero-terminated string at the current location. ++ ++* Add command-line option, -z nosectionheader, to omit ELF section ++ header. ++ ++Changes in 2.40: ++ ++* The linker has a new command line option to suppress the generation of any ++ warning or error messages. This can be useful when there is a need to create ++ a known non-working binary. The option is -w or --no-warnings. ++ ++* ld now supports zstd compressed debug sections. The new option ++ --compress-debug-sections=zstd compresses debug sections with zstd. ++ ++* Add --enable-default-compressed-debug-sections-algorithm={zlib,zstd} ++ that selects the default compression algorithm ++ for --enable-compressed-debug-sections. ++ ++* Remove support for -z bndplt (MPX prefix instructions). ++ ++Changes in 2.39: ++ ++* The ELF linker will now generate a warning message if the stack is made ++ executable. By default this warning is not issued if the user has ++ specifically requested an executable stack via the "-z execstack" ++ command line option, but the warning can be forced via the new ++ "--warn-execstack" option. Alternatively all warnings about creating ++ an executable stack can be suppressed via the "--no-warn-execstack" ++ option. ++ ++ In addition the ELF linker will also warn if it creates a memory resident ++ segment with all three of the Read, Write and eXecute permissions set, or ++ if it creates a thread local data segment with the eXecute permission set. ++ These warnings can be disabled via --no-warn-rwx-segments option and ++ re-enabled via the --warn-rwx-segments option. ++ ++ New configure options can also control these new features: ++ ++ --enable-warn-execstack=no ++ will disable the warnings about creating an executable stack. ++ ++ --enable-warn-execstack=yes ++ will make --warn-execstack enabled by default. ++ ++ --enable-warn-rwx-segments=no ++ will make --no-warn-rwx-segments enabled by default. ++ ++ --enable-default-execstack=no ++ will stop the creation of an executable stack simply because an input file ++ is missing a .note.GNU-stack section, even on architectures where this ++ behaviour is the default. ++ ++* TYPE= is now supported in an output section description to set the ++ section type value. ++ ++* Remove (rudimentary) support for the x86-64 sub-architectures Intel L1OM and ++ Intel K1OM. ++ ++* The ELF linker now supports a new --package-metadata option that allows ++ embedding a JSON payload in accordance to the Package Metadata specification. ++ If support for libjansson is enabled at build time, the linker will use it to ++ validate the input. This can be enabled with --enable-jansson. ++ For more details, see: https://systemd.io/ELF_PACKAGE_METADATA/ ++ ++Changes in 2.38: ++ ++* Add -z pack-relative-relocs/-z no pack-relative-relocs to x86 ELF ++ linker to pack relative relocations in the DT_RELR section. ++ ++* Add support for the LoongArch architecture. ++ ++* Add -z indirect-extern-access/-z noindirect-extern-access to x86 ELF ++ linker to control canonical function pointers and copy relocation. ++ ++* Add --max-cache-size=SIZE to set the the maximum cache size to SIZE ++ bytes. ++ ++Changes in 2.37: ++ ++* arm-symbianelf support removed. ++ ++* Add -z report-relative-reloc to x86 ELF linker to report dynamic ++ relative relocations. ++ ++* Add -z start-stop-gc to disable special treatment of __start_*/__stop_* ++ references when --gc-sections. ++ ++* Add -Bno-symbolic to cancel -Bsymbolic and -Bsymbolic-functions. ++ ++Changes in 2.36: ++ ++* Add libdep plugin, for linking dependencies of static libraries that ++ were recorded by ar in the __.LIBDEP archive member. ++ ++* Add --error-handling-script= command line option to allow a helper ++ script to be invoked when an undefined symbol or a missing library is ++ encountered. This option can be suppressed via the configure time ++ switch: --enable-error-handling-script=no. ++ ++* Add -z lam-u48 to x86-64 ELF linker to generate LAM_U48 property. ++ ++* Add -z lam-u57 to x86-64 ELF linker to enerate LAM_U57 property. ++ ++* Add -z lam-u48-report=[none|warning|error] to report missing LAM_U48 ++ property. ++ ++* Add -z lam-u57-report=[none|warning|error] to report missing LAM_U57 ++ property. ++ ++* Add -z lam-report=[none|warning|error] to report missing LAM_U48 and ++ LAM_U57 properties. ++ ++* Add -z x86-64-{baseline|v[234]} to the x86 ELF linker to mark ++ x86-64-{baseline|v[234]} ISA level as needed. ++ ++* Add -z unique-symbol to avoid duplicated local symbol names. ++ ++* The creation of PE format DLLs now defaults to using a more secure set of DLL ++ characteristics. ++ ++* The linker now deduplicates the types in .ctf sections. The new ++ command-line option --ctf-share-types describes how to do this: ++ its default value, share-unconflicted, produces the most compact ++ output. ++ ++* The linker now omits the "variable section" from .ctf sections by ++ default, saving space. This is almost certainly what you want ++ unless you are working on a project that has its own analogue ++ of symbol tables that are not reflected in the ELF symtabs. ++ ++* Add support for the SHF_GNU_RETAIN ELF section flag. ++ This flag specifies that the section should not be garbage collected by the ++ linker. ++ ++Changes in 2.35: ++ ++* X86 NaCl target support is removed. ++ ++* Add ELF linker command-line options, --export-dynamic-symbol and ++ --export-dynamic-symbol-list, to make symbols dynamic. ++ ++* Add a configure option, --enable-textrel-check=[no|yes|warning|error], ++ to decide what ELF linker should do by default with DT_TEXTREL in an ++ executable or shared library. Default to yes for Linux/x86 targets. ++ ++* The -Map= command line option has been extended so that if ++ is a directory then /.map will be ++ created. ++ ++* Add a command-line option for ELF linker, --warn-textrel, to warn that ++ DT_TEXTREL is set in a position-independent executable or shared object. ++ ++* Add command-line options --enable-non-contiguous-regions and ++ --enable-non-contiguous-regions-warnings. ++ ++* Add command-line option --imagic for the pdp11-aout target to output format ++ IMAGIC (0411) for separate instruction and data spaces, and change the ++ default format option for pdp11-aout to be --omagic. ++ ++* Relative pathnames in INPUT() and GROUP() directives in linker scripts are ++ searched relative to the directory of the linker script before other search ++ paths. ++ ++* Add ELF linker command-line option `-z start-stop-visibility=...' to control ++ the visibility of synthetic `__start_SECNAME` and `__stop_SECNAME` symbols. ++ ++* Add command-line option --dependency-file to write a Make-style dependency ++ file listing the input files consulted by the linker, like the files written ++ by the compiler's -M -MP options. ++ ++Changes in 2.34: ++ ++* The ld check for "PHDR segment not covered by LOAD segment" is more ++ effective, catching cases that were wrongly allowed by previous versions of ++ ld. If you see this error it is likely you are linking with a bad linker ++ script or the binary you are building is not intended to be loaded by a ++ dynamic loader. In the latter case --no-dynamic-linker is appropriate. ++ ++* cr16c support removed. ++ ++* Add support for z80-elf. ++ ++* Add support for relocation of each byte or word of multibyte value to Z80 ++ targets. ++ ++* Add support for Zilog eZ80 (both ADL and Z80 mode) and Zilog Z180 CPUs. ++ ++Changes in 2.33: ++ ++* Add command-line option --no-print-map-discarded. ++ ++* The Cortex-A53 Erratum 843419 workaround now supports a choice of which ++ workaround to use. The option --fix-cortex-a53-843419 now takes an ++ optional argument --fix-cortex-a53-843419[=full|adr|adrp] which can be ++ used to force a particular workaround to be used. See --help for AArch64 ++ for more details. ++ ++* Add target handlers for AArch64 for ELF GNU program properties. ++ ++* Add support for GNU_PROPERTY_AARCH64_FEATURE_1_BTI in ELF GNU program ++ properties in the AArch64 ELF linker. ++ ++* Add support for GNU_PROPERTY_AARCH64_FEATURE_1_PAC in ELF GNU program ++ properties in the AArch64 ELF linker. ++ ++* Add -z force-bti for AArch64 to enable GNU_PROPERTY_AARCH64_FEATURE_1_BTI ++ on output while warning about missing GNU_PROPERTY_AARCH64_FEATURE_1_BTI ++ on inputs and use PLTs protected with BTI. ++ ++* Add -z pac-plt for AArch64 to pick PAC enabled PLTs. ++ ++Changes in 2.32: ++ ++* Report property change in linker map file when merging GNU properties. ++ ++* Add support for the C-SKY processor series. ++ ++* -t now doesn't report members within archives, unless -t is given twice. ++ A single -t is now more useful when generating a list of files that should be ++ packaged for a linker bug report. For example: ++ gcc hello.c -save-temps -Wl,-t | xargs realpath | sort | uniq > files ++ tar cJf test.tar.xz `cat files` ++ ++Changes in 2.31: ++ ++* Speed up direct linking with DLLs for Cygwin and Mingw targets. ++ ++* Add a configure option --enable-separate-code to decide whether ++ -z separate-code should be enabled in ELF linker by default. Default ++ to yes for Linux/x86 targets. Note that -z separate-code can increase ++ disk and memory size. ++ ++Changes in 2.30: ++ ++* Add -z separate-code to generate separate code PT_LOAD segment. ++ ++* Add "-z undefs" command-line option as the inverse of the "-z defs" option. ++ ++* Add -z globalaudit command-line option to force audit libraries to be run ++ for every dynamic object loaded by an executable - provided that the loader ++ supports this functionality. ++ ++* Tighten linker script grammar around file name specifiers to prevent the use ++ of SORT_BY_ALIGNMENT and SORT_BY_INIT_PRIORITY on filenames. These would ++ previously be accepted but had no effect. ++ ++* The EXCLUDE_FILE directive can now be placed within any SORT_* directive ++ within input section lists. ++ ++Changes in 2.29: ++ ++* Support for -z shstk in the x86 ELF linker to generate ++ GNU_PROPERTY_X86_FEATURE_1_SHSTK in ELF GNU program properties. ++ ++* Add support for GNU_PROPERTY_X86_FEATURE_1_SHSTK in ELF GNU program ++ properties in the x86 ELF linker. ++ ++* Add support for GNU_PROPERTY_X86_FEATURE_1_IBT in ELF GNU program ++ properties in the x86 ELF linker. ++ ++* Support for -z ibtplt in the x86 ELF linker to generate IBT-enabled ++ PLT. ++ ++* Support for -z ibt in the x86 ELF linker to generate IBT-enabled ++ PLT as well as GNU_PROPERTY_X86_FEATURE_1_IBT in ELF GNU program ++ properties. ++ ++* Add support for ELF SHF_GNU_MBIND and PT_GNU_MBIND_XXX. ++ ++* Add support for ELF GNU program properties. ++ ++* Add support for the Texas Instruments PRU processor. ++ ++* When configuring for arc*-*-linux* targets the default linker emulation will ++ change if --with-cpu=nps400 is used at configure time. ++ ++* Improve assignment of LMAs to orphan sections in some edge cases where a ++ mixture of both AT>LMA_REGION and AT(LMA) are used. ++ ++* Orphan sections placed after an empty section that has an AT(LMA) will now ++ take an load memory address starting from LMA. ++ ++* Section groups can now be resolved (the group deleted and the group members ++ placed like normal sections) at partial link time either using the new linker ++ option --force-group-allocation or by placing FORCE_GROUP_ALLOCATION into the ++ linker script. ++ ++Changes in 2.28: ++ ++* The EXCLUDE_FILE linker script construct can now be applied outside of the ++ section list in order for the exclusions to apply over all input sections in ++ the list. ++ ++* Add support for the RISC-V architecture. ++ ++* The command-line option --no-eh-frame-hdr can now be used in ELF based ++ linkers to disable the automatic generation of .eh_frame_hdr sections. ++ ++* Add --in-implib= to the ARM linker to enable specifying a set of ++ Secure Gateway veneers that must exist in the output import library specified ++ by --out-implib= and the address they must have. As such, ++ --in-implib is only supported in combination with --cmse-implib. ++ ++* Extended the --out-implib= option, previously restricted to x86 PE ++ targets, to any ELF based target. This allows the generation of an import ++ library for an ELF executable, which can then be used by another application ++ to link against the executable. ++ ++Changes in 2.27: ++ ++* Add a configure option --enable-relro to decide whether -z relro should ++ be enabled in ELF linker by default. Default to yes for all Linux ++ targets except FRV, HPPA, IA64 and MIPS. Note that -z relro can increase ++ disk and memory size. ++ ++* Support for -z noreloc-overflow in the x86-64 ELF linker to disable ++ relocation overflow check. ++ ++* Add -z common/-z nocommon options for ELF targets to control whether to ++ convert common symbols to the STT_COMMON type during a relocatable link. ++ ++* Support for -z nodynamic-undefined-weak in the x86 ELF linker, which ++ avoids dynamic relocations against undefined weak symbols in executable. ++ ++* The NOCROSSREFSTO command was added to the linker script language. ++ ++* Add --no-apply-dynamic-relocs to the AArch64 linker to do not apply link-time ++ values for dynamic relocations. ++ ++Changes in 2.26: ++ ++* Add --fix-stm32l4xx-629360 to the ARM linker to enable a link-time ++ workaround for a bug in the bus matrix / memory controller for some of ++ the STM32 Cortex-M4 based products (STM32L4xx) ++ ++* Add a configure option --enable-compressed-debug-sections={all,ld} to ++ decide whether DWARF debug sections should be compressed by default. ++ ++* Add support for the ARC EM/HS, and ARC600/700 architectures. ++ ++* Experimental support for linker garbage collection (--gc-sections) ++ has been enabled for COFF and PE based targets. ++ ++* New command-line option for ELF targets to compress DWARF debug ++ sections, --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]. ++ ++* New command-line option, --orphan-handling=[place|warn|error|discard], to ++ adjust how orphan sections are handled. The default is 'place' which gives ++ the current behaviour, 'warn' and 'error' issue a warning or error ++ respectively when orphan sections are found, and 'discard' will discard all ++ orphan sections. ++ ++* Add support for LLVM plugin. ++ ++* Add --print-memory-usage option to report memory blocks usage. ++ ++* Add --require-defined option, it's like --undefined except the new symbol ++ must be defined by the end of the link. ++ ++Changes in 2.25: ++ ++* PE binaries now once again contain real timestamps by default. To disable ++ the inclusion of a timestamp in a PE binary, use the --no-insert-timestamp ++ command-line option. ++ ++* Replace support for openrisc and or32 with support for or1k. ++ ++* Add support for the --build-id command-line option to COFF based targets. ++ ++* x86/x86_64 pe-coff now supports the --build-id option. ++ ++* Add support for the Andes NDS32. ++ ++Changes in 2.24: ++ ++* Add LOG2CEIL() builtin function to the linker script language ++ ++* Add support for the Texas Instruments MSP430X processor. ++ ++* Add support for Altera Nios II. ++ ++* Add support for the V850E3V5 architecture. ++ ++* Add support for the Imagination Technologies Meta processor. ++ ++* --enable-new-dtags no longer generates old dtags in addition to new dtags. ++ ++* Remove linker support for MIPS ECOFF targets. ++ ++* Add ALIGN_WITH_INPUT to the linker script language to force the alignment of ++ an output section to use the maximum alignment of all its input sections. ++ ++Changes in 2.23: ++ ++* Enable compressed debug section feature for x86/x86_64 pe-coff. ++ ++* Add support for the 64-bit ARM architecture: AArch64. ++ ++* Added SORT_NONE to the linker script language to disable section sorting. ++ ++* Add a linker-provided symbol when producing ELF output, '__ehdr_start' ++ to point to the ELF file header (and nearby program headers) in the ++ program's memory image. ++ ++* Add support for S12X processor. ++ ++* Add support for the VLE extension to the PowerPC architecture. ++ ++* Add support for the Freescale XGATE architecture. ++ ++* Add option -f FILE on AIX (for response file). ++ ++* Add support for the Renesas RL78 architecture. ++ ++* Add support for the Adapteva EPIPHANY architecture. ++ ++Changes in 2.22: ++ ++* --copy-dt-needed-entries is no longer enabled by default. Instead ++ --no-copy-dt-needed-entries is the default. ++ ++* INPUT_SECTION_FLAGS has been added to the linker script language ++ to allow selection of input sections by section header section flags. ++ ++* Add support for the Tilera TILEPro and TILE-Gx architectures. ++ ++* Added SORT_BY_INIT_PRIORITY to the linker script language to permit ++ sorting sections by numerical value of the GCC init_priority attribute ++ encoded in the section name. ++ ++Changes in 2.21: ++ ++* Linker script expression evaluation is somewhat more sane. This may ++ break scripts that depend on quirks of the old expression evaluation. ++ ++* Turn off underscoring for x86_64 PE+-COFF targets. For old behavior the ++ option --enable-leading-mingw64-underscores can be used on configure of ++ bfd. ++ ++* Add support for the TMS320C6000 (TI C6X) processor family. ++ ++* --add-needed renamed to --copy-dt-needed-entries in order to avoid confusion ++ with --as-needed option. ++ ++* Extend .def file syntax by '== ' for imports and exports. This allows ++ to alias the import/export table name written in PE image. ++ ++* Add --exclude-all-symbols option to PE based linkers. This prevents all ++ symbols from automatically being exported. ++ ++* Add support for the Renesas RX processor. ++ ++* Add support for alpha-vms target. ++ ++Changes in 2.20: ++ ++* GNU/Linux targets now support the STB_GNU_UNIQUE symbol binding. This is a ++ GNU extension to the standard set of ELF symbol bindings. The binding will ++ be passed on to the dynamic linker which will make sure that in the entire ++ process there is just one symbol with the given name and type in use. ++ ++* PE targets now support a GNU extension to allow the alignment of common ++ common symbols to be specified. This support uses custom options in ++ the .drectve section, which will be disregarded by the native tools. ++ ++* PE targets now add primitive support for ELF version scripts; symbols ++ are not versioned, but the local and global symbol visibility directives ++ are respected when filtering symbols in auto-export mode. ++ ++* New option --no-export-dynamic to undo the effect of the -E and ++ --export-dynamic options. ++ ++* ELF: --warn-alternate-em option to warn if an object has alternate ++ ELF machine code. ++ ++* New script function REGION_ALIAS to add alias names to memory regions. ++ ++* PE targets no longer make use of the long section names PE extension to ++ the COFF format when generating executable images, by default. The old ++ (slightly non-conformant) behaviour can still be invoked by using the ++ new '--enable-long-section-names' command-line option. It is also enabled ++ automatically in the presence of un-stripped debug information, as GDB ++ needs to be able to find the debug info sections by their full names. ++ ++* For GNU/Linux systems the linker will now avoid processing any relocations ++ made against symbols of the STT_GNU_IFUNC type and instead emit them into ++ the resulting binary for processing by the loader. ++ ++* --as-needed now links in a dynamic library if it satisfies undefined ++ symbols in regular objects, or in other dynamic libraries. In the ++ latter case the library is not linked if it is found in a DT_NEEDED ++ entry of one of the libraries already linked. ++ ++* Add a new command-line option, -Ttext-segment ADDR, for ELF targets ++ to set the address of the first byte of the text segment. ++ ++* Add support for Sunplus score architecture. ++ ++* Add new option --use-nul-prefixed-import-tables to ld for PE targets to ++ allow fallback to old import table generation with null element prefix. ++ ++* Windows PE systems now support a new --exclude-modules-for-implib option, ++ allowing users to partition object files and archive members between a DLL ++ and its associated import library as they are generated during linking. ++ ++* Add support for Lattice Mico32 (lm32) architecture. ++ ++* Add CR16 ELF --embedded-relocs (used to embedded relocations into binaries ++ for Embedded-PIC code) option. ++ ++* Add to the PE/PE+ targets the support of two different kinds of ++ pseudo-relocations. They can be selected by the switches ++ --enable-runtime-pseudo-reloc-v1 and --enable-runtime-pseudo-reloc-v2. ++ For the switch --enable-runtime-pseudo-reloc it uses for 32-bit ++ runtime pseudo relocation version one, for 64-bit the version two. ++ ++Changes in 2.19: ++ ++* Linker scripts support a new INSERT command that makes it easier to ++ augment the default script. ++ ++* Linker script input section filespecs may now specify a file within an ++ archive by writing "archive:file". ++ ++* The --sort-common switch now has an optional argument which specifies the ++ direction of sorting. ++ ++* The M68K linker now supports multiple GOT generation schemes controlled via ++ the --got= command-line option. ++ ++* The ARM EABI linker will now generate stubs for function calls to symbols ++ that are too far away. The placement of the stubs is controlled by a new ++ linker command-line option: --stub-group-size=N. ++ ++Changes in 2.18: ++ ++* Linker sources now released under version 3 of the GNU General Public ++ License. ++ ++* ELF: New --build-id option to generate a unique per-binary identifier ++ embedded in a note section. ++ ++* Added support for National Semicondutor CompactRISC (ie CR16) target. ++ ++* -l:foo now searches the library path for a filename called foo, ++ without converting it to libfoo.a or libfoo.so. ++ ++* Add a new command-line option '--default-script=FILE' or '-dT FILE' ++ which specifies a replacement for the built in, default linker ++ script. ++ ++* ELF: Add -Bsymbolic-functions, --dynamic-list-cpp-new, which puts C++ ++ operator new and delete on the dynamic list, and --dynamic-list-data, ++ builtin list for --dynamic-list, which puts global data symbols on the ++ dynamic list. ++ ++* Add support for x86_64 PE+ target. ++ ++* Add support for Score target. ++ ++* ELF: Add --dynamic-list option to specify a list of global symbols ++ whose references shouldn't be bound to the definition within the ++ shared library, or a list of symbols which should be added to the ++ symbol table in the executable. ++ ++* The default output section LMA has changed for allocatable sections from ++ being equal to VMA, to keeping the difference between LMA and VMA the same as ++ the previous output section in the same region. This is a more useful ++ default when using overlays and other cases where you specify an LMA ++ differing from the VMA for some sections. ++ ++* New switch: --print-gc-sections to list any sections removed by garabge ++ collection. ++ ++* ARM: Added --vfp11-denorm-fix option to work around an erratum in current ++ VFP11 coprocessors. ++ ++Changes in 2.17: ++ ++* Support for the Infineon XC16X has been added by KPIT Cummins Infosystems. ++ ++* Modify the Linux linker search order to better match ld.so search order. ++ Look for DT_NEEDED libraries in paths specified by ld.so.conf before ++ searching the default directories, rather than vice versa. ++ Use $prefix/etc/ld.so.conf if it exists, otherwise /etc/ld.so.conf. ++ ++* PE-COFF: Forward exports from DLL's can now be specified in .def files ++ passed directly to ld. ++ ++* Support for the Z80 processor family has been added. ++ ++* Add support for the "@" syntax to the command line, so that extra ++ switches can be read from . ++ ++Changes in 2.16: ++ ++* Support for the R_ARM_V4BX relocation as defined in the ARM AAELF ++ specification has been added via the --fix-v4bx command-line option. ++ ++* New linker script construct AS_NEEDED(), which sets the --as-needed flag ++ for input files listed inside of it. ++ ++* A new command-line option, --sysroot, can be used to override the ++ default sysroot location. It only applies to toolchains that were ++ configured using --with-sysroot. ++ ++* New linker script functions: ORIGIN() and LENGTH() which return information ++ about a specified memory region. ++ ++* Port to MAXQ processor contributed by HCL Tech. ++ ++* Added SEGMENT_START to the linker script language to permit the user to ++ override the base address for a segment from the command-line. ++ ++* ELF: --warn-shared-textrel option to warn if adding a DT_TEXTREL to a shared ++ object. ++ ++* Added SORT_BY_NAME and SORT_BY_ALIGNMENT to the linker script ++ language to permit sorting sections by section name or section ++ maximum alignment. ++ ++* Added a new linker command-line switch, --sort-section name|alignment, ++ to sort sections by section name or maximum alignment. ++ ++* ELF: --add-needed/--no-add-needed options to control if a DT_NEEDED tag ++ should be added when a shared library comes from DT_NEEDED tags. ++ ++* Support for the crx-elf target added. ++ ++* Support for the sh-symbianelf target added. ++ ++* A new linker command-line switch has been added which allows the hash table ++ size to be set to a suitable prime value near to its argument. This switch ++ is --hash-size=. Also if the switch --reduce-memory-overheads is ++ used, and --hash-size has not been used, then the default value will be set ++ to 1021. ++ ++* Linker map files are now generated with an O(N) algorithm for finding symbols ++ that are defined in each section. This uses about 40% more memory for ++ symbols than the old O(N^2) algorithm. You can use the new ++ --reduce-memory-overheads option to select the old algorithm; this option ++ might also be used in the future to select similar tradeoffs. ++ ++Changes in 2.15: ++ ++* ELF: --as-needed/--no-as-needed options to control if a DT_NEEDED tag should ++ be added only when a shared library is referenced. ++ ++* PE: --large-address-aware option to indicate executables support virtual ++ addresses greater than 2 gigabytes. ++ ++* DWARF 2 support for i386pe added. ++ ++* The linker script operator DEFINED() will now yield 1 only for a symbol that ++ is defined before the statement where DEFINED is used. ++ ++* The MIPS --embedded-relocs (used to embed relocations into binaries for ++ Embedded-PIC code) is deprecated and will be removed in a future release. ++ ++* cr16c support added by NSC. ++ ++* m32r Linux (ELF) support added by Renesas. ++ ++* Improved linker's handling of unresolved symbols. The switch ++ --unresolved-symbols= has been added to tell the linker when it ++ should report them and the switch --warn-unresolved-symbols has been added to ++ make reports be issued as warning messages rather than errors. ++ ++Changes in 2.14: ++ ++* Added support for Xtensa architecture. ++ ++* Added --with-sysroot configure switch to specify a target system root, for ++ linking against a target filesystem image. ++ ++* Added --accept-unknown-linker-format to restore old linker behaviour (pre ++ 2.14) of silently accepting and linking in any files in an unknown binary ++ file format. ++ ++* Added --no-omagic to undo the effects of the -N option. ++ ++* Support for Texas Instruments TMS320C4x and TMS320C3x series of ++ DSP's contributed by Michael Hayes and Svein E. Seldal. ++ ++* Added --with-lib-path configure switch to specify default value for ++ LIB_PATH. ++ ++* ARM port to QNX operating system added by Graeme Peterson. ++ ++* IP2K support added by Denis Chertykov. ++ ++Changes in 2.13: ++ ++* Support for the Fujitsu FRV architecture added by Red Hat. Models for FR400 ++ and FR500 included. ++ ++Changes in version 2.13: ++ ++* DEC VAX ELF support, by Matt Thomas. ++ ++Changes in version 2.12: ++ ++* Support for Don Knuth's MMIX, by Hans-Peter Nilsson. ++ ++* Support for the OpenRISC 32-bit embedded processor by OpenCores. ++ ++* Support for -z nocopyreloc in the x86 ELF linker, which disables ++ production of copy relocs. Warning: using this option may result in ++ non-sharable applications. ++ ++* Support for -z combreloc in the ELF linker, which puts dynamic ++ relocations against the same symbol together, so that dynamic linker ++ can use an one-entry symbol lookup cache. ++ ++* Support for ELF SHF_MERGE section merging, by Jakub Jelinek. ++ ++Changes in version 2.11: ++ ++* Support for AMD x86-64 architecture, by Jan Hubicka, SuSE Labs. ++ ++* Support added for eliminating duplicate DWARF2 debug information by ++ having the compiler generate the information in sections called ++ .gnu.linkonce.wi.XXXX where XXXX is a checksum for the contents. The ++ linker then merges these sections together into the normal .debug_info ++ section. ++ ++* The native ELF linker now searches the directories in DT_RUNPATH or ++ DT_RPATH of a shared library for shared libraries needed by it. ++ ++* TI C54x support, by Timothy Wall. ++ ++* Added command-line switch --section-start to set the start address of any ++ specified section. ++ ++* Added ability to emit full relocation information in linked executables, ++ enabled by --emit-relocs. Some post-linkage optimization tools need ++ this information in order to be able to correctly identify and perform ++ symbol relative addressing in the event of changes in section contents ++ (instructions being added or deleted, extending data sections, etc.) ++ ++* Support for i860, by Jason Eckhardt (preliminary, alpha quality). ++ ++* Support for CRIS (Axis Communications ETRAX series). ++ ++* Support for PDP-11 and 2.11BSD a.out format, by Lars Brinkhoff. ++ ++Changes in version 2.10: ++ ++* Added AT> to the linker script language to allow load-time allocation of ++ sections into regions. ++ ++* Added garbage collection of unused sections, enabled by --gc-sections. ++ It does require a bit of backend support; currently implemented are ++ arm-elf, avr-elf, d10v-elf, fr30-elf, i386-elf, m32r-elf, m68k-elf, ++ mcore-elf, mips-elf, mn10300-elf, ppc-elf, sh-elf, sparc-elf, and v850-elf. ++ Others will ignore the option. ++ ++* Added SORT to the linker script language to permit sorting sections by file ++ name or section name. ++ ++* Added EXTERN to the linker script language as an equivalent to the -u ++ command-line option. ++ ++* Added ASSERT to the linker script language. ++ ++* Added EXCLUDE_FILE to the linker script language for further control over ++ wildcard file names. ++ ++* Added -O option to optimize linker output (as of this writing, this only ++ affects ELF shared library generation). ++ ++* The -e option now accepts a number as well as a symbol name. ++ ++* Added --no-undefined option to disallow undefined symbols when creating a ++ shared library. ++ ++* The linker now issues a warning, not an error, for an undefined symbol when ++ using -Bsymbolic; use the new --no-undefined option to get the old ++ behaviour. ++ ++* Added --demangle and --no-demangle options. ++ ++Changes in version 2.9: ++ ++* Added SQUAD to the linker script language. ++ ++* New option --no-warn-mismatch. ++ ++* The MEMORY command now parses the attributes to determine where sections that ++ are not placed in a specific memory region are placed. ++ ++Changes in version 2.8: ++ ++* Linker scripts may now contain shell wildcard characters for file and section ++ names. ++ ++* The linker now supports symbol versions in ELF. ++ ++* The NOCROSSREFS command was added to the linker script language. ++ ++* The LOADADDR expression was added to the linker script language. ++ ++* MAX and MIN functions were added to the linker script language. ++ ++* The OVERLAY construct was added to the linker script language. ++ ++* New option --warn-section-align to warn when the address of an output section ++ changes due to alignment of an input section. ++ ++* New options --filter/-F and --auxiliary/-f. ++ ++Changes in version 2.7: ++ ++* New option --cref to print out a cross reference table. ++ ++* New option --wrap SYMBOL. ++ ++* New option --no-whole-archive, to turn off the effect of --whole-archive. ++ ++* Input sections assigned to the output section /DISCARD/ in the linker script ++ are not included in the output file. ++ ++* The SunOS and ELF linkers now merge stabs debugging information which uses ++ the N_BINCL and N_EINCL stab types. This reduces the amount of debugging ++ information generated. ++ ++Changes in version 2.6: ++ ++* When an ELF section name is representable as a C identifier (this is not true ++of most ELF section names), the linker will automatically define symbols ++__start_SECNAME and __stop_SECNAME, where SECNAME is the section name, at the ++beginning and the end of the section. This is used by glibc. ++ ++ Addendum: Current versions of the linker (at least for version 2.18 onwards ++and possibly much earlier as well) place two restrictions on this feature: The ++symbols are only implemented for orphaned sections, not for explicitly placed ++sections and they are PROVIDEd rather than being defined. ++ ++* When an ELF section named .gnu.warning is encountered in an input file, the ++contents of the section are displayed as an error message, and the section is ++not copied into the output file. This is used by glibc. ++ ++* When an ELF section named .gnu.warning.SYMBOL is encountered in an input ++file, and the symbol SYMBOL is referenced by some object file, the contents of ++the section are displayed as an error message. The section is not copied into ++the output file, unless doing a relocatable or shared link. This is used by ++glibc. ++ ++* New options -split-by-reloc and -split-by-file. ++ ++* The linker now supports linking PIC compiled code on SPARC SunOS. It can ++also create SPARC SunOS shared libraries, and, like the native SunOS linker, ++will do so whenever there is an undefined symbol in the link and neither the -e ++nor the -r option was used. ++ ++* The -rpath option may be used on SunOS to set the list of directories to be ++searched at run time. This overrides the default of building the list from the ++-L options. ++ ++* The COFF linker now combines debugging information for structs, unions, and ++enums, so that even if the same type is defined in multiple input files it will ++only be defined once in the output file. The --traditional-format switch will ++prevent this optimization. ++ ++Changes in version 2.5: ++ ++* The linker now supports linking against SunOS shared libraries. It still can ++not link SunOS PIC (Position Independent Code) files, so it can not be used to ++generate shared libraries. ++ ++* The linker now supports linking against ELF shared libraries for the i386 ++(UnixWare) and SPARC (Solaris). It can also link ELF PIC files, and can be ++used to generate shared libraries. Shared library generation is not well ++tested; please report any problems encountered. The linker is now enabled for ++Solaris again. ++ ++* Eric Youngdale has contributed Linux support code, including linking against ++Linux a.out shared libraries. The linker produces Linux QMAGIC binaries. ++ ++* The ELF backend has been converted to the new linker code. To use the new ++ELF linker, each particular target requires a relocation function. So far, ++this function has been written for i386 (UnixWare), SPARC (Solaris) MIPS (Irix ++5), and HPPA ELF targets. ++ ++* The -( (--start-group) and -) (--end-group) options have been added to ++support searching a group of archives as though they were a single archive. ++This can also be used in a linker script, as GROUP ( files ). ++ ++* When a file is named on the command line, and the linker does not recognize ++it as an object file, the linker will now treat the file as a linker script ++file. A linker script named in this way augments, but does not replace, the ++default linker script. ++ ++* The -warn-once option was added. It causes the linker to only warn once per ++undefined symbol, rather than once per reference. ++ ++* The COFF backend has been converted to the new linker code. As with ELF, to ++use the new linker, each particular target requires a relocation function. So ++far, this function has been written for the i386, m68k, a29k and SH targets. ++ ++* The -V flag was made a synonym for -v, for SVR4 compatibility. The old -V ++behaviour is available via --verbose. ++ ++Changes in version 2.4: ++ ++* New linker code, by Steve Chamberlain and Ian Taylor. For a.out and ecoff ++ formats (so far), this should result in considerable savings in time ++ and memory used while linking; slightly poorer performance than ++ before for formats not converted yet. ++ ++* Command-line parsing is no longer done with flex. This means ++ oddball characters in filenames won't get treated as argument ++ separators. ++ ++* HP-PA ELF support, by Jeff Law. (No SOM support yet.) ++ ++* Mach i386 support, by David Mackenzie. ++ ++* Irix 4 shared libraries are now supported (Irix 5 uses ELF, and ELF shared ++ libraries are not yet supported). ++ ++* COFF shared libraries (as on SCO) should work as well. ++ ++* The linker is disabled for Solaris. (Actually, it was in 2.3 also, I just ++ forgot to note it.) Some of their C library routines don't work when ++ statically linked, and the GNU linker doesn't support dynamic linking yet. ++ ++Changes in version 2.3: ++ ++* Weak symbols are now supported. ++ ++* ELF support has been added. The linker has been bootstrapped on ++ UnixWare and Solaris. ++ ++* Alpha OSF/1 support has been added (non dynamic linking only). ++ ++Changes in version 2.2: ++ ++* The `bfd' library has been updated to reduce a.out-format string ++ table size. The effect of this is that files linked from many input ++ files with duplicate symbols (`-g' debugging records, or identical ++ static symbols) should be much smaller. ++ ++Changes in version 2.1: ++ ++* The ld -ySYMBOL flag (to trace references to SYMBOL) is now implemented. ++ ++* There is now support for writing ECOFF files, so ld and the ++ other utilities should work on Risc/Ultrix and Irix. ++ ++ ++Copyright (C) 2012-2023 Free Software Foundation, Inc. ++ ++Copying and distribution of this file, with or without modification, ++are permitted in any medium without royalty provided the copyright ++notice and this notice are preserved. ++ ++Local variables: ++fill-column: 79 ++End: +diff -rupN binutils.orig/ld/config.in binutils-2.41/ld/config.in +--- binutils.orig/ld/config.in 2023-10-19 12:11:47.607940858 +0100 ++++ binutils-2.41/ld/config.in 2023-10-19 12:11:56.515949625 +0100 +@@ -19,6 +19,14 @@ + /* Define if you want compressed debug sections by default. */ + #undef DEFAULT_FLAG_COMPRESS_DEBUG + ++/* Define to 1 if you want to turn executable stack warnings into errors by ++ default. */ ++#undef DEFAULT_LD_ERROR_EXECSTACK ++ ++/* Define to 1 if you want to turn executable segment warnings into errors by ++ default. */ ++#undef DEFAULT_LD_ERROR_RWX_SEGMENTS ++ + /* Define to 0 if you want to disable the generation of an executable stack + when a .note-GNU-stack section is missing. */ + #undef DEFAULT_LD_EXECSTACK +diff -rupN binutils.orig/ld/configure binutils-2.41/ld/configure +--- binutils.orig/ld/configure 2023-10-19 12:11:47.607940858 +0100 ++++ binutils-2.41/ld/configure 2023-10-19 12:11:56.516949626 +0100 +@@ -848,7 +848,9 @@ enable_relro + enable_textrel_check + enable_separate_code + enable_warn_execstack ++enable_error_execstack + enable_warn_rwx_segments ++enable_error_rwx_segments + enable_default_execstack + enable_error_handling_script + enable_default_hash_style +@@ -15638,6 +15640,16 @@ esac + fi + + ++ac_default_ld_error_execstack=0 ++# Check whether --enable-error-execstack was given. ++if test "${enable_error_execstack+set}" = set; then : ++ enableval=$enable_error_execstack; case "${enableval}" in ++ yes) ac_default_ld_error_execstack=1 ;; ++ no) ac_default_ld_error_execstack=0 ;; ++esac ++fi ++ ++ + ac_default_ld_warn_rwx_segments=unset + # Check whether --enable-warn-rwx-segments was given. + if test "${enable_warn_rwx_segments+set}" = set; then : +@@ -15648,6 +15660,16 @@ esac + fi + + ++ac_default_ld_error_rwx_segments=0 ++# Check whether --enable-error-rwx-segments was given. ++if test "${enable_error_rwx_segments+set}" = set; then : ++ enableval=$enable_error_rwx_segments; case "${enableval}" in ++ yes) ac_default_ld_error_rwx_segments=1 ;; ++ no) ac_default_ld_error_rwx_segments=0 ;; ++esac ++fi ++ ++ + ac_default_ld_default_execstack=unset + # Check whether --enable-default-execstack was given. + if test "${enable_default_execstack+set}" = set; then : +@@ -17442,6 +17464,12 @@ cat >>confdefs.h <<_ACEOF + _ACEOF + + ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_ERROR_EXECSTACK $ac_default_ld_error_execstack ++_ACEOF ++ ++ + if test "${ac_default_ld_warn_rwx_segments}" = unset; then + ac_default_ld_warn_rwx_segments=1 + fi +@@ -17451,6 +17479,12 @@ cat >>confdefs.h <<_ACEOF + _ACEOF + + ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_ERROR_RWX_SEGMENTS $ac_default_ld_error_rwx_segments ++_ACEOF ++ ++ + if test "${ac_default_ld_default_execstack}" = unset; then + ac_default_ld_default_execstack=1 + fi +diff -rupN binutils.orig/ld/configure.ac binutils-2.41/ld/configure.ac +--- binutils.orig/ld/configure.ac 2023-10-19 12:11:47.607940858 +0100 ++++ binutils-2.41/ld/configure.ac 2023-10-19 12:11:56.516949626 +0100 +@@ -225,6 +225,15 @@ AC_ARG_ENABLE(warn-execstack, + no) ac_default_ld_warn_execstack=0 ;; + esac]) + ++ac_default_ld_error_execstack=0 ++AC_ARG_ENABLE(error-execstack, ++ AS_HELP_STRING([--enable-error-execstack], ++ [turn executable stack warnings into errors]), ++[case "${enableval}" in ++ yes) ac_default_ld_error_execstack=1 ;; ++ no) ac_default_ld_error_execstack=0 ;; ++esac]) ++ + ac_default_ld_warn_rwx_segments=unset + AC_ARG_ENABLE(warn-rwx-segments, + AS_HELP_STRING([--enable-warn-rwx-segments], +@@ -234,6 +243,15 @@ AC_ARG_ENABLE(warn-rwx-segments, + no) ac_default_ld_warn_rwx_segments=0 ;; + esac]) + ++ac_default_ld_error_rwx_segments=0 ++AC_ARG_ENABLE(error-rwx-segments, ++ AS_HELP_STRING([--enable-error-rwx-segments], ++ [turn executable segment warnings into errors]), ++[case "${enableval}" in ++ yes) ac_default_ld_error_rwx_segments=1 ;; ++ no) ac_default_ld_error_rwx_segments=0 ;; ++esac]) ++ + ac_default_ld_default_execstack=unset + AC_ARG_ENABLE(default-execstack, + AS_HELP_STRING([--enable-default-execstack], +@@ -568,6 +586,10 @@ AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_EXECS + $ac_default_ld_warn_execstack, + [Define to 1 if you want to enable --warn-execstack in ELF linker by default.]) + ++AC_DEFINE_UNQUOTED(DEFAULT_LD_ERROR_EXECSTACK, ++ $ac_default_ld_error_execstack, ++ [Define to 1 if you want to turn executable stack warnings into errors by default.]) ++ + if test "${ac_default_ld_warn_rwx_segments}" = unset; then + ac_default_ld_warn_rwx_segments=1 + fi +@@ -575,6 +597,10 @@ AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_RWX_S + $ac_default_ld_warn_rwx_segments, + [Define to 0 if you want to disable --warn-rwx-segments in ELF linker by default.]) + ++AC_DEFINE_UNQUOTED(DEFAULT_LD_ERROR_RWX_SEGMENTS, ++ $ac_default_ld_error_rwx_segments, ++ [Define to 1 if you want to turn executable segment warnings into errors by default.]) ++ + if test "${ac_default_ld_default_execstack}" = unset; then + ac_default_ld_default_execstack=1 + fi +diff -rupN binutils.orig/ld/configure.ac.orig binutils-2.41/ld/configure.ac.orig +--- binutils.orig/ld/configure.ac.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/configure.ac.orig 2023-10-19 12:11:39.546932920 +0100 +@@ -0,0 +1,688 @@ ++dnl Process this file with autoconf to produce a configure script ++dnl ++dnl Copyright (C) 2012-2023 Free Software Foundation, Inc. ++dnl ++dnl This file is free software; you can redistribute it and/or modify ++dnl it under the terms of the GNU General Public License as published by ++dnl the Free Software Foundation; either version 3 of the License, or ++dnl (at your option) any later version. ++dnl ++dnl This program is distributed in the hope that it will be useful, ++dnl but WITHOUT ANY WARRANTY; without even the implied warranty of ++dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++dnl GNU General Public License for more details. ++dnl ++dnl You should have received a copy of the GNU General Public License ++dnl along with this program; see the file COPYING3. If not see ++dnl . ++dnl ++ ++m4_include([../bfd/version.m4]) ++AC_INIT([ld], BFD_VERSION) ++AC_CONFIG_SRCDIR(ldmain.c) ++ ++AC_CANONICAL_TARGET ++AC_CANONICAL_BUILD ++ ++AM_INIT_AUTOMAKE ++AM_SILENT_RULES([yes]) ++AM_MAINTAINER_MODE ++ ++AC_PROG_CC ++AC_PROG_CXX ++AC_PROG_GREP ++AC_GNU_SOURCE ++AC_USE_SYSTEM_EXTENSIONS ++AC_PROG_INSTALL ++PKG_PROG_PKG_CONFIG ++ ++LT_INIT ++ACX_LARGEFILE ++ ++ac_checking= ++. ${srcdir}/../bfd/development.sh ++test "$development" = true && ac_checking=yes ++AC_ARG_ENABLE(checking, ++[ --enable-checking enable run-time checks], ++[case "${enableval}" in ++ no|none) ac_checking= ;; ++ *) ac_checking=yes ;; ++esac])dnl ++if test x$ac_checking != x ; then ++ AC_DEFINE(ENABLE_CHECKING, 1, [Define if you want run-time sanity checks.]) ++fi ++ ++AC_ARG_WITH(lib-path, [ --with-lib-path=dir1:dir2... set default LIB_PATH],LIB_PATH=$withval) ++AC_ARG_ENABLE(targets, ++[ --enable-targets alternative target configurations], ++[case "${enableval}" in ++ yes | "") AC_MSG_ERROR(enable-targets option must specify target names or 'all') ++ ;; ++ no) enable_targets= ;; ++ *) enable_targets=$enableval ;; ++esac])dnl ++ ++BFD_64_BIT ++ ++AC_ARG_WITH(sysroot, ++[ --with-sysroot[=DIR] Search for usr/lib et al within DIR.], ++[ ++ case ${with_sysroot} in ++ yes) TARGET_SYSTEM_ROOT='${exec_prefix}/${target_alias}/sys-root' ;; ++ *) TARGET_SYSTEM_ROOT=$with_sysroot ;; ++ esac ++ ++ TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"' ++ use_sysroot=yes ++ ++ if test "x$prefix" = xNONE; then ++ test_prefix=/usr/local ++ else ++ test_prefix=$prefix ++ fi ++ if test "x$exec_prefix" = xNONE; then ++ test_exec_prefix=$test_prefix ++ else ++ test_exec_prefix=$exec_prefix ++ fi ++ case ${TARGET_SYSTEM_ROOT} in ++ "${test_prefix}"|"${test_prefix}/"*|\ ++ "${test_exec_prefix}"|"${test_exec_prefix}/"*|\ ++ '${prefix}'|'${prefix}/'*|\ ++ '${exec_prefix}'|'${exec_prefix}/'*) ++ t="$TARGET_SYSTEM_ROOT_DEFINE -DTARGET_SYSTEM_ROOT_RELOCATABLE" ++ TARGET_SYSTEM_ROOT_DEFINE="$t" ++ ;; ++ esac ++], [ ++ use_sysroot=no ++ TARGET_SYSTEM_ROOT= ++ TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"\"' ++]) ++AC_SUBST(use_sysroot) ++AC_SUBST(TARGET_SYSTEM_ROOT) ++AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) ++ ++dnl Use --enable-gold to decide if this linker should be the default. ++dnl "install_as_default" is set to false if gold is the default linker. ++dnl "installed_linker" is the installed BFD linker name. ++AC_ARG_ENABLE(gold, ++[[ --enable-gold[=ARG] build gold [ARG={default,yes,no}]]], ++[case "${enableval}" in ++ default) ++ install_as_default=no ++ installed_linker=ld.bfd ++ ;; ++ yes|no) ++ install_as_default=yes ++ installed_linker=ld.bfd ++ ;; ++ *) ++ AC_MSG_ERROR([invalid --enable-gold argument]) ++ ;; ++ esac], ++[install_as_default=yes ++ installed_linker=ld.bfd]) ++AC_SUBST(install_as_default) ++AC_SUBST(installed_linker) ++ ++AC_ARG_ENABLE([got], ++AS_HELP_STRING([--enable-got=], ++ [GOT handling scheme (target, single, negative, multigot)]), ++[case "${enableval}" in ++ target | single | negative | multigot) got_handling=$enableval ;; ++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-got option) ;; ++esac], ++[got_handling=target]) ++ ++case "${got_handling}" in ++ target) ++ AC_DEFINE([GOT_HANDLING_DEFAULT], [GOT_HANDLING_TARGET_DEFAULT], ++ [Define to choose default GOT handling scheme]) ;; ++ single) ++ AC_DEFINE([GOT_HANDLING_DEFAULT], [GOT_HANDLING_SINGLE], ++ [Define to choose default GOT handling scheme]) ;; ++ negative) ++ AC_DEFINE([GOT_HANDLING_DEFAULT], [GOT_HANDLING_NEGATIVE], ++ [Define to choose default GOT handling scheme]) ;; ++ multigot) ++ AC_DEFINE([GOT_HANDLING_DEFAULT], [GOT_HANDLING_MULTIGOT], ++ [Define to choose default GOT handling scheme]) ;; ++ *) AC_MSG_ERROR(bad value ${got_handling} for --enable-got option) ;; ++esac ++ ++# PR gas/19109 ++# Decide the default method for compressing debug sections. ++ac_default_compressed_debug_sections=unset ++# Provide a configure time option to override our default. ++AC_ARG_ENABLE(compressed_debug_sections, ++ AS_HELP_STRING([--enable-compressed-debug-sections={all,ld,none}], ++ [compress debug sections by default])], ++[case ,"${enableval}", in ++ ,yes, | ,all, | *,ld,*) ac_default_compressed_debug_sections=yes ;; ++ ,no, | ,none,) ac_default_compressed_debug_sections=no ;; ++esac])dnl ++ ++# Select default compression algorithm. ++ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB ++AC_ARG_ENABLE(default_compressed_debug_sections_algorithm, ++ AS_HELP_STRING([--enable-default-compressed-debug-sections-algorithm={zlib,zstd}], ++ [Default compression algorithm for --enable-compressed-debug-sections.]), ++[case "${enableval}" in ++ zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; ++esac])dnl ++ ++# Decide setting DT_RUNPATH instead of DT_RPATH by default ++ac_default_new_dtags=unset ++# Provide a configure time option to override our default. ++AC_ARG_ENABLE(new_dtags, ++ AS_HELP_STRING([--enable-new-dtags], ++ [set DT_RUNPATH instead of DT_RPATH by default])], ++[case "${enableval}" in ++ yes) ac_default_new_dtags=1 ;; ++ no) ac_default_new_dtags=0 ;; ++esac])dnl ++ ++# Decide if -z relro should be enabled in ELF linker by default. ++ac_default_ld_z_relro=unset ++# Provide a configure time option to override our default. ++AC_ARG_ENABLE(relro, ++ AS_HELP_STRING([--enable-relro], ++ [enable -z relro in ELF linker by default]), ++[case "${enableval}" in ++ yes) ac_default_ld_z_relro=1 ;; ++ no) ac_default_ld_z_relro=0 ;; ++esac])dnl ++ ++# Decide if DT_TEXTREL check should be enabled in ELF linker. ++ac_default_ld_textrel_check=unset ++AC_ARG_ENABLE([textrel-check], ++ AC_HELP_STRING([--enable-textrel-check=@<:@yes|no|warning|error@:>@], ++ [enable DT_TEXTREL check in ELF linker]), ++[case "${enableval}" in ++ yes|no|warning|error) ac_default_ld_textrel_check=${enableval} ;; ++esac]) ++ ++# Decide if -z separate-code should be enabled in ELF linker by default. ++ac_default_ld_z_separate_code=unset ++AC_ARG_ENABLE(separate-code, ++ AS_HELP_STRING([--enable-separate-code], ++ [enable -z separate-code in ELF linker by default]), ++[case "${enableval}" in ++ yes) ac_default_ld_z_separate_code=1 ;; ++ no) ac_default_ld_z_separate_code=0 ;; ++esac]) ++ ++ ++# By default warn when an executable stack is created due to object files ++# requesting such, not when the user specifies -z execstack. ++ac_default_ld_warn_execstack=2 ++AC_ARG_ENABLE(warn-execstack, ++ AS_HELP_STRING([--enable-warn-execstack], ++ [enable warnings when creating an executable stack]), ++[case "${enableval}" in ++ yes) ac_default_ld_warn_execstack=1 ;; ++ no) ac_default_ld_warn_execstack=0 ;; ++esac]) ++ ++ac_default_ld_warn_rwx_segments=unset ++AC_ARG_ENABLE(warn-rwx-segments, ++ AS_HELP_STRING([--enable-warn-rwx-segments], ++ [enable warnings when creating segements with RWX permissions]), ++[case "${enableval}" in ++ yes) ac_default_ld_warn_rwx_segments=1 ;; ++ no) ac_default_ld_warn_rwx_segments=0 ;; ++esac]) ++ ++ac_default_ld_default_execstack=unset ++AC_ARG_ENABLE(default-execstack, ++ AS_HELP_STRING([--enable-default-execstack], ++ [create an executable stack if an input file is missing a .note.GNU-stack section]), ++[case "${enableval}" in ++ yes) ac_default_ld_default_execstack=1 ;; ++ no) ac_default_ld_default_execstack=0 ;; ++esac]) ++ ++ ++# Decide if --error-handling-script should be supported. ++ac_support_error_handling_script=unset ++AC_ARG_ENABLE(error-handling-script, ++ AS_HELP_STRING([--enable-error-handling-script], ++ [enable/disable support for the --error-handling-script option]), ++[case "${enableval}" in ++ yes) ac_support_error_handling_script=1 ;; ++ no) ac_support_error_handling_script=0 ;; ++esac]) ++ ++# Decide which "--hash-style" to use by default ++# Provide a configure time option to override our default. ++AC_ARG_ENABLE([default-hash-style], ++AS_HELP_STRING([--enable-default-hash-style={sysv,gnu,both}], ++ [use this default hash style]), ++[case "${enable_default_hash_style}" in ++ sysv | gnu | both) ;; ++ *) AC_MSG_ERROR([bad value ${enable_default_hash_style} for enable-default-hash-style option]) ;; ++esac], ++[case "${target}" in ++ # Enable gnu hash only on GNU targets, but not mips ++ mips*-*-*) enable_default_hash_style=sysv ;; ++ *-*-gnu* | *-*-linux* | *-*-nacl*) enable_default_hash_style=both ;; ++ *) enable_default_hash_style=sysv ;; ++esac]) ++ ++case "${enable_default_hash_style}" in ++ sysv | both) ac_default_emit_sysv_hash=1 ;; ++ *) ac_default_emit_sysv_hash=0 ;; ++esac ++ ++case "${enable_default_hash_style}" in ++ gnu | both) ac_default_emit_gnu_hash=1 ;; ++ *) ac_default_emit_gnu_hash=0 ;; ++esac ++ ++AC_ARG_ENABLE(initfini-array, ++[ --disable-initfini-array do not use .init_array/.fini_array sections], ++[case "${enableval}" in ++ yes|no) ;; ++ *) AC_MSG_ERROR([invalid --enable-initfini-array argument]) ;; ++ esac], [enable_initfini_array=yes]) ++AC_SUBST(enable_initfini_array) ++if test $enable_initfini_array = yes; then ++ AC_DEFINE(HAVE_INITFINI_ARRAY, 1, ++ [Define .init_array/.fini_array sections are available and working.]) ++fi ++ ++GCC_ENABLE([libctf], [yes], [], [Handle .ctf type-info sections]) ++if test "${enable_libctf}" = yes; then ++ AC_DEFINE(ENABLE_LIBCTF, 1, [Handle .ctf type-info sections]) ++fi ++AM_CONDITIONAL(ENABLE_LIBCTF, test "${enable_libctf}" = yes) ++AC_SUBST(enable_libctf) ++ ++# Used to validate --package-metadata= input. Disabled by default. ++AC_ARG_ENABLE([jansson], ++ [AS_HELP_STRING([--enable-jansson], ++ [enable jansson [default=no]])], ++ [enable_jansson=$enableval], ++ [enable_jansson="no"]) ++ ++AS_IF([test "x$enable_jansson" != "xno"], ++ [PKG_CHECK_MODULES(JANSSON, [jansson], ++ [ ++ AC_DEFINE(HAVE_JANSSON, 1, [The jansson library is to be used]) ++ AC_SUBST([JANSSON_CFLAGS]) ++ AC_SUBST([JANSSON_LIBS]) ++ ], ++ [AC_MSG_ERROR([Cannot find jansson library])]) ++ ]) ++ ++AM_BINUTILS_WARNINGS ++ ++AM_LC_MESSAGES ++ ++AC_CONFIG_HEADERS([config.h:config.in]) ++ ++# PR 14072 ++AH_VERBATIM([00_CONFIG_H_CHECK], ++[/* Check that config.h is #included before system headers ++ (this works only for glibc, but that should be enough). */ ++#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__CONFIG_H__) ++# error config.h must be #included before system headers ++#endif ++#define __CONFIG_H__ 1]) ++ ++if test -z "$target" ; then ++ AC_MSG_ERROR(Unrecognized target system type; please check config.sub.) ++fi ++if test -z "$host" ; then ++ AC_MSG_ERROR(Unrecognized host system type; please check config.sub.) ++fi ++ ++# host-specific stuff: ++ ++ALL_LINGUAS="bg da de es fi fr ga id it ja pt_BR ru sr sv tr uk vi zh_CN zh_TW" ++ZW_GNU_GETTEXT_SISTER_DIR ++AM_PO_SUBDIRS ++ ++AC_EXEEXT ++ ++AC_PROG_YACC ++AM_PROG_LEX ++ ++AM_MAINTAINER_MODE ++AM_CONDITIONAL(GENINSRC_NEVER, false) ++ACX_PROG_CMP_IGNORE_INITIAL ++ ++. ${srcdir}/configure.host ++ ++AC_SUBST(HDEFINES) ++AC_SUBST(NATIVE_LIB_DIRS) ++ ++# We use headers from include/ that check various HAVE_*_H macros, thus ++# should ensure they are set by configure. This is true even when C99 ++# guarantees they are available. ++# sha1.h and md4.h test HAVE_LIMITS_H, HAVE_SYS_TYPES_H and HAVE_STDINT_H ++# plugin-api.h tests HAVE_STDINT_H and HAVE_INTTYPES_H ++# Besides those, we need to check anything used in ld/ not in C99. ++AC_CHECK_HEADERS(fcntl.h elf-hints.h limits.h inttypes.h stdint.h \ ++ sys/file.h sys/mman.h sys/param.h sys/stat.h sys/time.h \ ++ sys/types.h unistd.h) ++AC_CHECK_FUNCS(close glob lseek mkstemp open realpath waitpid) ++ ++BFD_BINARY_FOPEN ++ ++AC_CHECK_DECLS([asprintf, environ]) ++ ++AC_FUNC_MMAP ++ ++AC_SEARCH_LIBS([dlopen], [dl]) ++ ++AC_MSG_CHECKING(for a known getopt prototype in unistd.h) ++AC_CACHE_VAL(ld_cv_decl_getopt_unistd_h, ++[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [extern int getopt (int, char *const*, const char *);])], ++ld_cv_decl_getopt_unistd_h=yes, ld_cv_decl_getopt_unistd_h=no)]) ++AC_MSG_RESULT($ld_cv_decl_getopt_unistd_h) ++if test $ld_cv_decl_getopt_unistd_h = yes; then ++ AC_DEFINE([HAVE_DECL_GETOPT], 1, ++ [Is the prototype for getopt in in the expected format?]) ++fi ++ ++# Link in zlib/zstd if we can. This allows us to read and write ++# compressed debug sections. ++AM_ZLIB ++AC_ZSTD ++ ++# When converting linker scripts into strings for use in emulation ++# files, use astring.sed if the compiler supports ANSI string ++# concatenation, or ostring.sed otherwise. This is to support the ++# broken Microsoft MSVC compiler, which limits the length of string ++# constants, while still supporting pre-ANSI compilers which do not ++# support string concatenation. ++AC_MSG_CHECKING([whether ANSI C string concatenation works]) ++AC_CACHE_VAL(ld_cv_string_concatenation, ++[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [char *a = "a" "a";])], ++ ld_cv_string_concatenation=yes, ++ ld_cv_string_concatenation=no)]) ++AC_MSG_RESULT($ld_cv_string_concatenation) ++if test "$ld_cv_string_concatenation" = "yes"; then ++ STRINGIFY=astring.sed ++else ++ STRINGIFY=ostring.sed ++fi ++AC_SUBST(STRINGIFY) ++ ++# target-specific stuff: ++ ++all_targets= ++EMUL= ++all_emuls= ++all_emul_extras= ++all_libpath= ++TDIRS= ++ ++elf_list_options=false ++elf_shlib_list_options=false ++elf_plt_unwind_list_options=false ++for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'` ++do ++ if test "$targ_alias" = "all"; then ++ all_targets=true ++ elf_list_options=true ++ elf_shlib_list_options=true ++ elf_plt_unwind_list_options=true ++ else ++ # Canonicalize the secondary target names. ++ result=`$ac_config_sub $targ_alias 2>/dev/null` ++ if test -n "$result"; then ++ targ=$result ++ else ++ targ=$targ_alias ++ fi ++ ++ . ${srcdir}/configure.tgt ++ ++ if test "$targ" = "$target"; then ++ EMUL=$targ_emul ++ fi ++ ++ if test x${enable_64_bit_bfd} = xno; then ++ . ${srcdir}/../bfd/config.bfd ++ fi ++ ++ if test x${enable_64_bit_bfd} = xyes; then ++ targ_extra_emuls="$targ_extra_emuls $targ64_extra_emuls" ++ targ_extra_libpath="$targ_extra_libpath $targ64_extra_libpath" ++ fi ++ ++ for i in $targ_emul $targ_extra_emuls $targ_extra_libpath; do ++ case " $all_emuls " in ++ *" e${i}.o "*) ;; ++ *) ++ all_emuls="$all_emuls e${i}.o" ++ eval result=\$tdir_$i ++ test -z "$result" && result=$targ_alias ++ TDIRS="$TDIRS ++tdir_$i=$result" ++ case "${i}" in ++ *elf*) ++ elf_list_options=true ++ ;; ++ *) ++ if $GREP "TEMPLATE_NAME=elf" ${srcdir}/emulparams/${i}.sh >/dev/null 2>/dev/null; then ++ elf_list_options=true ++ fi ++ ;; ++ esac ++ if test "$elf_list_options" = "true"; then ++ source_sh() ++ { ++ . $1 ++ } ++ source_sh ${srcdir}/emulparams/${i}.sh ++ if test x${GENERATE_SHLIB_SCRIPT} = xyes; then ++ elf_shlib_list_options=true ++ fi ++ if test x${PLT_UNWIND} = xyes; then ++ elf_plt_unwind_list_options=true ++ fi ++ fi ++ ;; ++ esac ++ done ++ ++ for i in $targ_emul $targ_extra_libpath; do ++ case " $all_libpath " in ++ *" ${i} "*) ;; ++ *) ++ if test -z "$all_libpath"; then ++ all_libpath=${i} ++ else ++ all_libpath="$all_libpath ${i}" ++ fi ++ ;; ++ esac ++ done ++ ++ for i in $targ_extra_ofiles; do ++ case " $all_emul_extras " in ++ *" ${i} "*) ;; ++ *) ++ all_emul_extras="$all_emul_extras ${i}" ++ ;; ++ esac ++ done ++ ++ fi ++done ++ ++if test x$ac_default_compressed_debug_sections = xyes ; then ++ AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.]) ++fi ++ ++AC_DEFINE_UNQUOTED(DEFAULT_COMPRESSED_DEBUG_ALGORITHM, $ac_default_compressed_debug_sections_algorithm, ++ [Default compression algorithm for --enable-compressed-debug-sections.]) ++ ++if test "${ac_default_new_dtags}" = unset; then ++ ac_default_new_dtags=0 ++fi ++AC_DEFINE_UNQUOTED(DEFAULT_NEW_DTAGS, ++ $ac_default_new_dtags, ++ [Define to 1 if you want to set DT_RUNPATH instead of DT_RPATH by default.]) ++ ++if test "${ac_default_ld_z_relro}" = unset; then ++ ac_default_ld_z_relro=0 ++fi ++AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_RELRO, ++ $ac_default_ld_z_relro, ++ [Define to 1 if you want to enable -z relro in ELF linker by default.]) ++ ++ac_default_ld_textrel_check_warning=0 ++case "${ac_default_ld_textrel_check}" in ++ unset|no) ++ ac_default_ld_textrel_check=textrel_check_none ++ ;; ++ yes|warning) ++ ac_default_ld_textrel_check=textrel_check_warning ++ ac_default_ld_textrel_check_warning=1 ++ ;; ++ error) ++ ac_default_ld_textrel_check=textrel_check_error ++ ;; ++esac ++AC_DEFINE_UNQUOTED(DEFAULT_LD_TEXTREL_CHECK, ++ $ac_default_ld_textrel_check, ++ [The default method for DT_TEXTREL check in ELF linker.]) ++AC_DEFINE_UNQUOTED(DEFAULT_LD_TEXTREL_CHECK_WARNING, ++ $ac_default_ld_textrel_check_warning, ++ [Define to 1 if DT_TEXTREL check is warning in ELF linker by default.]) ++ ++if test "${ac_default_ld_z_separate_code}" = unset; then ++ ac_default_ld_z_separate_code=0 ++fi ++AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_SEPARATE_CODE, ++ $ac_default_ld_z_separate_code, ++ [Define to 1 if you want to enable -z separate-code in ELF linker by default.]) ++ ++ ++AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_EXECSTACK, ++ $ac_default_ld_warn_execstack, ++ [Define to 1 if you want to enable --warn-execstack in ELF linker by default.]) ++ ++if test "${ac_default_ld_warn_rwx_segments}" = unset; then ++ ac_default_ld_warn_rwx_segments=1 ++fi ++AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_RWX_SEGMENTS, ++ $ac_default_ld_warn_rwx_segments, ++ [Define to 0 if you want to disable --warn-rwx-segments in ELF linker by default.]) ++ ++if test "${ac_default_ld_default_execstack}" = unset; then ++ ac_default_ld_default_execstack=1 ++fi ++AC_DEFINE_UNQUOTED(DEFAULT_LD_EXECSTACK, ++ $ac_default_ld_default_execstack, ++ [Define to 0 if you want to disable the generation of an executable stack when a .note-GNU-stack section is missing.]) ++ ++ ++if test "${ac_support_error_handling_script}" = unset; then ++ ac_support_error_handling_script=1 ++fi ++AC_DEFINE_UNQUOTED(SUPPORT_ERROR_HANDLING_SCRIPT, ++ $ac_support_error_handling_script, ++ [Define to 1 if you want to support the --error-handling-script command line option.]) ++ ++AC_DEFINE_UNQUOTED([DEFAULT_EMIT_SYSV_HASH], ++ [$ac_default_emit_sysv_hash], ++ [Define to 1 if you want to emit sysv hash in the ELF linker by default.]) ++ ++AC_DEFINE_UNQUOTED([DEFAULT_EMIT_GNU_HASH], ++ [$ac_default_emit_gnu_hash], ++ [Define to 1 if you want to emit gnu hash in the ELF linker by default.]) ++ ++AC_SUBST(elf_list_options) ++AC_SUBST(elf_shlib_list_options) ++AC_SUBST(elf_plt_unwind_list_options) ++AC_SUBST(EMUL) ++ ++AC_SUBST(TDIRS) ++AM_SUBST_NOTMAKE(TDIRS) ++ ++if test x${all_targets} = xtrue; then ++ if test x${enable_64_bit_bfd} = xyes; then ++ EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)' ++ EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES) $(ALL_64_EMUL_EXTRA_OFILES)' ++ else ++ EMULATION_OFILES='$(ALL_EMULATIONS)' ++ EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES)' ++ fi ++else ++ EMULATION_OFILES=$all_emuls ++ EMUL_EXTRA_OFILES=$all_emul_extras ++fi ++AC_SUBST(EMULATION_OFILES) ++AC_SUBST(EMUL_EXTRA_OFILES) ++AC_SUBST(LIB_PATH) ++ ++EMULATION_LIBPATH=$all_libpath ++AC_SUBST(EMULATION_LIBPATH) ++ ++if test x${enable_static} = xno; then ++ TESTBFDLIB="-Wl,--rpath,../bfd/.libs ../bfd/.libs/libbfd.so" ++ TESTCTFLIB="-Wl,--rpath,../libctf/.libs ../libctf/.libs/libctf.so" ++ TESTSFRAMELIB="-Wl,--rpath,../libsframe/.libs ../libsframe/.libs/libsframe.so" ++else ++ TESTBFDLIB="../bfd/.libs/libbfd.a" ++ TESTCTFLIB="../libctf/.libs/libctf.a" ++ TESTSFRAMELIB="../libsframe/.libs/libsframe.a" ++fi ++if test "${enable_libctf}" = no; then ++ TESTCTFLIB= ++fi ++AC_SUBST(TESTBFDLIB) ++AC_SUBST(TESTCTFLIB) ++AC_SUBST(TESTSFRAMELIB) ++ ++target_vendor=${target_vendor=$host_vendor} ++case "$target_vendor" in ++ hp) EXTRA_SHLIB_EXTENSION=".sl" ;; ++ *) EXTRA_SHLIB_EXTENSION= ;; ++esac ++ ++case "$target_os" in ++ lynxos) EXTRA_SHLIB_EXTENSION=".a" ;; ++esac ++ ++if test x${EXTRA_SHLIB_EXTENSION} != x ; then ++ AC_DEFINE_UNQUOTED(EXTRA_SHLIB_EXTENSION, "$EXTRA_SHLIB_EXTENSION", ++ [Additional extension a shared object might have.]) ++fi ++ ++AC_CONFIG_COMMANDS([default], ++[[ ++case "$srcdir" in ++ .) srcdirpre= ;; ++ *) srcdirpre='$(srcdir)/' ;; ++esac ++POFILES= ++GMOFILES= ++for lang in dummy $OBSOLETE_ALL_LINGUAS; do ++ if test $lang != dummy; then ++ POFILES="$POFILES $srcdirpre$lang.po" ++ GMOFILES="$GMOFILES $srcdirpre$lang.gmo" ++ fi ++done ++sed -e '/^SRC-POTFILES =/r po/SRC-POTFILES' \ ++ -e '/^BLD-POTFILES =/r po/BLD-POTFILES' \ ++ -e "s,@POFILES@,$POFILES," \ ++ -e "s,@GMOFILES@,$GMOFILES," \ ++ po/Makefile.in > po/Makefile]],[[]]) ++ ++dnl Required by html, pdf, install-pdf and install-html ++AC_SUBST(datarootdir) ++AC_SUBST(docdir) ++AC_SUBST(htmldir) ++AC_SUBST(pdfdir) ++ ++AC_CONFIG_FILES(Makefile po/Makefile.in:po/Make-in) ++AC_OUTPUT ++ ++GNU_MAKE_JOBSERVER +diff -rupN binutils.orig/ld/configure.orig binutils-2.41/ld/configure.orig +--- binutils.orig/ld/configure.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/configure.orig 2023-10-19 12:11:39.585932958 +0100 +@@ -0,0 +1,20352 @@ ++#! /bin/sh ++# Guess values for system-dependent variables and create Makefiles. ++# Generated by GNU Autoconf 2.69 for ld 2.41. ++# ++# ++# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. ++# ++# ++# This configure script is free software; the Free Software Foundation ++# gives unlimited permission to copy, distribute and modify it. ++## -------------------- ## ++## M4sh Initialization. ## ++## -------------------- ## ++ ++# Be more Bourne compatible ++DUALCASE=1; export DUALCASE # for MKS sh ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : ++ emulate sh ++ NULLCMD=: ++ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++ setopt NO_GLOB_SUBST ++else ++ case `(set -o) 2>/dev/null` in #( ++ *posix*) : ++ set -o posix ;; #( ++ *) : ++ ;; ++esac ++fi ++ ++ ++as_nl=' ++' ++export as_nl ++# Printing a long string crashes Solaris 7 /usr/bin/printf. ++as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo ++# Prefer a ksh shell builtin over an external printf program on Solaris, ++# but without wasting forks for bash or zsh. ++if test -z "$BASH_VERSION$ZSH_VERSION" \ ++ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='print -r --' ++ as_echo_n='print -rn --' ++elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='printf %s\n' ++ as_echo_n='printf %s' ++else ++ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then ++ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' ++ as_echo_n='/usr/ucb/echo -n' ++ else ++ as_echo_body='eval expr "X$1" : "X\\(.*\\)"' ++ as_echo_n_body='eval ++ arg=$1; ++ case $arg in #( ++ *"$as_nl"*) ++ expr "X$arg" : "X\\(.*\\)$as_nl"; ++ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; ++ esac; ++ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ++ ' ++ export as_echo_n_body ++ as_echo_n='sh -c $as_echo_n_body as_echo' ++ fi ++ export as_echo_body ++ as_echo='sh -c $as_echo_body as_echo' ++fi ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ PATH_SEPARATOR=: ++ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { ++ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || ++ PATH_SEPARATOR=';' ++ } ++fi ++ ++ ++# IFS ++# We need space, tab and new line, in precisely that order. Quoting is ++# there to prevent editors from complaining about space-tab. ++# (If _AS_PATH_WALK were called with IFS unset, it would disable word ++# splitting by setting IFS to empty value.) ++IFS=" "" $as_nl" ++ ++# Find who we are. Look in the path if we contain no directory separator. ++as_myself= ++case $0 in #(( ++ *[\\/]* ) as_myself=$0 ;; ++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++# We did not find ourselves, most probably we were run as `sh COMMAND' ++# in which case we are not to be found in the path. ++if test "x$as_myself" = x; then ++ as_myself=$0 ++fi ++if test ! -f "$as_myself"; then ++ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 ++ exit 1 ++fi ++ ++# Unset variables that we do not need and which cause bugs (e.g. in ++# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" ++# suppresses any "Segmentation fault" message there. '((' could ++# trigger a bug in pdksh 5.2.14. ++for as_var in BASH_ENV ENV MAIL MAILPATH ++do eval test x\${$as_var+set} = xset \ ++ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : ++done ++PS1='$ ' ++PS2='> ' ++PS4='+ ' ++ ++# NLS nuisances. ++LC_ALL=C ++export LC_ALL ++LANGUAGE=C ++export LANGUAGE ++ ++# CDPATH. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++# Use a proper internal environment variable to ensure we don't fall ++ # into an infinite loop, continuously re-executing ourselves. ++ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then ++ _as_can_reexec=no; export _as_can_reexec; ++ # We cannot yet assume a decent shell, so we have to provide a ++# neutralization value for shells without unset; and this also ++# works around shells that cannot unset nonexistent variables. ++# Preserve -v and -x to the replacement shell. ++BASH_ENV=/dev/null ++ENV=/dev/null ++(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV ++case $- in # (((( ++ *v*x* | *x*v* ) as_opts=-vx ;; ++ *v* ) as_opts=-v ;; ++ *x* ) as_opts=-x ;; ++ * ) as_opts= ;; ++esac ++exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} ++# Admittedly, this is quite paranoid, since all the known shells bail ++# out after a failed `exec'. ++$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 ++as_fn_exit 255 ++ fi ++ # We don't want this to propagate to other subprocesses. ++ { _as_can_reexec=; unset _as_can_reexec;} ++if test "x$CONFIG_SHELL" = x; then ++ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : ++ emulate sh ++ NULLCMD=: ++ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '\${1+\"\$@\"}'='\"\$@\"' ++ setopt NO_GLOB_SUBST ++else ++ case \`(set -o) 2>/dev/null\` in #( ++ *posix*) : ++ set -o posix ;; #( ++ *) : ++ ;; ++esac ++fi ++" ++ as_required="as_fn_return () { (exit \$1); } ++as_fn_success () { as_fn_return 0; } ++as_fn_failure () { as_fn_return 1; } ++as_fn_ret_success () { return 0; } ++as_fn_ret_failure () { return 1; } ++ ++exitcode=0 ++as_fn_success || { exitcode=1; echo as_fn_success failed.; } ++as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } ++as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } ++as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } ++if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : ++ ++else ++ exitcode=1; echo positional parameters were not saved. ++fi ++test x\$exitcode = x0 || exit 1 ++test -x / || exit 1" ++ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO ++ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO ++ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && ++ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 ++test \$(( 1 + 1 )) = 2 || exit 1 ++ ++ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ++ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ++ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ++ PATH=/empty FPATH=/empty; export PATH FPATH ++ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ ++ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" ++ if (eval "$as_required") 2>/dev/null; then : ++ as_have_required=yes ++else ++ as_have_required=no ++fi ++ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : ++ ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++as_found=false ++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ as_found=: ++ case $as_dir in #( ++ /*) ++ for as_base in sh bash ksh sh5; do ++ # Try only shells that exist, to save several forks. ++ as_shell=$as_dir/$as_base ++ if { test -f "$as_shell" || test -f "$as_shell.exe"; } && ++ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : ++ CONFIG_SHELL=$as_shell as_have_required=yes ++ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : ++ break 2 ++fi ++fi ++ done;; ++ esac ++ as_found=false ++done ++$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && ++ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : ++ CONFIG_SHELL=$SHELL as_have_required=yes ++fi; } ++IFS=$as_save_IFS ++ ++ ++ if test "x$CONFIG_SHELL" != x; then : ++ export CONFIG_SHELL ++ # We cannot yet assume a decent shell, so we have to provide a ++# neutralization value for shells without unset; and this also ++# works around shells that cannot unset nonexistent variables. ++# Preserve -v and -x to the replacement shell. ++BASH_ENV=/dev/null ++ENV=/dev/null ++(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV ++case $- in # (((( ++ *v*x* | *x*v* ) as_opts=-vx ;; ++ *v* ) as_opts=-v ;; ++ *x* ) as_opts=-x ;; ++ * ) as_opts= ;; ++esac ++exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} ++# Admittedly, this is quite paranoid, since all the known shells bail ++# out after a failed `exec'. ++$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 ++exit 255 ++fi ++ ++ if test x$as_have_required = xno; then : ++ $as_echo "$0: This script requires a shell more modern than all" ++ $as_echo "$0: the shells that I found on your system." ++ if test x${ZSH_VERSION+set} = xset ; then ++ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" ++ $as_echo "$0: be upgraded to zsh 4.3.4 or later." ++ else ++ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, ++$0: including any error possibly output before this ++$0: message. Then install a modern shell, or manually run ++$0: the script under such a shell if you do have one." ++ fi ++ exit 1 ++fi ++fi ++fi ++SHELL=${CONFIG_SHELL-/bin/sh} ++export SHELL ++# Unset more variables known to interfere with behavior of common tools. ++CLICOLOR_FORCE= GREP_OPTIONS= ++unset CLICOLOR_FORCE GREP_OPTIONS ++ ++## --------------------- ## ++## M4sh Shell Functions. ## ++## --------------------- ## ++# as_fn_unset VAR ++# --------------- ++# Portably unset VAR. ++as_fn_unset () ++{ ++ { eval $1=; unset $1;} ++} ++as_unset=as_fn_unset ++ ++# as_fn_set_status STATUS ++# ----------------------- ++# Set $? to STATUS, without forking. ++as_fn_set_status () ++{ ++ return $1 ++} # as_fn_set_status ++ ++# as_fn_exit STATUS ++# ----------------- ++# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. ++as_fn_exit () ++{ ++ set +e ++ as_fn_set_status $1 ++ exit $1 ++} # as_fn_exit ++ ++# as_fn_mkdir_p ++# ------------- ++# Create "$as_dir" as a directory, including parents if necessary. ++as_fn_mkdir_p () ++{ ++ ++ case $as_dir in #( ++ -*) as_dir=./$as_dir;; ++ esac ++ test -d "$as_dir" || eval $as_mkdir_p || { ++ as_dirs= ++ while :; do ++ case $as_dir in #( ++ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( ++ *) as_qdir=$as_dir;; ++ esac ++ as_dirs="'$as_qdir' $as_dirs" ++ as_dir=`$as_dirname -- "$as_dir" || ++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_dir" : 'X\(//\)[^/]' \| \ ++ X"$as_dir" : 'X\(//\)$' \| \ ++ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$as_dir" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ test -d "$as_dir" && break ++ done ++ test -z "$as_dirs" || eval "mkdir $as_dirs" ++ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" ++ ++ ++} # as_fn_mkdir_p ++ ++# as_fn_executable_p FILE ++# ----------------------- ++# Test if FILE is an executable regular file. ++as_fn_executable_p () ++{ ++ test -f "$1" && test -x "$1" ++} # as_fn_executable_p ++# as_fn_append VAR VALUE ++# ---------------------- ++# Append the text in VALUE to the end of the definition contained in VAR. Take ++# advantage of any shell optimizations that allow amortized linear growth over ++# repeated appends, instead of the typical quadratic growth present in naive ++# implementations. ++if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : ++ eval 'as_fn_append () ++ { ++ eval $1+=\$2 ++ }' ++else ++ as_fn_append () ++ { ++ eval $1=\$$1\$2 ++ } ++fi # as_fn_append ++ ++# as_fn_arith ARG... ++# ------------------ ++# Perform arithmetic evaluation on the ARGs, and store the result in the ++# global $as_val. Take advantage of shells that can avoid forks. The arguments ++# must be portable across $(()) and expr. ++if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : ++ eval 'as_fn_arith () ++ { ++ as_val=$(( $* )) ++ }' ++else ++ as_fn_arith () ++ { ++ as_val=`expr "$@" || test $? -eq 1` ++ } ++fi # as_fn_arith ++ ++ ++# as_fn_error STATUS ERROR [LINENO LOG_FD] ++# ---------------------------------------- ++# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are ++# provided, also output the error to LOG_FD, referencing LINENO. Then exit the ++# script with STATUS, using 1 if that was 0. ++as_fn_error () ++{ ++ as_status=$1; test $as_status -eq 0 && as_status=1 ++ if test "$4"; then ++ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 ++ fi ++ $as_echo "$as_me: error: $2" >&2 ++ as_fn_exit $as_status ++} # as_fn_error ++ ++if expr a : '\(a\)' >/dev/null 2>&1 && ++ test "X`expr 00001 : '.*\(...\)'`" = X001; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then ++ as_basename=basename ++else ++ as_basename=false ++fi ++ ++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then ++ as_dirname=dirname ++else ++ as_dirname=false ++fi ++ ++as_me=`$as_basename -- "$0" || ++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ ++ X"$0" : 'X\(//\)$' \| \ ++ X"$0" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X/"$0" | ++ sed '/^.*\/\([^/][^/]*\)\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\/\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\/\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ ++# Avoid depending upon Character Ranges. ++as_cr_letters='abcdefghijklmnopqrstuvwxyz' ++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ++as_cr_Letters=$as_cr_letters$as_cr_LETTERS ++as_cr_digits='0123456789' ++as_cr_alnum=$as_cr_Letters$as_cr_digits ++ ++ ++ as_lineno_1=$LINENO as_lineno_1a=$LINENO ++ as_lineno_2=$LINENO as_lineno_2a=$LINENO ++ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && ++ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { ++ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) ++ sed -n ' ++ p ++ /[$]LINENO/= ++ ' <$as_myself | ++ sed ' ++ s/[$]LINENO.*/&-/ ++ t lineno ++ b ++ :lineno ++ N ++ :loop ++ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ ++ t loop ++ s/-\n.*// ++ ' >$as_me.lineno && ++ chmod +x "$as_me.lineno" || ++ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } ++ ++ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have ++ # already done that, so ensure we don't try to do so again and fall ++ # in an infinite loop. This has already happened in practice. ++ _as_can_reexec=no; export _as_can_reexec ++ # Don't try to exec as it changes $[0], causing all sort of problems ++ # (the dirname of $[0] is not the place where we might find the ++ # original and so on. Autoconf is especially sensitive to this). ++ . "./$as_me.lineno" ++ # Exit status is that of the last command. ++ exit ++} ++ ++ECHO_C= ECHO_N= ECHO_T= ++case `echo -n x` in #((((( ++-n*) ++ case `echo 'xy\c'` in ++ *c*) ECHO_T=' ';; # ECHO_T is single tab character. ++ xy) ECHO_C='\c';; ++ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ++ ECHO_T=' ';; ++ esac;; ++*) ++ ECHO_N='-n';; ++esac ++ ++rm -f conf$$ conf$$.exe conf$$.file ++if test -d conf$$.dir; then ++ rm -f conf$$.dir/conf$$.file ++else ++ rm -f conf$$.dir ++ mkdir conf$$.dir 2>/dev/null ++fi ++if (echo >conf$$.file) 2>/dev/null; then ++ if ln -s conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s='ln -s' ++ # ... but there are two gotchas: ++ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. ++ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. ++ # In both cases, we have to default to `cp -pR'. ++ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ++ as_ln_s='cp -pR' ++ elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++ else ++ as_ln_s='cp -pR' ++ fi ++else ++ as_ln_s='cp -pR' ++fi ++rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file ++rmdir conf$$.dir 2>/dev/null ++ ++if mkdir -p . 2>/dev/null; then ++ as_mkdir_p='mkdir -p "$as_dir"' ++else ++ test -d ./-p && rmdir ./-p ++ as_mkdir_p=false ++fi ++ ++as_test_x='test -x' ++as_executable_p=as_fn_executable_p ++ ++# Sed expression to map a string onto a valid CPP name. ++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" ++ ++# Sed expression to map a string onto a valid variable name. ++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" ++ ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++ ++test -n "$DJDIR" || exec 7<&0 &1 ++ ++# Name of the host. ++# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, ++# so uname gets run too. ++ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` ++ ++# ++# Initializations. ++# ++ac_default_prefix=/usr/local ++ac_clean_files= ++ac_config_libobj_dir=. ++LIBOBJS= ++cross_compiling=no ++subdirs= ++MFLAGS= ++MAKEFLAGS= ++ ++# Identity of this package. ++PACKAGE_NAME='ld' ++PACKAGE_TARNAME='ld' ++PACKAGE_VERSION='2.41' ++PACKAGE_STRING='ld 2.41' ++PACKAGE_BUGREPORT='' ++PACKAGE_URL='' ++ ++ac_unique_file="ldmain.c" ++# Factoring default headers for most tests. ++ac_includes_default="\ ++#include ++#ifdef HAVE_SYS_TYPES_H ++# include ++#endif ++#ifdef HAVE_SYS_STAT_H ++# include ++#endif ++#ifdef STDC_HEADERS ++# include ++# include ++#else ++# ifdef HAVE_STDLIB_H ++# include ++# endif ++#endif ++#ifdef HAVE_STRING_H ++# if !defined STDC_HEADERS && defined HAVE_MEMORY_H ++# include ++# endif ++# include ++#endif ++#ifdef HAVE_STRINGS_H ++# include ++#endif ++#ifdef HAVE_INTTYPES_H ++# include ++#endif ++#ifdef HAVE_STDINT_H ++# include ++#endif ++#ifdef HAVE_UNISTD_H ++# include ++#endif" ++ ++ac_header_list= ++ac_subst_vars='am__EXEEXT_FALSE ++am__EXEEXT_TRUE ++LTLIBOBJS ++LIBOBJS ++TESTSFRAMELIB ++TESTCTFLIB ++TESTBFDLIB ++EMULATION_LIBPATH ++LIB_PATH ++EMUL_EXTRA_OFILES ++EMULATION_OFILES ++TDIRS ++EMUL ++elf_plt_unwind_list_options ++elf_shlib_list_options ++elf_list_options ++STRINGIFY ++ZSTD_LIBS ++ZSTD_CFLAGS ++zlibinc ++zlibdir ++NATIVE_LIB_DIRS ++HDEFINES ++do_compare ++GENINSRC_NEVER_FALSE ++GENINSRC_NEVER_TRUE ++LEXLIB ++LEX_OUTPUT_ROOT ++LEX ++YFLAGS ++YACC ++MSGMERGE ++MSGFMT ++MKINSTALLDIRS ++CATOBJEXT ++GENCAT ++INSTOBJEXT ++DATADIRNAME ++CATALOGS ++POSUB ++GMSGFMT ++XGETTEXT ++INCINTL ++LIBINTL_DEP ++LIBINTL ++USE_NLS ++WARN_WRITE_STRINGS ++NO_WERROR ++WARN_CFLAGS_FOR_BUILD ++WARN_CFLAGS ++JANSSON_LIBS ++JANSSON_CFLAGS ++enable_libctf ++ENABLE_LIBCTF_FALSE ++ENABLE_LIBCTF_TRUE ++enable_initfini_array ++installed_linker ++install_as_default ++TARGET_SYSTEM_ROOT_DEFINE ++TARGET_SYSTEM_ROOT ++use_sysroot ++ENABLE_BFD_64_BIT_FALSE ++ENABLE_BFD_64_BIT_TRUE ++LARGEFILE_CPPFLAGS ++CXXCPP ++OTOOL64 ++OTOOL ++LIPO ++NMEDIT ++DSYMUTIL ++RANLIB ++AR ++OBJDUMP ++LN_S ++NM ++ac_ct_DUMPBIN ++DUMPBIN ++LD ++FGREP ++SED ++LIBTOOL ++PKG_CONFIG_LIBDIR ++PKG_CONFIG_PATH ++PKG_CONFIG ++EGREP ++CPP ++GREP ++am__fastdepCXX_FALSE ++am__fastdepCXX_TRUE ++CXXDEPMODE ++ac_ct_CXX ++CXXFLAGS ++CXX ++am__fastdepCC_FALSE ++am__fastdepCC_TRUE ++CCDEPMODE ++am__nodep ++AMDEPBACKSLASH ++AMDEP_FALSE ++AMDEP_TRUE ++am__quote ++am__include ++DEPDIR ++OBJEXT ++EXEEXT ++ac_ct_CC ++CPPFLAGS ++LDFLAGS ++CFLAGS ++CC ++MAINT ++MAINTAINER_MODE_FALSE ++MAINTAINER_MODE_TRUE ++AM_BACKSLASH ++AM_DEFAULT_VERBOSITY ++AM_DEFAULT_V ++AM_V ++am__untar ++am__tar ++AMTAR ++am__leading_dot ++SET_MAKE ++AWK ++mkdir_p ++MKDIR_P ++INSTALL_STRIP_PROGRAM ++STRIP ++install_sh ++MAKEINFO ++AUTOHEADER ++AUTOMAKE ++AUTOCONF ++ACLOCAL ++VERSION ++PACKAGE ++CYGPATH_W ++am__isrc ++INSTALL_DATA ++INSTALL_SCRIPT ++INSTALL_PROGRAM ++target_os ++target_vendor ++target_cpu ++target ++host_os ++host_vendor ++host_cpu ++host ++build_os ++build_vendor ++build_cpu ++build ++target_alias ++host_alias ++build_alias ++LIBS ++ECHO_T ++ECHO_N ++ECHO_C ++DEFS ++mandir ++localedir ++libdir ++psdir ++pdfdir ++dvidir ++htmldir ++infodir ++docdir ++oldincludedir ++includedir ++localstatedir ++sharedstatedir ++sysconfdir ++datadir ++datarootdir ++libexecdir ++sbindir ++bindir ++program_transform_name ++prefix ++exec_prefix ++PACKAGE_URL ++PACKAGE_BUGREPORT ++PACKAGE_STRING ++PACKAGE_VERSION ++PACKAGE_TARNAME ++PACKAGE_NAME ++PATH_SEPARATOR ++SHELL' ++ac_subst_files='' ++ac_user_opts=' ++enable_option_checking ++enable_silent_rules ++enable_maintainer_mode ++enable_dependency_tracking ++enable_shared ++enable_static ++with_pic ++enable_fast_install ++with_gnu_ld ++enable_libtool_lock ++enable_plugins ++enable_largefile ++enable_checking ++with_lib_path ++enable_targets ++enable_64_bit_bfd ++with_sysroot ++enable_gold ++enable_got ++enable_compressed_debug_sections ++enable_default_compressed_debug_sections_algorithm ++enable_new_dtags ++enable_relro ++enable_textrel_check ++enable_separate_code ++enable_warn_execstack ++enable_warn_rwx_segments ++enable_default_execstack ++enable_error_handling_script ++enable_default_hash_style ++enable_initfini_array ++enable_libctf ++enable_jansson ++enable_werror ++enable_build_warnings ++enable_nls ++with_system_zlib ++with_zstd ++' ++ ac_precious_vars='build_alias ++host_alias ++target_alias ++CC ++CFLAGS ++LDFLAGS ++LIBS ++CPPFLAGS ++CXX ++CXXFLAGS ++CCC ++CPP ++PKG_CONFIG ++PKG_CONFIG_PATH ++PKG_CONFIG_LIBDIR ++CXXCPP ++JANSSON_CFLAGS ++JANSSON_LIBS ++YACC ++YFLAGS ++ZSTD_CFLAGS ++ZSTD_LIBS' ++ ++ ++# Initialize some variables set by options. ++ac_init_help= ++ac_init_version=false ++ac_unrecognized_opts= ++ac_unrecognized_sep= ++# The variables have the same names as the options, with ++# dashes changed to underlines. ++cache_file=/dev/null ++exec_prefix=NONE ++no_create= ++no_recursion= ++prefix=NONE ++program_prefix=NONE ++program_suffix=NONE ++program_transform_name=s,x,x, ++silent= ++site= ++srcdir= ++verbose= ++x_includes=NONE ++x_libraries=NONE ++ ++# Installation directory options. ++# These are left unexpanded so users can "make install exec_prefix=/foo" ++# and all the variables that are supposed to be based on exec_prefix ++# by default will actually change. ++# Use braces instead of parens because sh, perl, etc. also accept them. ++# (The list follows the same order as the GNU Coding Standards.) ++bindir='${exec_prefix}/bin' ++sbindir='${exec_prefix}/sbin' ++libexecdir='${exec_prefix}/libexec' ++datarootdir='${prefix}/share' ++datadir='${datarootdir}' ++sysconfdir='${prefix}/etc' ++sharedstatedir='${prefix}/com' ++localstatedir='${prefix}/var' ++includedir='${prefix}/include' ++oldincludedir='/usr/include' ++docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' ++infodir='${datarootdir}/info' ++htmldir='${docdir}' ++dvidir='${docdir}' ++pdfdir='${docdir}' ++psdir='${docdir}' ++libdir='${exec_prefix}/lib' ++localedir='${datarootdir}/locale' ++mandir='${datarootdir}/man' ++ ++ac_prev= ++ac_dashdash= ++for ac_option ++do ++ # If the previous option needs an argument, assign it. ++ if test -n "$ac_prev"; then ++ eval $ac_prev=\$ac_option ++ ac_prev= ++ continue ++ fi ++ ++ case $ac_option in ++ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; ++ *=) ac_optarg= ;; ++ *) ac_optarg=yes ;; ++ esac ++ ++ # Accept the important Cygnus configure options, so we can diagnose typos. ++ ++ case $ac_dashdash$ac_option in ++ --) ++ ac_dashdash=yes ;; ++ ++ -bindir | --bindir | --bindi | --bind | --bin | --bi) ++ ac_prev=bindir ;; ++ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) ++ bindir=$ac_optarg ;; ++ ++ -build | --build | --buil | --bui | --bu) ++ ac_prev=build_alias ;; ++ -build=* | --build=* | --buil=* | --bui=* | --bu=*) ++ build_alias=$ac_optarg ;; ++ ++ -cache-file | --cache-file | --cache-fil | --cache-fi \ ++ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ++ ac_prev=cache_file ;; ++ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ ++ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) ++ cache_file=$ac_optarg ;; ++ ++ --config-cache | -C) ++ cache_file=config.cache ;; ++ ++ -datadir | --datadir | --datadi | --datad) ++ ac_prev=datadir ;; ++ -datadir=* | --datadir=* | --datadi=* | --datad=*) ++ datadir=$ac_optarg ;; ++ ++ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ ++ | --dataroo | --dataro | --datar) ++ ac_prev=datarootdir ;; ++ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ ++ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) ++ datarootdir=$ac_optarg ;; ++ ++ -disable-* | --disable-*) ++ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ as_fn_error $? "invalid feature name: $ac_useropt" ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"enable_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval enable_$ac_useropt=no ;; ++ ++ -docdir | --docdir | --docdi | --doc | --do) ++ ac_prev=docdir ;; ++ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) ++ docdir=$ac_optarg ;; ++ ++ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ++ ac_prev=dvidir ;; ++ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) ++ dvidir=$ac_optarg ;; ++ ++ -enable-* | --enable-*) ++ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ as_fn_error $? "invalid feature name: $ac_useropt" ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"enable_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval enable_$ac_useropt=\$ac_optarg ;; ++ ++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ ++ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ ++ | --exec | --exe | --ex) ++ ac_prev=exec_prefix ;; ++ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ ++ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ ++ | --exec=* | --exe=* | --ex=*) ++ exec_prefix=$ac_optarg ;; ++ ++ -gas | --gas | --ga | --g) ++ # Obsolete; use --with-gas. ++ with_gas=yes ;; ++ ++ -help | --help | --hel | --he | -h) ++ ac_init_help=long ;; ++ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ++ ac_init_help=recursive ;; ++ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ++ ac_init_help=short ;; ++ ++ -host | --host | --hos | --ho) ++ ac_prev=host_alias ;; ++ -host=* | --host=* | --hos=* | --ho=*) ++ host_alias=$ac_optarg ;; ++ ++ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ++ ac_prev=htmldir ;; ++ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ ++ | --ht=*) ++ htmldir=$ac_optarg ;; ++ ++ -includedir | --includedir | --includedi | --included | --include \ ++ | --includ | --inclu | --incl | --inc) ++ ac_prev=includedir ;; ++ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ ++ | --includ=* | --inclu=* | --incl=* | --inc=*) ++ includedir=$ac_optarg ;; ++ ++ -infodir | --infodir | --infodi | --infod | --info | --inf) ++ ac_prev=infodir ;; ++ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) ++ infodir=$ac_optarg ;; ++ ++ -libdir | --libdir | --libdi | --libd) ++ ac_prev=libdir ;; ++ -libdir=* | --libdir=* | --libdi=* | --libd=*) ++ libdir=$ac_optarg ;; ++ ++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ ++ | --libexe | --libex | --libe) ++ ac_prev=libexecdir ;; ++ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ ++ | --libexe=* | --libex=* | --libe=*) ++ libexecdir=$ac_optarg ;; ++ ++ -localedir | --localedir | --localedi | --localed | --locale) ++ ac_prev=localedir ;; ++ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) ++ localedir=$ac_optarg ;; ++ ++ -localstatedir | --localstatedir | --localstatedi | --localstated \ ++ | --localstate | --localstat | --localsta | --localst | --locals) ++ ac_prev=localstatedir ;; ++ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ ++ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) ++ localstatedir=$ac_optarg ;; ++ ++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ++ ac_prev=mandir ;; ++ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) ++ mandir=$ac_optarg ;; ++ ++ -nfp | --nfp | --nf) ++ # Obsolete; use --without-fp. ++ with_fp=no ;; ++ ++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \ ++ | --no-cr | --no-c | -n) ++ no_create=yes ;; ++ ++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \ ++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ++ no_recursion=yes ;; ++ ++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ ++ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ ++ | --oldin | --oldi | --old | --ol | --o) ++ ac_prev=oldincludedir ;; ++ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ ++ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ ++ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) ++ oldincludedir=$ac_optarg ;; ++ ++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ++ ac_prev=prefix ;; ++ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ++ prefix=$ac_optarg ;; ++ ++ -program-prefix | --program-prefix | --program-prefi | --program-pref \ ++ | --program-pre | --program-pr | --program-p) ++ ac_prev=program_prefix ;; ++ -program-prefix=* | --program-prefix=* | --program-prefi=* \ ++ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) ++ program_prefix=$ac_optarg ;; ++ ++ -program-suffix | --program-suffix | --program-suffi | --program-suff \ ++ | --program-suf | --program-su | --program-s) ++ ac_prev=program_suffix ;; ++ -program-suffix=* | --program-suffix=* | --program-suffi=* \ ++ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) ++ program_suffix=$ac_optarg ;; ++ ++ -program-transform-name | --program-transform-name \ ++ | --program-transform-nam | --program-transform-na \ ++ | --program-transform-n | --program-transform- \ ++ | --program-transform | --program-transfor \ ++ | --program-transfo | --program-transf \ ++ | --program-trans | --program-tran \ ++ | --progr-tra | --program-tr | --program-t) ++ ac_prev=program_transform_name ;; ++ -program-transform-name=* | --program-transform-name=* \ ++ | --program-transform-nam=* | --program-transform-na=* \ ++ | --program-transform-n=* | --program-transform-=* \ ++ | --program-transform=* | --program-transfor=* \ ++ | --program-transfo=* | --program-transf=* \ ++ | --program-trans=* | --program-tran=* \ ++ | --progr-tra=* | --program-tr=* | --program-t=*) ++ program_transform_name=$ac_optarg ;; ++ ++ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ++ ac_prev=pdfdir ;; ++ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) ++ pdfdir=$ac_optarg ;; ++ ++ -psdir | --psdir | --psdi | --psd | --ps) ++ ac_prev=psdir ;; ++ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) ++ psdir=$ac_optarg ;; ++ ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil) ++ silent=yes ;; ++ ++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ++ ac_prev=sbindir ;; ++ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ ++ | --sbi=* | --sb=*) ++ sbindir=$ac_optarg ;; ++ ++ -sharedstatedir | --sharedstatedir | --sharedstatedi \ ++ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ ++ | --sharedst | --shareds | --shared | --share | --shar \ ++ | --sha | --sh) ++ ac_prev=sharedstatedir ;; ++ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ ++ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ ++ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ ++ | --sha=* | --sh=*) ++ sharedstatedir=$ac_optarg ;; ++ ++ -site | --site | --sit) ++ ac_prev=site ;; ++ -site=* | --site=* | --sit=*) ++ site=$ac_optarg ;; ++ ++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ++ ac_prev=srcdir ;; ++ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ++ srcdir=$ac_optarg ;; ++ ++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ ++ | --syscon | --sysco | --sysc | --sys | --sy) ++ ac_prev=sysconfdir ;; ++ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ ++ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) ++ sysconfdir=$ac_optarg ;; ++ ++ -target | --target | --targe | --targ | --tar | --ta | --t) ++ ac_prev=target_alias ;; ++ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) ++ target_alias=$ac_optarg ;; ++ ++ -v | -verbose | --verbose | --verbos | --verbo | --verb) ++ verbose=yes ;; ++ ++ -version | --version | --versio | --versi | --vers | -V) ++ ac_init_version=: ;; ++ ++ -with-* | --with-*) ++ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ as_fn_error $? "invalid package name: $ac_useropt" ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"with_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval with_$ac_useropt=\$ac_optarg ;; ++ ++ -without-* | --without-*) ++ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ as_fn_error $? "invalid package name: $ac_useropt" ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"with_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval with_$ac_useropt=no ;; ++ ++ --x) ++ # Obsolete; use --with-x. ++ with_x=yes ;; ++ ++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ ++ | --x-incl | --x-inc | --x-in | --x-i) ++ ac_prev=x_includes ;; ++ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ ++ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) ++ x_includes=$ac_optarg ;; ++ ++ -x-libraries | --x-libraries | --x-librarie | --x-librari \ ++ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ++ ac_prev=x_libraries ;; ++ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ ++ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) ++ x_libraries=$ac_optarg ;; ++ ++ -*) as_fn_error $? "unrecognized option: \`$ac_option' ++Try \`$0 --help' for more information" ++ ;; ++ ++ *=*) ++ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` ++ # Reject names that are not valid shell variable names. ++ case $ac_envvar in #( ++ '' | [0-9]* | *[!_$as_cr_alnum]* ) ++ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; ++ esac ++ eval $ac_envvar=\$ac_optarg ++ export $ac_envvar ;; ++ ++ *) ++ # FIXME: should be removed in autoconf 3.0. ++ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 ++ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && ++ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 ++ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ++ ;; ++ ++ esac ++done ++ ++if test -n "$ac_prev"; then ++ ac_option=--`echo $ac_prev | sed 's/_/-/g'` ++ as_fn_error $? "missing argument to $ac_option" ++fi ++ ++if test -n "$ac_unrecognized_opts"; then ++ case $enable_option_checking in ++ no) ;; ++ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; ++ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; ++ esac ++fi ++ ++# Check all directory arguments for consistency. ++for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ ++ datadir sysconfdir sharedstatedir localstatedir includedir \ ++ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ ++ libdir localedir mandir ++do ++ eval ac_val=\$$ac_var ++ # Remove trailing slashes. ++ case $ac_val in ++ */ ) ++ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` ++ eval $ac_var=\$ac_val;; ++ esac ++ # Be sure to have absolute directory names. ++ case $ac_val in ++ [\\/$]* | ?:[\\/]* ) continue;; ++ NONE | '' ) case $ac_var in *prefix ) continue;; esac;; ++ esac ++ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" ++done ++ ++# There might be people who depend on the old broken behavior: `$host' ++# used to hold the argument of --host etc. ++# FIXME: To remove some day. ++build=$build_alias ++host=$host_alias ++target=$target_alias ++ ++# FIXME: To remove some day. ++if test "x$host_alias" != x; then ++ if test "x$build_alias" = x; then ++ cross_compiling=maybe ++ elif test "x$build_alias" != "x$host_alias"; then ++ cross_compiling=yes ++ fi ++fi ++ ++ac_tool_prefix= ++test -n "$host_alias" && ac_tool_prefix=$host_alias- ++ ++test "$silent" = yes && exec 6>/dev/null ++ ++ ++ac_pwd=`pwd` && test -n "$ac_pwd" && ++ac_ls_di=`ls -di .` && ++ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || ++ as_fn_error $? "working directory cannot be determined" ++test "X$ac_ls_di" = "X$ac_pwd_ls_di" || ++ as_fn_error $? "pwd does not report name of working directory" ++ ++ ++# Find the source files, if location was not specified. ++if test -z "$srcdir"; then ++ ac_srcdir_defaulted=yes ++ # Try the directory containing this script, then the parent directory. ++ ac_confdir=`$as_dirname -- "$as_myself" || ++$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_myself" : 'X\(//\)[^/]' \| \ ++ X"$as_myself" : 'X\(//\)$' \| \ ++ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$as_myself" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ srcdir=$ac_confdir ++ if test ! -r "$srcdir/$ac_unique_file"; then ++ srcdir=.. ++ fi ++else ++ ac_srcdir_defaulted=no ++fi ++if test ! -r "$srcdir/$ac_unique_file"; then ++ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." ++ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" ++fi ++ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ++ac_abs_confdir=`( ++ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" ++ pwd)` ++# When building in place, set srcdir=. ++if test "$ac_abs_confdir" = "$ac_pwd"; then ++ srcdir=. ++fi ++# Remove unnecessary trailing slashes from srcdir. ++# Double slashes in file names in object file debugging info ++# mess up M-x gdb in Emacs. ++case $srcdir in ++*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; ++esac ++for ac_var in $ac_precious_vars; do ++ eval ac_env_${ac_var}_set=\${${ac_var}+set} ++ eval ac_env_${ac_var}_value=\$${ac_var} ++ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} ++ eval ac_cv_env_${ac_var}_value=\$${ac_var} ++done ++ ++# ++# Report the --help message. ++# ++if test "$ac_init_help" = "long"; then ++ # Omit some internal or obsolete options to make the list less imposing. ++ # This message is too long to be a string in the A/UX 3.1 sh. ++ cat <<_ACEOF ++\`configure' configures ld 2.41 to adapt to many kinds of systems. ++ ++Usage: $0 [OPTION]... [VAR=VALUE]... ++ ++To assign environment variables (e.g., CC, CFLAGS...), specify them as ++VAR=VALUE. See below for descriptions of some of the useful variables. ++ ++Defaults for the options are specified in brackets. ++ ++Configuration: ++ -h, --help display this help and exit ++ --help=short display options specific to this package ++ --help=recursive display the short help of all the included packages ++ -V, --version display version information and exit ++ -q, --quiet, --silent do not print \`checking ...' messages ++ --cache-file=FILE cache test results in FILE [disabled] ++ -C, --config-cache alias for \`--cache-file=config.cache' ++ -n, --no-create do not create output files ++ --srcdir=DIR find the sources in DIR [configure dir or \`..'] ++ ++Installation directories: ++ --prefix=PREFIX install architecture-independent files in PREFIX ++ [$ac_default_prefix] ++ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX ++ [PREFIX] ++ ++By default, \`make install' will install all the files in ++\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify ++an installation prefix other than \`$ac_default_prefix' using \`--prefix', ++for instance \`--prefix=\$HOME'. ++ ++For better control, use the options below. ++ ++Fine tuning of the installation directories: ++ --bindir=DIR user executables [EPREFIX/bin] ++ --sbindir=DIR system admin executables [EPREFIX/sbin] ++ --libexecdir=DIR program executables [EPREFIX/libexec] ++ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] ++ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] ++ --localstatedir=DIR modifiable single-machine data [PREFIX/var] ++ --libdir=DIR object code libraries [EPREFIX/lib] ++ --includedir=DIR C header files [PREFIX/include] ++ --oldincludedir=DIR C header files for non-gcc [/usr/include] ++ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] ++ --datadir=DIR read-only architecture-independent data [DATAROOTDIR] ++ --infodir=DIR info documentation [DATAROOTDIR/info] ++ --localedir=DIR locale-dependent data [DATAROOTDIR/locale] ++ --mandir=DIR man documentation [DATAROOTDIR/man] ++ --docdir=DIR documentation root [DATAROOTDIR/doc/ld] ++ --htmldir=DIR html documentation [DOCDIR] ++ --dvidir=DIR dvi documentation [DOCDIR] ++ --pdfdir=DIR pdf documentation [DOCDIR] ++ --psdir=DIR ps documentation [DOCDIR] ++_ACEOF ++ ++ cat <<\_ACEOF ++ ++Program names: ++ --program-prefix=PREFIX prepend PREFIX to installed program names ++ --program-suffix=SUFFIX append SUFFIX to installed program names ++ --program-transform-name=PROGRAM run sed PROGRAM on installed program names ++ ++System types: ++ --build=BUILD configure for building on BUILD [guessed] ++ --host=HOST cross-compile to build programs to run on HOST [BUILD] ++ --target=TARGET configure for building compilers for TARGET [HOST] ++_ACEOF ++fi ++ ++if test -n "$ac_init_help"; then ++ case $ac_init_help in ++ short | recursive ) echo "Configuration of ld 2.41:";; ++ esac ++ cat <<\_ACEOF ++ ++Optional Features: ++ --disable-option-checking ignore unrecognized --enable/--with options ++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) ++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] ++ --enable-silent-rules less verbose build output (undo: "make V=1") ++ --disable-silent-rules verbose build output (undo: "make V=0") ++ --enable-maintainer-mode ++ enable make rules and dependencies not useful (and ++ sometimes confusing) to the casual installer ++ --enable-dependency-tracking ++ do not reject slow dependency extractors ++ --disable-dependency-tracking ++ speeds up one-time build ++ --enable-shared[=PKGS] build shared libraries [default=yes] ++ --enable-static[=PKGS] build static libraries [default=yes] ++ --enable-fast-install[=PKGS] ++ optimize for fast installation [default=yes] ++ --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-plugins Enable support for plugins ++ --disable-largefile omit support for large files ++ --enable-checking enable run-time checks ++ --enable-targets alternative target configurations ++ --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) ++ --enable-gold[=ARG] build gold [ARG={default,yes,no}] ++ --enable-got= GOT handling scheme (target, single, negative, ++ multigot) ++ --enable-compressed-debug-sections={all,ld,none} ++ compress debug sections by default] ++ --enable-default-compressed-debug-sections-algorithm={zlib,zstd} ++ Default compression algorithm for ++ --enable-compressed-debug-sections. ++ --enable-new-dtags set DT_RUNPATH instead of DT_RPATH by default] ++ --enable-relro enable -z relro in ELF linker by default ++ --enable-textrel-check=[yes|no|warning|error] ++ enable DT_TEXTREL check in ELF linker ++ --enable-separate-code enable -z separate-code in ELF linker by default ++ --enable-warn-execstack enable warnings when creating an executable stack ++ --enable-warn-rwx-segments ++ enable warnings when creating segements with RWX ++ permissions ++ --enable-default-execstack ++ create an executable stack if an input file is ++ missing a .note.GNU-stack section ++ --enable-error-handling-script ++ enable/disable support for the ++ --error-handling-script option ++ --enable-default-hash-style={sysv,gnu,both} ++ use this default hash style ++ --disable-initfini-array do not use .init_array/.fini_array sections ++ --enable-libctf Handle .ctf type-info sections [default=yes] ++ --enable-jansson enable jansson [default=no] ++ --enable-werror treat compile warnings as errors ++ --enable-build-warnings enable build-time compiler warnings ++ --disable-nls do not use Native Language Support ++ ++Optional Packages: ++ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] ++ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) ++ --with-pic try to use only PIC/non-PIC objects [default=use ++ both] ++ --with-gnu-ld assume the C compiler uses GNU ld [default=no] ++ --with-lib-path=dir1:dir2... set default LIB_PATH ++ --with-sysroot=DIR Search for usr/lib et al within DIR. ++ --with-system-zlib use installed libz ++ --with-zstd support zstd compressed debug sections ++ (default=auto) ++ ++Some influential environment variables: ++ CC C compiler command ++ CFLAGS C compiler flags ++ LDFLAGS linker flags, e.g. -L if you have libraries in a ++ nonstandard directory ++ LIBS libraries to pass to the linker, e.g. -l ++ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if ++ you have headers in a nonstandard directory ++ CXX C++ compiler command ++ CXXFLAGS C++ compiler flags ++ CPP C preprocessor ++ PKG_CONFIG path to pkg-config utility ++ PKG_CONFIG_PATH ++ directories to add to pkg-config's search path ++ PKG_CONFIG_LIBDIR ++ path overriding pkg-config's built-in search path ++ CXXCPP C++ preprocessor ++ JANSSON_CFLAGS ++ C compiler flags for JANSSON, overriding pkg-config ++ JANSSON_LIBS ++ linker flags for JANSSON, overriding pkg-config ++ YACC The `Yet Another Compiler Compiler' implementation to use. ++ Defaults to the first program found out of: `bison -y', `byacc', ++ `yacc'. ++ YFLAGS The list of arguments that will be passed by default to $YACC. ++ This script will default YFLAGS to the empty string to avoid a ++ default value of `-d' given by some make applications. ++ ZSTD_CFLAGS C compiler flags for ZSTD, overriding pkg-config ++ ZSTD_LIBS linker flags for ZSTD, overriding pkg-config ++ ++Use these variables to override the choices made by `configure' or to help ++it to find libraries and programs with nonstandard names/locations. ++ ++Report bugs to the package provider. ++_ACEOF ++ac_status=$? ++fi ++ ++if test "$ac_init_help" = "recursive"; then ++ # If there are subdirs, report their specific --help. ++ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue ++ test -d "$ac_dir" || ++ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || ++ continue ++ ac_builddir=. ++ ++case "$ac_dir" in ++.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; ++*) ++ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` ++ # A ".." for each directory in $ac_dir_suffix. ++ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` ++ case $ac_top_builddir_sub in ++ "") ac_top_builddir_sub=. ac_top_build_prefix= ;; ++ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; ++ esac ;; ++esac ++ac_abs_top_builddir=$ac_pwd ++ac_abs_builddir=$ac_pwd$ac_dir_suffix ++# for backward compatibility: ++ac_top_builddir=$ac_top_build_prefix ++ ++case $srcdir in ++ .) # We are building in place. ++ ac_srcdir=. ++ ac_top_srcdir=$ac_top_builddir_sub ++ ac_abs_top_srcdir=$ac_pwd ;; ++ [\\/]* | ?:[\\/]* ) # Absolute name. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ++ ac_abs_top_srcdir=$srcdir ;; ++ *) # Relative name. ++ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_build_prefix$srcdir ++ ac_abs_top_srcdir=$ac_pwd/$srcdir ;; ++esac ++ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix ++ ++ cd "$ac_dir" || { ac_status=$?; continue; } ++ # Check for guested configure. ++ if test -f "$ac_srcdir/configure.gnu"; then ++ echo && ++ $SHELL "$ac_srcdir/configure.gnu" --help=recursive ++ elif test -f "$ac_srcdir/configure"; then ++ echo && ++ $SHELL "$ac_srcdir/configure" --help=recursive ++ else ++ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 ++ fi || ac_status=$? ++ cd "$ac_pwd" || { ac_status=$?; break; } ++ done ++fi ++ ++test -n "$ac_init_help" && exit $ac_status ++if $ac_init_version; then ++ cat <<\_ACEOF ++ld configure 2.41 ++generated by GNU Autoconf 2.69 ++ ++Copyright (C) 2012 Free Software Foundation, Inc. ++This configure script is free software; the Free Software Foundation ++gives unlimited permission to copy, distribute and modify it. ++_ACEOF ++ exit ++fi ++ ++## ------------------------ ## ++## Autoconf initialization. ## ++## ------------------------ ## ++ ++# ac_fn_c_try_compile LINENO ++# -------------------------- ++# Try to compile conftest.$ac_ext, and return whether this succeeded. ++ac_fn_c_try_compile () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ rm -f conftest.$ac_objext ++ if { { ac_try="$ac_compile" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_compile") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest.$ac_objext; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_compile ++ ++# ac_fn_cxx_try_compile LINENO ++# ---------------------------- ++# Try to compile conftest.$ac_ext, and return whether this succeeded. ++ac_fn_cxx_try_compile () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ rm -f conftest.$ac_objext ++ if { { ac_try="$ac_compile" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_compile") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++ test -z "$ac_cxx_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest.$ac_objext; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_cxx_try_compile ++ ++# ac_fn_c_try_cpp LINENO ++# ---------------------- ++# Try to preprocess conftest.$ac_ext, and return whether this succeeded. ++ac_fn_c_try_cpp () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { { ac_try="$ac_cpp conftest.$ac_ext" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } > conftest.i && { ++ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || ++ test ! -s conftest.err ++ }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_cpp ++ ++# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES ++# ------------------------------------------------------- ++# Tests whether HEADER exists, giving a warning if it cannot be compiled using ++# the include files in INCLUDES and setting the cache variable VAR ++# accordingly. ++ac_fn_c_check_header_mongrel () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if eval \${$3+:} false; then : ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++else ++ # Is the header compilable? ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 ++$as_echo_n "checking $2 usability... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++#include <$2> ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_header_compiler=yes ++else ++ ac_header_compiler=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 ++$as_echo "$ac_header_compiler" >&6; } ++ ++# Is the header present? ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 ++$as_echo_n "checking $2 presence... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include <$2> ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ac_header_preproc=yes ++else ++ ac_header_preproc=no ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 ++$as_echo "$ac_header_preproc" >&6; } ++ ++# So? What about this header? ++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( ++ yes:no: ) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 ++$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 ++$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ++ ;; ++ no:yes:* ) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 ++$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 ++$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 ++$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 ++$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 ++$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ++ ;; ++esac ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ eval "$3=\$ac_header_compiler" ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++fi ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_header_mongrel ++ ++# ac_fn_c_try_run LINENO ++# ---------------------- ++# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes ++# that executables *can* be run. ++ac_fn_c_try_run () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' ++ { { case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_try") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: program exited with status $ac_status" >&5 ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=$ac_status ++fi ++ rm -rf conftest.dSYM conftest_ipa8_conftest.oo ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_run ++ ++# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES ++# ------------------------------------------------------- ++# Tests whether HEADER exists and can be compiled using the include files in ++# INCLUDES, setting the cache variable VAR accordingly. ++ac_fn_c_check_header_compile () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++#include <$2> ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_header_compile ++ ++# ac_fn_c_try_link LINENO ++# ----------------------- ++# Try to link conftest.$ac_ext, and return whether this succeeded. ++ac_fn_c_try_link () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ rm -f conftest.$ac_objext conftest$ac_exeext ++ if { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ test -x conftest$ac_exeext ++ }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information ++ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would ++ # interfere with the next link command; also delete a directory that is ++ # left behind by Apple's compiler. We do this before executing the actions. ++ rm -rf conftest.dSYM conftest_ipa8_conftest.oo ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_link ++ ++# ac_fn_c_check_func LINENO FUNC VAR ++# ---------------------------------- ++# Tests whether FUNC exists, setting the cache variable VAR accordingly ++ac_fn_c_check_func () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++/* Define $2 to an innocuous variant, in case declares $2. ++ For example, HP-UX 11i declares gettimeofday. */ ++#define $2 innocuous_$2 ++ ++/* System header to define __stub macros and hopefully few prototypes, ++ which can conflict with char $2 (); below. ++ Prefer to if __STDC__ is defined, since ++ exists even on freestanding compilers. */ ++ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ ++#undef $2 ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char $2 (); ++/* The GNU C library defines this for functions which it implements ++ to always fail with ENOSYS. Some functions are actually named ++ something starting with __ and the normal name is an alias. */ ++#if defined __stub_$2 || defined __stub___$2 ++choke me ++#endif ++ ++int ++main () ++{ ++return $2 (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_func ++ ++# ac_fn_cxx_try_cpp LINENO ++# ------------------------ ++# Try to preprocess conftest.$ac_ext, and return whether this succeeded. ++ac_fn_cxx_try_cpp () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { { ac_try="$ac_cpp conftest.$ac_ext" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } > conftest.i && { ++ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || ++ test ! -s conftest.err ++ }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_cxx_try_cpp ++ ++# ac_fn_cxx_try_link LINENO ++# ------------------------- ++# Try to link conftest.$ac_ext, and return whether this succeeded. ++ac_fn_cxx_try_link () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ rm -f conftest.$ac_objext conftest$ac_exeext ++ if { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++ test -z "$ac_cxx_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ test -x conftest$ac_exeext ++ }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information ++ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would ++ # interfere with the next link command; also delete a directory that is ++ # left behind by Apple's compiler. We do this before executing the actions. ++ rm -rf conftest.dSYM conftest_ipa8_conftest.oo ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_cxx_try_link ++ ++# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES ++# -------------------------------------------- ++# Tries to find the compile-time value of EXPR in a program that includes ++# INCLUDES, setting VAR accordingly. Returns whether the value could be ++# computed ++ac_fn_c_compute_int () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if test "$cross_compiling" = yes; then ++ # Depending upon the size, compute the lo and hi bounds. ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++int ++main () ++{ ++static int test_array [1 - 2 * !(($2) >= 0)]; ++test_array [0] = 0; ++return test_array [0]; ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_lo=0 ac_mid=0 ++ while :; do ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++int ++main () ++{ ++static int test_array [1 - 2 * !(($2) <= $ac_mid)]; ++test_array [0] = 0; ++return test_array [0]; ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_hi=$ac_mid; break ++else ++ as_fn_arith $ac_mid + 1 && ac_lo=$as_val ++ if test $ac_lo -le $ac_mid; then ++ ac_lo= ac_hi= ++ break ++ fi ++ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ done ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++int ++main () ++{ ++static int test_array [1 - 2 * !(($2) < 0)]; ++test_array [0] = 0; ++return test_array [0]; ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_hi=-1 ac_mid=-1 ++ while :; do ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++int ++main () ++{ ++static int test_array [1 - 2 * !(($2) >= $ac_mid)]; ++test_array [0] = 0; ++return test_array [0]; ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_lo=$ac_mid; break ++else ++ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val ++ if test $ac_mid -le $ac_hi; then ++ ac_lo= ac_hi= ++ break ++ fi ++ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ done ++else ++ ac_lo= ac_hi= ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++# Binary search between lo and hi bounds. ++while test "x$ac_lo" != "x$ac_hi"; do ++ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++int ++main () ++{ ++static int test_array [1 - 2 * !(($2) <= $ac_mid)]; ++test_array [0] = 0; ++return test_array [0]; ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_hi=$ac_mid ++else ++ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++case $ac_lo in #(( ++?*) eval "$3=\$ac_lo"; ac_retval=0 ;; ++'') ac_retval=1 ;; ++esac ++ else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++static long int longval () { return $2; } ++static unsigned long int ulongval () { return $2; } ++#include ++#include ++int ++main () ++{ ++ ++ FILE *f = fopen ("conftest.val", "w"); ++ if (! f) ++ return 1; ++ if (($2) < 0) ++ { ++ long int i = longval (); ++ if (i != ($2)) ++ return 1; ++ fprintf (f, "%ld", i); ++ } ++ else ++ { ++ unsigned long int i = ulongval (); ++ if (i != ($2)) ++ return 1; ++ fprintf (f, "%lu", i); ++ } ++ /* Do not output a trailing newline, as this causes \r\n confusion ++ on some platforms. */ ++ return ferror (f) || fclose (f) != 0; ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ echo >>conftest.val; read $3 &5 ++$as_echo_n "checking whether $as_decl_name is declared... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++int ++main () ++{ ++#ifndef $as_decl_name ++#ifdef __cplusplus ++ (void) $as_decl_use; ++#else ++ (void) $as_decl_name; ++#endif ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_decl ++cat >config.log <<_ACEOF ++This file contains any messages produced by compilers while ++running configure, to aid debugging if configure makes a mistake. ++ ++It was created by ld $as_me 2.41, which was ++generated by GNU Autoconf 2.69. Invocation command line was ++ ++ $ $0 $@ ++ ++_ACEOF ++exec 5>>config.log ++{ ++cat <<_ASUNAME ++## --------- ## ++## Platform. ## ++## --------- ## ++ ++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` ++uname -m = `(uname -m) 2>/dev/null || echo unknown` ++uname -r = `(uname -r) 2>/dev/null || echo unknown` ++uname -s = `(uname -s) 2>/dev/null || echo unknown` ++uname -v = `(uname -v) 2>/dev/null || echo unknown` ++ ++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` ++/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` ++ ++/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` ++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` ++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` ++/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` ++/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` ++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` ++/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` ++ ++_ASUNAME ++ ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ $as_echo "PATH: $as_dir" ++ done ++IFS=$as_save_IFS ++ ++} >&5 ++ ++cat >&5 <<_ACEOF ++ ++ ++## ----------- ## ++## Core tests. ## ++## ----------- ## ++ ++_ACEOF ++ ++ ++# Keep a trace of the command line. ++# Strip out --no-create and --no-recursion so they do not pile up. ++# Strip out --silent because we don't want to record it for future runs. ++# Also quote any args containing shell meta-characters. ++# Make two passes to allow for proper duplicate-argument suppression. ++ac_configure_args= ++ac_configure_args0= ++ac_configure_args1= ++ac_must_keep_next=false ++for ac_pass in 1 2 ++do ++ for ac_arg ++ do ++ case $ac_arg in ++ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil) ++ continue ;; ++ *\'*) ++ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ esac ++ case $ac_pass in ++ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; ++ 2) ++ as_fn_append ac_configure_args1 " '$ac_arg'" ++ if test $ac_must_keep_next = true; then ++ ac_must_keep_next=false # Got value, back to normal. ++ else ++ case $ac_arg in ++ *=* | --config-cache | -C | -disable-* | --disable-* \ ++ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ ++ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ ++ | -with-* | --with-* | -without-* | --without-* | --x) ++ case "$ac_configure_args0 " in ++ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; ++ esac ++ ;; ++ -* ) ac_must_keep_next=true ;; ++ esac ++ fi ++ as_fn_append ac_configure_args " '$ac_arg'" ++ ;; ++ esac ++ done ++done ++{ ac_configure_args0=; unset ac_configure_args0;} ++{ ac_configure_args1=; unset ac_configure_args1;} ++ ++# When interrupted or exit'd, cleanup temporary files, and complete ++# config.log. We remove comments because anyway the quotes in there ++# would cause problems or look ugly. ++# WARNING: Use '\'' to represent an apostrophe within the trap. ++# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. ++trap 'exit_status=$? ++ # Save into config.log some information that might help in debugging. ++ { ++ echo ++ ++ $as_echo "## ---------------- ## ++## Cache variables. ## ++## ---------------- ##" ++ echo ++ # The following way of writing the cache mishandles newlines in values, ++( ++ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do ++ eval ac_val=\$$ac_var ++ case $ac_val in #( ++ *${as_nl}*) ++ case $ac_var in #( ++ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 ++$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ++ esac ++ case $ac_var in #( ++ _ | IFS | as_nl) ;; #( ++ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( ++ *) { eval $ac_var=; unset $ac_var;} ;; ++ esac ;; ++ esac ++ done ++ (set) 2>&1 | ++ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( ++ *${as_nl}ac_space=\ *) ++ sed -n \ ++ "s/'\''/'\''\\\\'\'''\''/g; ++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ++ ;; #( ++ *) ++ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ++ ;; ++ esac | ++ sort ++) ++ echo ++ ++ $as_echo "## ----------------- ## ++## Output variables. ## ++## ----------------- ##" ++ echo ++ for ac_var in $ac_subst_vars ++ do ++ eval ac_val=\$$ac_var ++ case $ac_val in ++ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; ++ esac ++ $as_echo "$ac_var='\''$ac_val'\''" ++ done | sort ++ echo ++ ++ if test -n "$ac_subst_files"; then ++ $as_echo "## ------------------- ## ++## File substitutions. ## ++## ------------------- ##" ++ echo ++ for ac_var in $ac_subst_files ++ do ++ eval ac_val=\$$ac_var ++ case $ac_val in ++ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; ++ esac ++ $as_echo "$ac_var='\''$ac_val'\''" ++ done | sort ++ echo ++ fi ++ ++ if test -s confdefs.h; then ++ $as_echo "## ----------- ## ++## confdefs.h. ## ++## ----------- ##" ++ echo ++ cat confdefs.h ++ echo ++ fi ++ test "$ac_signal" != 0 && ++ $as_echo "$as_me: caught signal $ac_signal" ++ $as_echo "$as_me: exit $exit_status" ++ } >&5 ++ rm -f core *.core core.conftest.* && ++ rm -f -r conftest* confdefs* conf$$* $ac_clean_files && ++ exit $exit_status ++' 0 ++for ac_signal in 1 2 13 15; do ++ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal ++done ++ac_signal=0 ++ ++# confdefs.h avoids OS command line length limits that DEFS can exceed. ++rm -f -r conftest* confdefs.h ++ ++$as_echo "/* confdefs.h */" > confdefs.h ++ ++# Predefined preprocessor variables. ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_NAME "$PACKAGE_NAME" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_TARNAME "$PACKAGE_TARNAME" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_VERSION "$PACKAGE_VERSION" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_STRING "$PACKAGE_STRING" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" ++_ACEOF ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_URL "$PACKAGE_URL" ++_ACEOF ++ ++ ++# Let the site file select an alternate cache file if it wants to. ++# Prefer an explicitly selected file to automatically selected ones. ++ac_site_file1=NONE ++ac_site_file2=NONE ++if test -n "$CONFIG_SITE"; then ++ # We do not want a PATH search for config.site. ++ case $CONFIG_SITE in #(( ++ -*) ac_site_file1=./$CONFIG_SITE;; ++ */*) ac_site_file1=$CONFIG_SITE;; ++ *) ac_site_file1=./$CONFIG_SITE;; ++ esac ++elif test "x$prefix" != xNONE; then ++ ac_site_file1=$prefix/share/config.site ++ ac_site_file2=$prefix/etc/config.site ++else ++ ac_site_file1=$ac_default_prefix/share/config.site ++ ac_site_file2=$ac_default_prefix/etc/config.site ++fi ++for ac_site_file in "$ac_site_file1" "$ac_site_file2" ++do ++ test "x$ac_site_file" = xNONE && continue ++ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 ++$as_echo "$as_me: loading site script $ac_site_file" >&6;} ++ sed 's/^/| /' "$ac_site_file" >&5 ++ . "$ac_site_file" \ ++ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "failed to load site script $ac_site_file ++See \`config.log' for more details" "$LINENO" 5; } ++ fi ++done ++ ++if test -r "$cache_file"; then ++ # Some versions of bash will fail to source /dev/null (special files ++ # actually), so we avoid doing that. DJGPP emulates it as a regular file. ++ if test /dev/null != "$cache_file" && test -f "$cache_file"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 ++$as_echo "$as_me: loading cache $cache_file" >&6;} ++ case $cache_file in ++ [\\/]* | ?:[\\/]* ) . "$cache_file";; ++ *) . "./$cache_file";; ++ esac ++ fi ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 ++$as_echo "$as_me: creating cache $cache_file" >&6;} ++ >$cache_file ++fi ++ ++as_fn_append ac_header_list " stdlib.h" ++as_fn_append ac_header_list " unistd.h" ++as_fn_append ac_header_list " sys/param.h" ++# Check that the precious variables saved in the cache have kept the same ++# value. ++ac_cache_corrupted=false ++for ac_var in $ac_precious_vars; do ++ eval ac_old_set=\$ac_cv_env_${ac_var}_set ++ eval ac_new_set=\$ac_env_${ac_var}_set ++ eval ac_old_val=\$ac_cv_env_${ac_var}_value ++ eval ac_new_val=\$ac_env_${ac_var}_value ++ case $ac_old_set,$ac_new_set in ++ set,) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 ++$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ++ ac_cache_corrupted=: ;; ++ ,set) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 ++$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ++ ac_cache_corrupted=: ;; ++ ,);; ++ *) ++ if test "x$ac_old_val" != "x$ac_new_val"; then ++ # differences in whitespace do not lead to failure. ++ ac_old_val_w=`echo x $ac_old_val` ++ ac_new_val_w=`echo x $ac_new_val` ++ if test "$ac_old_val_w" != "$ac_new_val_w"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 ++$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ++ ac_cache_corrupted=: ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 ++$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} ++ eval $ac_var=\$ac_old_val ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 ++$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 ++$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} ++ fi;; ++ esac ++ # Pass precious variables to config.status. ++ if test "$ac_new_set" = set; then ++ case $ac_new_val in ++ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; ++ *) ac_arg=$ac_var=$ac_new_val ;; ++ esac ++ case " $ac_configure_args " in ++ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. ++ *) as_fn_append ac_configure_args " '$ac_arg'" ;; ++ esac ++ fi ++done ++if $ac_cache_corrupted; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 ++$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} ++ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 ++fi ++## -------------------- ## ++## Main body of script. ## ++## -------------------- ## ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++ ++ ++ ++ ++ ++ac_aux_dir= ++for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do ++ if test -f "$ac_dir/install-sh"; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/install-sh -c" ++ break ++ elif test -f "$ac_dir/install.sh"; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/install.sh -c" ++ break ++ elif test -f "$ac_dir/shtool"; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/shtool install -c" ++ break ++ fi ++done ++if test -z "$ac_aux_dir"; then ++ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 ++fi ++ ++# These three variables are undocumented and unsupported, ++# and are intended to be withdrawn in a future Autoconf release. ++# They can cause serious problems if a builder's source tree is in a directory ++# whose full name contains unusual characters. ++ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ++ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ++ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ++ ++ ++# Make sure we can run config.sub. ++$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || ++ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 ++$as_echo_n "checking build system type... " >&6; } ++if ${ac_cv_build+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_build_alias=$build_alias ++test "x$ac_build_alias" = x && ++ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` ++test "x$ac_build_alias" = x && ++ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ++ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || ++ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 ++$as_echo "$ac_cv_build" >&6; } ++case $ac_cv_build in ++*-*-*) ;; ++*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; ++esac ++build=$ac_cv_build ++ac_save_IFS=$IFS; IFS='-' ++set x $ac_cv_build ++shift ++build_cpu=$1 ++build_vendor=$2 ++shift; shift ++# Remember, the first character of IFS is used to create $*, ++# except with old shells: ++build_os=$* ++IFS=$ac_save_IFS ++case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 ++$as_echo_n "checking host system type... " >&6; } ++if ${ac_cv_host+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "x$host_alias" = x; then ++ ac_cv_host=$ac_cv_build ++else ++ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || ++ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 ++$as_echo "$ac_cv_host" >&6; } ++case $ac_cv_host in ++*-*-*) ;; ++*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; ++esac ++host=$ac_cv_host ++ac_save_IFS=$IFS; IFS='-' ++set x $ac_cv_host ++shift ++host_cpu=$1 ++host_vendor=$2 ++shift; shift ++# Remember, the first character of IFS is used to create $*, ++# except with old shells: ++host_os=$* ++IFS=$ac_save_IFS ++case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 ++$as_echo_n "checking target system type... " >&6; } ++if ${ac_cv_target+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "x$target_alias" = x; then ++ ac_cv_target=$ac_cv_host ++else ++ ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || ++ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 ++$as_echo "$ac_cv_target" >&6; } ++case $ac_cv_target in ++*-*-*) ;; ++*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; ++esac ++target=$ac_cv_target ++ac_save_IFS=$IFS; IFS='-' ++set x $ac_cv_target ++shift ++target_cpu=$1 ++target_vendor=$2 ++shift; shift ++# Remember, the first character of IFS is used to create $*, ++# except with old shells: ++target_os=$* ++IFS=$ac_save_IFS ++case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac ++ ++ ++# The aliases save the names the user supplied, while $host etc. ++# will get canonicalized. ++test -n "$target_alias" && ++ test "$program_prefix$program_suffix$program_transform_name" = \ ++ NONENONEs,x,x, && ++ program_prefix=${target_alias}- ++ ++ ++am__api_version='1.15' ++ ++# Find a good install program. We prefer a C program (faster), ++# so one script is as good as another. But avoid the broken or ++# incompatible versions: ++# SysV /etc/install, /usr/sbin/install ++# SunOS /usr/etc/install ++# IRIX /sbin/install ++# AIX /bin/install ++# AmigaOS /C/install, which installs bootblocks on floppy discs ++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag ++# AFS /usr/afsws/bin/install, which mishandles nonexistent args ++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" ++# OS/2's system install, which has a completely different semantic ++# ./install, which can be erroneously created by make from ./install.sh. ++# Reject install programs that cannot install multiple files. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 ++$as_echo_n "checking for a BSD-compatible install... " >&6; } ++if test -z "$INSTALL"; then ++if ${ac_cv_path_install+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ # Account for people who put trailing slashes in PATH elements. ++case $as_dir/ in #(( ++ ./ | .// | /[cC]/* | \ ++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ++ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ ++ /usr/ucb/* ) ;; ++ *) ++ # OSF1 and SCO ODT 3.0 have their own names for install. ++ # Don't use installbsd from OSF since it installs stuff as root ++ # by default. ++ for ac_prog in ginstall scoinst install; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then ++ if test $ac_prog = install && ++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # AIX install. It has an incompatible calling convention. ++ : ++ elif test $ac_prog = install && ++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # program-specific install script used by HP pwplus--don't use. ++ : ++ else ++ rm -rf conftest.one conftest.two conftest.dir ++ echo one > conftest.one ++ echo two > conftest.two ++ mkdir conftest.dir ++ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && ++ test -s conftest.one && test -s conftest.two && ++ test -s conftest.dir/conftest.one && ++ test -s conftest.dir/conftest.two ++ then ++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" ++ break 3 ++ fi ++ fi ++ fi ++ done ++ done ++ ;; ++esac ++ ++ done ++IFS=$as_save_IFS ++ ++rm -rf conftest.one conftest.two conftest.dir ++ ++fi ++ if test "${ac_cv_path_install+set}" = set; then ++ INSTALL=$ac_cv_path_install ++ else ++ # As a last resort, use the slow shell script. Don't cache a ++ # value for INSTALL within a source directory, because that will ++ # break other packages using the cache if that directory is ++ # removed, or if the value is a relative name. ++ INSTALL=$ac_install_sh ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 ++$as_echo "$INSTALL" >&6; } ++ ++# Use test -z because SunOS4 sh mishandles braces in ${var-val}. ++# It thinks the first close brace ends the variable substitution. ++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' ++ ++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' ++ ++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 ++$as_echo_n "checking whether build environment is sane... " >&6; } ++# Reject unsafe characters in $srcdir or the absolute working directory ++# name. Accept space and tab only in the latter. ++am_lf=' ++' ++case `pwd` in ++ *[\\\"\#\$\&\'\`$am_lf]*) ++ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; ++esac ++case $srcdir in ++ *[\\\"\#\$\&\'\`$am_lf\ \ ]*) ++ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; ++esac ++ ++# Do 'set' in a subshell so we don't clobber the current shell's ++# arguments. Must try -L first in case configure is actually a ++# symlink; some systems play weird games with the mod time of symlinks ++# (eg FreeBSD returns the mod time of the symlink's containing ++# directory). ++if ( ++ am_has_slept=no ++ for am_try in 1 2; do ++ echo "timestamp, slept: $am_has_slept" > conftest.file ++ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` ++ if test "$*" = "X"; then ++ # -L didn't work. ++ set X `ls -t "$srcdir/configure" conftest.file` ++ fi ++ if test "$*" != "X $srcdir/configure conftest.file" \ ++ && test "$*" != "X conftest.file $srcdir/configure"; then ++ ++ # If neither matched, then we have a broken ls. This can happen ++ # if, for instance, CONFIG_SHELL is bash and it inherits a ++ # broken ls alias from the environment. This has actually ++ # happened. Such a system could not be considered "sane". ++ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken ++ alias in your environment" "$LINENO" 5 ++ fi ++ if test "$2" = conftest.file || test $am_try -eq 2; then ++ break ++ fi ++ # Just in case. ++ sleep 1 ++ am_has_slept=yes ++ done ++ test "$2" = conftest.file ++ ) ++then ++ # Ok. ++ : ++else ++ as_fn_error $? "newly created file is older than distributed files! ++Check your system clock" "$LINENO" 5 ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++# If we didn't sleep, we still need to ensure time stamps of config.status and ++# generated files are strictly newer. ++am_sleep_pid= ++if grep 'slept: no' conftest.file >/dev/null 2>&1; then ++ ( sleep 1 ) & ++ am_sleep_pid=$! ++fi ++ ++rm -f conftest.file ++ ++test "$program_prefix" != NONE && ++ program_transform_name="s&^&$program_prefix&;$program_transform_name" ++# Use a double $ so make ignores it. ++test "$program_suffix" != NONE && ++ program_transform_name="s&\$&$program_suffix&;$program_transform_name" ++# Double any \ or $. ++# By default was `s,x,x', remove it if useless. ++ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' ++program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` ++ ++# Expand $ac_aux_dir to an absolute path. ++am_aux_dir=`cd "$ac_aux_dir" && pwd` ++ ++if test x"${MISSING+set}" != xset; then ++ case $am_aux_dir in ++ *\ * | *\ *) ++ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; ++ *) ++ MISSING="\${SHELL} $am_aux_dir/missing" ;; ++ esac ++fi ++# Use eval to expand $SHELL ++if eval "$MISSING --is-lightweight"; then ++ am_missing_run="$MISSING " ++else ++ am_missing_run= ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 ++$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} ++fi ++ ++if test x"${install_sh+set}" != xset; then ++ case $am_aux_dir in ++ *\ * | *\ *) ++ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; ++ *) ++ install_sh="\${SHELL} $am_aux_dir/install-sh" ++ esac ++fi ++ ++# Installed binaries are usually stripped using 'strip' when the user ++# run "make install-strip". However 'strip' might not be the right ++# tool to use in cross-compilation environments, therefore Automake ++# will honor the 'STRIP' environment variable to overrule this program. ++if test "$cross_compiling" != no; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. ++set dummy ${ac_tool_prefix}strip; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_STRIP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$STRIP"; then ++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_STRIP="${ac_tool_prefix}strip" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++STRIP=$ac_cv_prog_STRIP ++if test -n "$STRIP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 ++$as_echo "$STRIP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_STRIP"; then ++ ac_ct_STRIP=$STRIP ++ # Extract the first word of "strip", so it can be a program name with args. ++set dummy strip; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_STRIP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_STRIP"; then ++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_STRIP="strip" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP ++if test -n "$ac_ct_STRIP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 ++$as_echo "$ac_ct_STRIP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_STRIP" = x; then ++ STRIP=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ STRIP=$ac_ct_STRIP ++ fi ++else ++ STRIP="$ac_cv_prog_STRIP" ++fi ++ ++fi ++INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 ++$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } ++if test -z "$MKDIR_P"; then ++ if ${ac_cv_path_mkdir+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in mkdir gmkdir; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue ++ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( ++ 'mkdir (GNU coreutils) '* | \ ++ 'mkdir (coreutils) '* | \ ++ 'mkdir (fileutils) '4.1*) ++ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext ++ break 3;; ++ esac ++ done ++ done ++ done ++IFS=$as_save_IFS ++ ++fi ++ ++ test -d ./--version && rmdir ./--version ++ if test "${ac_cv_path_mkdir+set}" = set; then ++ MKDIR_P="$ac_cv_path_mkdir -p" ++ else ++ # As a last resort, use the slow shell script. Don't cache a ++ # value for MKDIR_P within a source directory, because that will ++ # break other packages using the cache if that directory is ++ # removed, or if the value is a relative name. ++ MKDIR_P="$ac_install_sh -d" ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 ++$as_echo "$MKDIR_P" >&6; } ++ ++for ac_prog in gawk mawk nawk awk ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_AWK+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$AWK"; then ++ ac_cv_prog_AWK="$AWK" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_AWK="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++AWK=$ac_cv_prog_AWK ++if test -n "$AWK"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 ++$as_echo "$AWK" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$AWK" && break ++done ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 ++$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } ++set x ${MAKE-make} ++ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` ++if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat >conftest.make <<\_ACEOF ++SHELL = /bin/sh ++all: ++ @echo '@@@%%%=$(MAKE)=@@@%%%' ++_ACEOF ++# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. ++case `${MAKE-make} -f conftest.make 2>/dev/null` in ++ *@@@%%%=?*=@@@%%%*) ++ eval ac_cv_prog_make_${ac_make}_set=yes;; ++ *) ++ eval ac_cv_prog_make_${ac_make}_set=no;; ++esac ++rm -f conftest.make ++fi ++if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ SET_MAKE= ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ SET_MAKE="MAKE=${MAKE-make}" ++fi ++ ++rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++ ++# Check whether --enable-silent-rules was given. ++if test "${enable_silent_rules+set}" = set; then : ++ enableval=$enable_silent_rules; ++fi ++ ++case $enable_silent_rules in # ((( ++ yes) AM_DEFAULT_VERBOSITY=0;; ++ no) AM_DEFAULT_VERBOSITY=1;; ++ *) AM_DEFAULT_VERBOSITY=1;; ++esac ++am_make=${MAKE-make} ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 ++$as_echo_n "checking whether $am_make supports nested variables... " >&6; } ++if ${am_cv_make_support_nested_variables+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if $as_echo 'TRUE=$(BAR$(V)) ++BAR0=false ++BAR1=true ++V=1 ++am__doit: ++ @$(TRUE) ++.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then ++ am_cv_make_support_nested_variables=yes ++else ++ am_cv_make_support_nested_variables=no ++fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 ++$as_echo "$am_cv_make_support_nested_variables" >&6; } ++if test $am_cv_make_support_nested_variables = yes; then ++ AM_V='$(V)' ++ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' ++else ++ AM_V=$AM_DEFAULT_VERBOSITY ++ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY ++fi ++AM_BACKSLASH='\' ++ ++if test "`cd $srcdir && pwd`" != "`pwd`"; then ++ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output ++ # is not polluted with repeated "-I." ++ am__isrc=' -I$(srcdir)' ++ # test to see if srcdir already configured ++ if test -f $srcdir/config.status; then ++ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 ++ fi ++fi ++ ++# test whether we have cygpath ++if test -z "$CYGPATH_W"; then ++ if (cygpath --version) >/dev/null 2>/dev/null; then ++ CYGPATH_W='cygpath -w' ++ else ++ CYGPATH_W=echo ++ fi ++fi ++ ++ ++# Define the identity of the package. ++ PACKAGE='ld' ++ VERSION='2.41' ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE "$PACKAGE" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define VERSION "$VERSION" ++_ACEOF ++ ++# Some tools Automake needs. ++ ++ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} ++ ++ ++AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} ++ ++ ++AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} ++ ++ ++AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} ++ ++ ++MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} ++ ++# For better backward compatibility. To be removed once Automake 1.9.x ++# dies out for good. For more background, see: ++# ++# ++mkdir_p='$(MKDIR_P)' ++ ++# We need awk for the "check" target (and possibly the TAP driver). The ++# system "awk" is bad on some platforms. ++# Always define AMTAR for backward compatibility. Yes, it's still used ++# in the wild :-( We should find a proper way to deprecate it ... ++AMTAR='$${TAR-tar}' ++ ++ ++# We'll loop over all known methods to create a tar archive until one works. ++_am_tools='gnutar pax cpio none' ++ ++am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' ++ ++ ++ ++ ++ ++ ++# POSIX will say in a future version that running "rm -f" with no argument ++# is OK; and we want to be able to make that assumption in our Makefile ++# recipes. So use an aggressive probe to check that the usage we want is ++# actually supported "in the wild" to an acceptable degree. ++# See automake bug#10828. ++# To make any issue more visible, cause the running configure to be aborted ++# by default if the 'rm' program in use doesn't match our expectations; the ++# user can still override this though. ++if rm -f && rm -fr && rm -rf; then : OK; else ++ cat >&2 <<'END' ++Oops! ++ ++Your 'rm' program seems unable to run without file operands specified ++on the command line, even when the '-f' option is present. This is contrary ++to the behaviour of most rm programs out there, and not conforming with ++the upcoming POSIX standard: ++ ++Please tell bug-automake@gnu.org about your system, including the value ++of your $PATH and any error possibly output before this message. This ++can help us improve future automake versions. ++ ++END ++ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then ++ echo 'Configuration will proceed anyway, since you have set the' >&2 ++ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 ++ echo >&2 ++ else ++ cat >&2 <<'END' ++Aborting the configuration process, to ensure you take notice of the issue. ++ ++You can download and install GNU coreutils to get an 'rm' implementation ++that behaves properly: . ++ ++If you want to complete the configuration process using your problematic ++'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM ++to "yes", and re-run configure. ++ ++END ++ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 ++ fi ++fi ++ ++# Check whether --enable-silent-rules was given. ++if test "${enable_silent_rules+set}" = set; then : ++ enableval=$enable_silent_rules; ++fi ++ ++case $enable_silent_rules in # ((( ++ yes) AM_DEFAULT_VERBOSITY=0;; ++ no) AM_DEFAULT_VERBOSITY=1;; ++ *) AM_DEFAULT_VERBOSITY=0;; ++esac ++am_make=${MAKE-make} ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 ++$as_echo_n "checking whether $am_make supports nested variables... " >&6; } ++if ${am_cv_make_support_nested_variables+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if $as_echo 'TRUE=$(BAR$(V)) ++BAR0=false ++BAR1=true ++V=1 ++am__doit: ++ @$(TRUE) ++.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then ++ am_cv_make_support_nested_variables=yes ++else ++ am_cv_make_support_nested_variables=no ++fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 ++$as_echo "$am_cv_make_support_nested_variables" >&6; } ++if test $am_cv_make_support_nested_variables = yes; then ++ AM_V='$(V)' ++ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' ++else ++ AM_V=$AM_DEFAULT_VERBOSITY ++ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY ++fi ++AM_BACKSLASH='\' ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 ++$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } ++ # Check whether --enable-maintainer-mode was given. ++if test "${enable_maintainer_mode+set}" = set; then : ++ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval ++else ++ USE_MAINTAINER_MODE=no ++fi ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 ++$as_echo "$USE_MAINTAINER_MODE" >&6; } ++ if test $USE_MAINTAINER_MODE = yes; then ++ MAINTAINER_MODE_TRUE= ++ MAINTAINER_MODE_FALSE='#' ++else ++ MAINTAINER_MODE_TRUE='#' ++ MAINTAINER_MODE_FALSE= ++fi ++ ++ MAINT=$MAINTAINER_MODE_TRUE ++ ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. ++set dummy ${ac_tool_prefix}gcc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_CC+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="${ac_tool_prefix}gcc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_CC"; then ++ ac_ct_CC=$CC ++ # Extract the first word of "gcc", so it can be a program name with args. ++set dummy gcc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_CC+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CC="gcc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 ++$as_echo "$ac_ct_CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_CC" = x; then ++ CC="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ CC=$ac_ct_CC ++ fi ++else ++ CC="$ac_cv_prog_CC" ++fi ++ ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. ++set dummy ${ac_tool_prefix}cc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_CC+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="${ac_tool_prefix}cc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ fi ++fi ++if test -z "$CC"; then ++ # Extract the first word of "cc", so it can be a program name with args. ++set dummy cc; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_CC+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++ ac_prog_rejected=no ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ++ ac_prog_rejected=yes ++ continue ++ fi ++ ac_cv_prog_CC="cc" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++if test $ac_prog_rejected = yes; then ++ # We found a bogon in the path, so make sure we never use it. ++ set dummy $ac_cv_prog_CC ++ shift ++ if test $# != 0; then ++ # We chose a different compiler from the bogus one. ++ # However, it has the same basename, so the bogon will be chosen ++ # first if we set CC to just the basename; use the full file name. ++ shift ++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" ++ fi ++fi ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in cl.exe ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_CC+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="$ac_tool_prefix$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 ++$as_echo "$CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$CC" && break ++ done ++fi ++if test -z "$CC"; then ++ ac_ct_CC=$CC ++ for ac_prog in cl.exe ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_CC+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CC="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 ++$as_echo "$ac_ct_CC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$ac_ct_CC" && break ++done ++ ++ if test "x$ac_ct_CC" = x; then ++ CC="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ CC=$ac_ct_CC ++ fi ++fi ++ ++fi ++ ++ ++test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "no acceptable C compiler found in \$PATH ++See \`config.log' for more details" "$LINENO" 5; } ++ ++# Provide some information about the compiler. ++$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 ++set X $ac_compile ++ac_compiler=$2 ++for ac_option in --version -v -V -qversion; do ++ { { ac_try="$ac_compiler $ac_option >&5" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_compiler $ac_option >&5") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ sed '10a\ ++... rest of stderr output deleted ... ++ 10q' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ fi ++ rm -f conftest.er1 conftest.err ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++done ++ ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" ++# Try to create an executable without -o first, disregard a.out. ++# It will help us diagnose broken compilers, and finding out an intuition ++# of exeext. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 ++$as_echo_n "checking whether the C compiler works... " >&6; } ++ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` ++ ++# The possible output files: ++ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ++ ++ac_rmfiles= ++for ac_file in $ac_files ++do ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; ++ * ) ac_rmfiles="$ac_rmfiles $ac_file";; ++ esac ++done ++rm -f $ac_rmfiles ++ ++if { { ac_try="$ac_link_default" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link_default") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then : ++ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. ++# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' ++# in a Makefile. We should not override ac_cv_exeext if it was cached, ++# so that the user can short-circuit this test for compilers unknown to ++# Autoconf. ++for ac_file in $ac_files '' ++do ++ test -f "$ac_file" || continue ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ++ ;; ++ [ab].out ) ++ # We found the default executable, but exeext='' is most ++ # certainly right. ++ break;; ++ *.* ) ++ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; ++ then :; else ++ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` ++ fi ++ # We set ac_cv_exeext here because the later test for it is not ++ # safe: cross compilers may not add the suffix if given an `-o' ++ # argument, so we may need to know it at that point already. ++ # Even if this section looks crufty: it has the advantage of ++ # actually working. ++ break;; ++ * ) ++ break;; ++ esac ++done ++test "$ac_cv_exeext" = no && ac_cv_exeext= ++ ++else ++ ac_file='' ++fi ++if test -z "$ac_file"; then : ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++$as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error 77 "C compiler cannot create executables ++See \`config.log' for more details" "$LINENO" 5; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 ++$as_echo_n "checking for C compiler default output file name... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 ++$as_echo "$ac_file" >&6; } ++ac_exeext=$ac_cv_exeext ++ ++rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ++ac_clean_files=$ac_clean_files_save ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 ++$as_echo_n "checking for suffix of executables... " >&6; } ++if { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then : ++ # If both `conftest.exe' and `conftest' are `present' (well, observable) ++# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will ++# work properly (i.e., refer to `conftest.exe'), while it won't with ++# `rm'. ++for ac_file in conftest.exe conftest conftest.*; do ++ test -f "$ac_file" || continue ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; ++ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` ++ break;; ++ * ) break;; ++ esac ++done ++else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "cannot compute suffix of executables: cannot compile and link ++See \`config.log' for more details" "$LINENO" 5; } ++fi ++rm -f conftest conftest$ac_cv_exeext ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 ++$as_echo "$ac_cv_exeext" >&6; } ++ ++rm -f conftest.$ac_ext ++EXEEXT=$ac_cv_exeext ++ac_exeext=$EXEEXT ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++int ++main () ++{ ++FILE *f = fopen ("conftest.out", "w"); ++ return ferror (f) || fclose (f) != 0; ++ ++ ; ++ return 0; ++} ++_ACEOF ++ac_clean_files="$ac_clean_files conftest.out" ++# Check that the compiler produces executables we can run. If not, either ++# the compiler is broken, or we cross compile. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 ++$as_echo_n "checking whether we are cross compiling... " >&6; } ++if test "$cross_compiling" != yes; then ++ { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++ if { ac_try='./conftest$ac_cv_exeext' ++ { { case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_try") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ cross_compiling=no ++ else ++ if test "$cross_compiling" = maybe; then ++ cross_compiling=yes ++ else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "cannot run C compiled programs. ++If you meant to cross compile, use \`--host'. ++See \`config.log' for more details" "$LINENO" 5; } ++ fi ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 ++$as_echo "$cross_compiling" >&6; } ++ ++rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ++ac_clean_files=$ac_clean_files_save ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 ++$as_echo_n "checking for suffix of object files... " >&6; } ++if ${ac_cv_objext+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.o conftest.obj ++if { { ac_try="$ac_compile" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_compile") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then : ++ for ac_file in conftest.o conftest.obj conftest.*; do ++ test -f "$ac_file" || continue; ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; ++ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` ++ break;; ++ esac ++done ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "cannot compute suffix of object files: cannot compile ++See \`config.log' for more details" "$LINENO" 5; } ++fi ++rm -f conftest.$ac_cv_objext conftest.$ac_ext ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 ++$as_echo "$ac_cv_objext" >&6; } ++OBJEXT=$ac_cv_objext ++ac_objext=$OBJEXT ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 ++$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } ++if ${ac_cv_c_compiler_gnu+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_compiler_gnu=yes ++else ++ ac_compiler_gnu=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_c_compiler_gnu=$ac_compiler_gnu ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 ++$as_echo "$ac_cv_c_compiler_gnu" >&6; } ++if test $ac_compiler_gnu = yes; then ++ GCC=yes ++else ++ GCC= ++fi ++ac_test_CFLAGS=${CFLAGS+set} ++ac_save_CFLAGS=$CFLAGS ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 ++$as_echo_n "checking whether $CC accepts -g... " >&6; } ++if ${ac_cv_prog_cc_g+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_save_c_werror_flag=$ac_c_werror_flag ++ ac_c_werror_flag=yes ++ ac_cv_prog_cc_g=no ++ CFLAGS="-g" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_prog_cc_g=yes ++else ++ CFLAGS="" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ++else ++ ac_c_werror_flag=$ac_save_c_werror_flag ++ CFLAGS="-g" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_prog_cc_g=yes ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ac_c_werror_flag=$ac_save_c_werror_flag ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 ++$as_echo "$ac_cv_prog_cc_g" >&6; } ++if test "$ac_test_CFLAGS" = set; then ++ CFLAGS=$ac_save_CFLAGS ++elif test $ac_cv_prog_cc_g = yes; then ++ if test "$GCC" = yes; then ++ CFLAGS="-g -O2" ++ else ++ CFLAGS="-g" ++ fi ++else ++ if test "$GCC" = yes; then ++ CFLAGS="-O2" ++ else ++ CFLAGS= ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 ++$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } ++if ${ac_cv_prog_cc_c89+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_cv_prog_cc_c89=no ++ac_save_CC=$CC ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++#include ++struct stat; ++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ ++struct buf { int x; }; ++FILE * (*rcsopen) (struct buf *, struct stat *, int); ++static char *e (p, i) ++ char **p; ++ int i; ++{ ++ return p[i]; ++} ++static char *f (char * (*g) (char **, int), char **p, ...) ++{ ++ char *s; ++ va_list v; ++ va_start (v,p); ++ s = g (p, va_arg (v,int)); ++ va_end (v); ++ return s; ++} ++ ++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has ++ function prototypes and stuff, but not '\xHH' hex character constants. ++ These don't provoke an error unfortunately, instead are silently treated ++ as 'x'. The following induces an error, until -std is added to get ++ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an ++ array size at least. It's necessary to write '\x00'==0 to get something ++ that's true only with -std. */ ++int osf4_cc_array ['\x00' == 0 ? 1 : -1]; ++ ++/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters ++ inside strings and character constants. */ ++#define FOO(x) 'x' ++int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; ++ ++int test (int i, double x); ++struct s1 {int (*f) (int a);}; ++struct s2 {int (*f) (double a);}; ++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); ++int argc; ++char **argv; ++int ++main () ++{ ++return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ++ ; ++ return 0; ++} ++_ACEOF ++for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ ++ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" ++do ++ CC="$ac_save_CC $ac_arg" ++ if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_prog_cc_c89=$ac_arg ++fi ++rm -f core conftest.err conftest.$ac_objext ++ test "x$ac_cv_prog_cc_c89" != "xno" && break ++done ++rm -f conftest.$ac_ext ++CC=$ac_save_CC ++ ++fi ++# AC_CACHE_VAL ++case "x$ac_cv_prog_cc_c89" in ++ x) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 ++$as_echo "none needed" >&6; } ;; ++ xno) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 ++$as_echo "unsupported" >&6; } ;; ++ *) ++ CC="$CC $ac_cv_prog_cc_c89" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 ++$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; ++esac ++if test "x$ac_cv_prog_cc_c89" != xno; then : ++ ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 ++$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } ++if ${am_cv_prog_cc_c_o+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++ # Make sure it works both with $CC and with simple cc. ++ # Following AC_PROG_CC_C_O, we do the test twice because some ++ # compilers refuse to overwrite an existing .o file with -o, ++ # though they will create one. ++ am_cv_prog_cc_c_o=yes ++ for am_i in 1 2; do ++ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ++ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } \ ++ && test -f conftest2.$ac_objext; then ++ : OK ++ else ++ am_cv_prog_cc_c_o=no ++ break ++ fi ++ done ++ rm -f core conftest* ++ unset am_i ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 ++$as_echo "$am_cv_prog_cc_c_o" >&6; } ++if test "$am_cv_prog_cc_c_o" != yes; then ++ # Losing compiler, so override with the script. ++ # FIXME: It is wrong to rewrite CC. ++ # But if we don't then we get into trouble of one sort or another. ++ # A longer-term fix would be to have automake use am__CC in this case, ++ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" ++ CC="$am_aux_dir/compile $CC" ++fi ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++DEPDIR="${am__leading_dot}deps" ++ ++ac_config_commands="$ac_config_commands depfiles" ++ ++ ++am_make=${MAKE-make} ++cat > confinc << 'END' ++am__doit: ++ @echo this is the am__doit target ++.PHONY: am__doit ++END ++# If we don't find an include directive, just comment out the code. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 ++$as_echo_n "checking for style of include used by $am_make... " >&6; } ++am__include="#" ++am__quote= ++_am_result=none ++# First try GNU make style include. ++echo "include confinc" > confmf ++# Ignore all kinds of additional output from 'make'. ++case `$am_make -s -f confmf 2> /dev/null` in #( ++*the\ am__doit\ target*) ++ am__include=include ++ am__quote= ++ _am_result=GNU ++ ;; ++esac ++# Now try BSD make style include. ++if test "$am__include" = "#"; then ++ echo '.include "confinc"' > confmf ++ case `$am_make -s -f confmf 2> /dev/null` in #( ++ *the\ am__doit\ target*) ++ am__include=.include ++ am__quote="\"" ++ _am_result=BSD ++ ;; ++ esac ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 ++$as_echo "$_am_result" >&6; } ++rm -f confinc confmf ++ ++# Check whether --enable-dependency-tracking was given. ++if test "${enable_dependency_tracking+set}" = set; then : ++ enableval=$enable_dependency_tracking; ++fi ++ ++if test "x$enable_dependency_tracking" != xno; then ++ am_depcomp="$ac_aux_dir/depcomp" ++ AMDEPBACKSLASH='\' ++ am__nodep='_no' ++fi ++ if test "x$enable_dependency_tracking" != xno; then ++ AMDEP_TRUE= ++ AMDEP_FALSE='#' ++else ++ AMDEP_TRUE='#' ++ AMDEP_FALSE= ++fi ++ ++ ++ ++depcc="$CC" am_compiler_list= ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 ++$as_echo_n "checking dependency style of $depcc... " >&6; } ++if ${am_cv_CC_dependencies_compiler_type+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named 'D' -- because '-MD' means "put the output ++ # in D". ++ rm -rf conftest.dir ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_CC_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` ++ fi ++ am__universal=false ++ case " $depcc " in #( ++ *\ -arch\ *\ -arch\ *) am__universal=true ;; ++ esac ++ ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with \), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with ++ # Solaris 10 /bin/sh. ++ echo '/* dummy */' > sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ # We check with '-c' and '-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle '-M -o', and we need to detect this. Also, some Intel ++ # versions had trouble with output in subdirs. ++ am__obj=sub/conftest.${OBJEXT-o} ++ am__minus_obj="-o $am__obj" ++ case $depmode in ++ gcc) ++ # This depmode causes a compiler race in universal mode. ++ test "$am__universal" = false || continue ++ ;; ++ nosideeffect) ++ # After this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested. ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ msvc7 | msvc7msys | msvisualcpp | msvcmsys) ++ # This compiler won't grok '-c -o', but also, the minuso test has ++ # not run yet. These depmodes are late enough in the game, and ++ # so weak that their functioning should not be impacted. ++ am__obj=conftest.${OBJEXT-o} ++ am__minus_obj= ++ ;; ++ none) break ;; ++ esac ++ if depmode=$depmode \ ++ source=sub/conftest.c object=$am__obj \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_CC_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_CC_dependencies_compiler_type=none ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 ++$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } ++CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type ++ ++ if ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then ++ am__fastdepCC_TRUE= ++ am__fastdepCC_FALSE='#' ++else ++ am__fastdepCC_TRUE='#' ++ am__fastdepCC_FALSE= ++fi ++ ++ ++ac_ext=cpp ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++if test -z "$CXX"; then ++ if test -n "$CCC"; then ++ CXX=$CCC ++ else ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_CXX+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$CXX"; then ++ ac_cv_prog_CXX="$CXX" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++CXX=$ac_cv_prog_CXX ++if test -n "$CXX"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 ++$as_echo "$CXX" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$CXX" && break ++ done ++fi ++if test -z "$CXX"; then ++ ac_ct_CXX=$CXX ++ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_CXX+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_CXX"; then ++ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CXX="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_CXX=$ac_cv_prog_ac_ct_CXX ++if test -n "$ac_ct_CXX"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 ++$as_echo "$ac_ct_CXX" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$ac_ct_CXX" && break ++done ++ ++ if test "x$ac_ct_CXX" = x; then ++ CXX="g++" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ CXX=$ac_ct_CXX ++ fi ++fi ++ ++ fi ++fi ++# Provide some information about the compiler. ++$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 ++set X $ac_compile ++ac_compiler=$2 ++for ac_option in --version -v -V -qversion; do ++ { { ac_try="$ac_compiler $ac_option >&5" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_compiler $ac_option >&5") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ sed '10a\ ++... rest of stderr output deleted ... ++ 10q' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ fi ++ rm -f conftest.er1 conftest.err ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++done ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 ++$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } ++if ${ac_cv_cxx_compiler_gnu+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_compile "$LINENO"; then : ++ ac_compiler_gnu=yes ++else ++ ac_compiler_gnu=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_cxx_compiler_gnu=$ac_compiler_gnu ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 ++$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } ++if test $ac_compiler_gnu = yes; then ++ GXX=yes ++else ++ GXX= ++fi ++ac_test_CXXFLAGS=${CXXFLAGS+set} ++ac_save_CXXFLAGS=$CXXFLAGS ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 ++$as_echo_n "checking whether $CXX accepts -g... " >&6; } ++if ${ac_cv_prog_cxx_g+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_save_cxx_werror_flag=$ac_cxx_werror_flag ++ ac_cxx_werror_flag=yes ++ ac_cv_prog_cxx_g=no ++ CXXFLAGS="-g" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_compile "$LINENO"; then : ++ ac_cv_prog_cxx_g=yes ++else ++ CXXFLAGS="" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_compile "$LINENO"; then : ++ ++else ++ ac_cxx_werror_flag=$ac_save_cxx_werror_flag ++ CXXFLAGS="-g" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_compile "$LINENO"; then : ++ ac_cv_prog_cxx_g=yes ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ac_cxx_werror_flag=$ac_save_cxx_werror_flag ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 ++$as_echo "$ac_cv_prog_cxx_g" >&6; } ++if test "$ac_test_CXXFLAGS" = set; then ++ CXXFLAGS=$ac_save_CXXFLAGS ++elif test $ac_cv_prog_cxx_g = yes; then ++ if test "$GXX" = yes; then ++ CXXFLAGS="-g -O2" ++ else ++ CXXFLAGS="-g" ++ fi ++else ++ if test "$GXX" = yes; then ++ CXXFLAGS="-O2" ++ else ++ CXXFLAGS= ++ fi ++fi ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++depcc="$CXX" am_compiler_list= ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 ++$as_echo_n "checking dependency style of $depcc... " >&6; } ++if ${am_cv_CXX_dependencies_compiler_type+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named 'D' -- because '-MD' means "put the output ++ # in D". ++ rm -rf conftest.dir ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_CXX_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` ++ fi ++ am__universal=false ++ case " $depcc " in #( ++ *\ -arch\ *\ -arch\ *) am__universal=true ;; ++ esac ++ ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with \), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with ++ # Solaris 10 /bin/sh. ++ echo '/* dummy */' > sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ # We check with '-c' and '-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle '-M -o', and we need to detect this. Also, some Intel ++ # versions had trouble with output in subdirs. ++ am__obj=sub/conftest.${OBJEXT-o} ++ am__minus_obj="-o $am__obj" ++ case $depmode in ++ gcc) ++ # This depmode causes a compiler race in universal mode. ++ test "$am__universal" = false || continue ++ ;; ++ nosideeffect) ++ # After this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested. ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ msvc7 | msvc7msys | msvisualcpp | msvcmsys) ++ # This compiler won't grok '-c -o', but also, the minuso test has ++ # not run yet. These depmodes are late enough in the game, and ++ # so weak that their functioning should not be impacted. ++ am__obj=conftest.${OBJEXT-o} ++ am__minus_obj= ++ ;; ++ none) break ;; ++ esac ++ if depmode=$depmode \ ++ source=sub/conftest.c object=$am__obj \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_CXX_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_CXX_dependencies_compiler_type=none ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 ++$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } ++CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type ++ ++ if ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then ++ am__fastdepCXX_TRUE= ++ am__fastdepCXX_FALSE='#' ++else ++ am__fastdepCXX_TRUE='#' ++ am__fastdepCXX_FALSE= ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 ++$as_echo_n "checking for grep that handles long lines and -e... " >&6; } ++if ${ac_cv_path_GREP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$GREP"; then ++ ac_path_GREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in grep ggrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" ++ as_fn_executable_p "$ac_path_GREP" || continue ++# Check for GNU ac_path_GREP and select it if it is found. ++ # Check for GNU $ac_path_GREP ++case `"$ac_path_GREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'GREP' >> "conftest.nl" ++ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_GREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_GREP="$ac_path_GREP" ++ ac_path_GREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_GREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_GREP"; then ++ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_GREP=$GREP ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 ++$as_echo "$ac_cv_path_GREP" >&6; } ++ GREP="$ac_cv_path_GREP" ++ ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 ++$as_echo_n "checking how to run the C preprocessor... " >&6; } ++# On Suns, sometimes $CPP names a directory. ++if test -n "$CPP" && test -d "$CPP"; then ++ CPP= ++fi ++if test -z "$CPP"; then ++ if ${ac_cv_prog_CPP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # Double quotes because CPP needs to be expanded ++ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.i conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ break ++fi ++ ++ done ++ ac_cv_prog_CPP=$CPP ++ ++fi ++ CPP=$ac_cv_prog_CPP ++else ++ ac_cv_prog_CPP=$CPP ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 ++$as_echo "$CPP" >&6; } ++ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.i conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ ++else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "C preprocessor \"$CPP\" fails sanity check ++See \`config.log' for more details" "$LINENO" 5; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 ++$as_echo_n "checking for egrep... " >&6; } ++if ${ac_cv_path_EGREP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 ++ then ac_cv_path_EGREP="$GREP -E" ++ else ++ if test -z "$EGREP"; then ++ ac_path_EGREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in egrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" ++ as_fn_executable_p "$ac_path_EGREP" || continue ++# Check for GNU ac_path_EGREP and select it if it is found. ++ # Check for GNU $ac_path_EGREP ++case `"$ac_path_EGREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'EGREP' >> "conftest.nl" ++ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_EGREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_EGREP="$ac_path_EGREP" ++ ac_path_EGREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_EGREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_EGREP"; then ++ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_EGREP=$EGREP ++fi ++ ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 ++$as_echo "$ac_cv_path_EGREP" >&6; } ++ EGREP="$ac_cv_path_EGREP" ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 ++$as_echo_n "checking for ANSI C header files... " >&6; } ++if ${ac_cv_header_stdc+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++#include ++#include ++#include ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_header_stdc=yes ++else ++ ac_cv_header_stdc=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ++if test $ac_cv_header_stdc = yes; then ++ # SunOS 4.x string.h does not declare mem*, contrary to ANSI. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "memchr" >/dev/null 2>&1; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "free" >/dev/null 2>&1; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. ++ if test "$cross_compiling" = yes; then : ++ : ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++#include ++#if ((' ' & 0x0FF) == 0x020) ++# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') ++# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) ++#else ++# define ISLOWER(c) \ ++ (('a' <= (c) && (c) <= 'i') \ ++ || ('j' <= (c) && (c) <= 'r') \ ++ || ('s' <= (c) && (c) <= 'z')) ++# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) ++#endif ++ ++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) ++int ++main () ++{ ++ int i; ++ for (i = 0; i < 256; i++) ++ if (XOR (islower (i), ISLOWER (i)) ++ || toupper (i) != TOUPPER (i)) ++ return 2; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++ ++fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 ++$as_echo "$ac_cv_header_stdc" >&6; } ++if test $ac_cv_header_stdc = yes; then ++ ++$as_echo "#define STDC_HEADERS 1" >>confdefs.h ++ ++fi ++ ++# On IRIX 5.3, sys/types and inttypes.h are conflicting. ++for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ ++ inttypes.h stdint.h unistd.h ++do : ++ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ++ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default ++" ++if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ ++ ++ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" ++if test "x$ac_cv_header_minix_config_h" = xyes; then : ++ MINIX=yes ++else ++ MINIX= ++fi ++ ++ ++ if test "$MINIX" = yes; then ++ ++$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h ++ ++ ++$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h ++ ++ ++$as_echo "#define _MINIX 1" >>confdefs.h ++ ++ fi ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 ++$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } ++if ${ac_cv_safe_to_define___extensions__+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++# define __EXTENSIONS__ 1 ++ $ac_includes_default ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_safe_to_define___extensions__=yes ++else ++ ac_cv_safe_to_define___extensions__=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 ++$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } ++ test $ac_cv_safe_to_define___extensions__ = yes && ++ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h ++ ++ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h ++ ++ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h ++ ++ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h ++ ++ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. ++set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_PKG_CONFIG+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $PKG_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++PKG_CONFIG=$ac_cv_path_PKG_CONFIG ++if test -n "$PKG_CONFIG"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 ++$as_echo "$PKG_CONFIG" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_path_PKG_CONFIG"; then ++ ac_pt_PKG_CONFIG=$PKG_CONFIG ++ # Extract the first word of "pkg-config", so it can be a program name with args. ++set dummy pkg-config; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $ac_pt_PKG_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG ++if test -n "$ac_pt_PKG_CONFIG"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 ++$as_echo "$ac_pt_PKG_CONFIG" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_pt_PKG_CONFIG" = x; then ++ PKG_CONFIG="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ PKG_CONFIG=$ac_pt_PKG_CONFIG ++ fi ++else ++ PKG_CONFIG="$ac_cv_path_PKG_CONFIG" ++fi ++ ++fi ++if test -n "$PKG_CONFIG"; then ++ _pkg_min_version=0.9.0 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 ++$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } ++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ PKG_CONFIG="" ++ fi ++fi ++ ++case `pwd` in ++ *\ * | *\ *) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 ++$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; ++esac ++ ++ ++ ++macro_version='2.2.7a' ++macro_revision='1.3134' ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ltmain="$ac_aux_dir/ltmain.sh" ++ ++# Backslashify metacharacters that are still active within ++# double-quoted strings. ++sed_quote_subst='s/\(["`$\\]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\(["`\\]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++ ++ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ++ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 ++$as_echo_n "checking how to print strings... " >&6; } ++# Test print first, because it will be a builtin if present. ++if test "X`print -r -- -n 2>/dev/null`" = X-n && \ ++ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ++ ECHO='print -r --' ++elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ++ ECHO='printf %s\n' ++else ++ # Use this function as a fallback that always works. ++ func_fallback_echo () ++ { ++ eval 'cat <<_LTECHO_EOF ++$1 ++_LTECHO_EOF' ++ } ++ ECHO='func_fallback_echo' ++fi ++ ++# func_echo_all arg... ++# Invoke $ECHO with all args, space-separated. ++func_echo_all () ++{ ++ $ECHO "" ++} ++ ++case "$ECHO" in ++ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 ++$as_echo "printf" >&6; } ;; ++ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 ++$as_echo "print -r" >&6; } ;; ++ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 ++$as_echo "cat" >&6; } ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 ++$as_echo_n "checking for a sed that does not truncate output... " >&6; } ++if ${ac_cv_path_SED+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ ++ for ac_i in 1 2 3 4 5 6 7; do ++ ac_script="$ac_script$as_nl$ac_script" ++ done ++ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed ++ { ac_script=; unset ac_script;} ++ if test -z "$SED"; then ++ ac_path_SED_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in sed gsed; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" ++ as_fn_executable_p "$ac_path_SED" || continue ++# Check for GNU ac_path_SED and select it if it is found. ++ # Check for GNU $ac_path_SED ++case `"$ac_path_SED" --version 2>&1` in ++*GNU*) ++ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo '' >> "conftest.nl" ++ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_SED_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_SED="$ac_path_SED" ++ ac_path_SED_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_SED_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_SED"; then ++ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_SED=$SED ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 ++$as_echo "$ac_cv_path_SED" >&6; } ++ SED="$ac_cv_path_SED" ++ rm -f conftest.sed ++ ++test -z "$SED" && SED=sed ++Xsed="$SED -e 1s/^X//" ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 ++$as_echo_n "checking for fgrep... " >&6; } ++if ${ac_cv_path_FGREP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 ++ then ac_cv_path_FGREP="$GREP -F" ++ else ++ if test -z "$FGREP"; then ++ ac_path_FGREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in fgrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" ++ as_fn_executable_p "$ac_path_FGREP" || continue ++# Check for GNU ac_path_FGREP and select it if it is found. ++ # Check for GNU $ac_path_FGREP ++case `"$ac_path_FGREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'FGREP' >> "conftest.nl" ++ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_FGREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_FGREP="$ac_path_FGREP" ++ ac_path_FGREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_FGREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_FGREP"; then ++ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_FGREP=$FGREP ++fi ++ ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 ++$as_echo "$ac_cv_path_FGREP" >&6; } ++ FGREP="$ac_cv_path_FGREP" ++ ++ ++test -z "$GREP" && GREP=grep ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# Check whether --with-gnu-ld was given. ++if test "${with_gnu_ld+set}" = set; then : ++ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes ++else ++ with_gnu_ld=no ++fi ++ ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 ++$as_echo_n "checking for ld used by $CC... " >&6; } ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [\\/]* | ?:[\\/]*) ++ re_direlt='/[^/][^/]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` ++ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 ++$as_echo_n "checking for GNU ld... " >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 ++$as_echo_n "checking for non-GNU ld... " >&6; } ++fi ++if ${lt_cv_path_LD+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 &5 ++$as_echo "$LD" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 ++$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } ++if ${lt_cv_prog_gnu_ld+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 &5 ++$as_echo "$lt_cv_prog_gnu_ld" >&6; } ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 ++$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } ++if ${lt_cv_path_NM+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$NM"; then ++ # Let the user override the nm to test. ++ lt_nm_to_check="$NM" ++ else ++ lt_nm_to_check="${ac_tool_prefix}nm" ++ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then ++ lt_nm_to_check="$lt_nm_to_check nm" ++ fi ++ fi ++ for lt_tmp_nm in "$lt_nm_to_check"; do ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ # Strip out any user-provided options from the nm to test twice, ++ # the first time to test to see if nm (rather than its options) has ++ # an explicit path, the second time to yield a file which can be ++ # nm'ed itself. ++ tmp_nm_path="`$ECHO "$lt_tmp_nm" | sed 's, -.*$,,'`" ++ case "$tmp_nm_path" in ++ */*|*\\*) tmp_nm="$lt_tmp_nm";; ++ *) tmp_nm="$ac_dir/$lt_tmp_nm";; ++ esac ++ tmp_nm_to_nm="`$ECHO "$tmp_nm" | sed 's, -.*$,,'`" ++ if test -f "$tmp_nm_to_nm" || test -f "$tmp_nm_to_nm$ac_exeext" ; then ++ # Check to see if the nm accepts a BSD-compat flag. ++ # Adding the `sed 1q' prevents false positives on HP-UX, which says: ++ # nm: unknown option "B" ignored ++ case `"$tmp_nm" -B "$tmp_nm_to_nm" 2>&1 | grep -v '^ *$' | sed '1q'` in ++ *$tmp_nm*) lt_cv_path_NM="$tmp_nm -B" ++ break ++ ;; ++ *) ++ case `"$tmp_nm" -p "$tmp_nm_to_nm" 2>&1 | grep -v '^ *$' | sed '1q'` in ++ *$tmp_nm*) ++ lt_cv_path_NM="$tmp_nm -p" ++ break ++ ;; ++ *) ++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but ++ continue # so that we can try to find one that supports BSD flags ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++ done ++ : ${lt_cv_path_NM=no} ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 ++$as_echo "$lt_cv_path_NM" >&6; } ++if test "$lt_cv_path_NM" != "no"; then ++ NM="$lt_cv_path_NM" ++else ++ # Didn't find any BSD compatible name lister, look for dumpbin. ++ if test -n "$DUMPBIN"; then : ++ # Let the user override the test. ++ else ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in dumpbin "link -dump" ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_DUMPBIN+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$DUMPBIN"; then ++ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++DUMPBIN=$ac_cv_prog_DUMPBIN ++if test -n "$DUMPBIN"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 ++$as_echo "$DUMPBIN" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$DUMPBIN" && break ++ done ++fi ++if test -z "$DUMPBIN"; then ++ ac_ct_DUMPBIN=$DUMPBIN ++ for ac_prog in dumpbin "link -dump" ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_DUMPBIN"; then ++ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN ++if test -n "$ac_ct_DUMPBIN"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 ++$as_echo "$ac_ct_DUMPBIN" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$ac_ct_DUMPBIN" && break ++done ++ ++ if test "x$ac_ct_DUMPBIN" = x; then ++ DUMPBIN=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ DUMPBIN=$ac_ct_DUMPBIN ++ fi ++fi ++ ++ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in ++ *COFF*) ++ DUMPBIN="$DUMPBIN -symbols" ++ ;; ++ *) ++ DUMPBIN=: ++ ;; ++ esac ++ fi ++ ++ if test "$DUMPBIN" != ":"; then ++ NM="$DUMPBIN" ++ fi ++fi ++test -z "$NM" && NM=nm ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 ++$as_echo_n "checking the name lister ($NM) interface... " >&6; } ++if ${lt_cv_nm_interface+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_nm_interface="BSD nm" ++ echo "int some_variable = 0;" > conftest.$ac_ext ++ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) ++ (eval "$ac_compile" 2>conftest.err) ++ cat conftest.err >&5 ++ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) ++ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) ++ cat conftest.err >&5 ++ (eval echo "\"\$as_me:$LINENO: output\"" >&5) ++ cat conftest.out >&5 ++ if $GREP 'External.*some_variable' conftest.out > /dev/null; then ++ lt_cv_nm_interface="MS dumpbin" ++ fi ++ rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 ++$as_echo "$lt_cv_nm_interface" >&6; } ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 ++$as_echo_n "checking whether ln -s works... " >&6; } ++LN_S=$as_ln_s ++if test "$LN_S" = "ln -s"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 ++$as_echo "no, using $LN_S" >&6; } ++fi ++ ++# find the maximum length of command line arguments ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 ++$as_echo_n "checking the maximum length of command line arguments... " >&6; } ++if ${lt_cv_sys_max_cmd_len+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ i=0 ++ teststring="ABCD" ++ ++ case $build_os in ++ msdosdjgpp*) ++ # On DJGPP, this test can blow up pretty badly due to problems in libc ++ # (any single argument exceeding 2000 bytes causes a buffer overrun ++ # during glob expansion). Even if it were fixed, the result of this ++ # check would be larger than it should be. ++ lt_cv_sys_max_cmd_len=12288; # 12K is about right ++ ;; ++ ++ gnu*) ++ # Under GNU Hurd, this test is not required because there is ++ # no limit to the length of command line arguments. ++ # Libtool will interpret -1 as no limit whatsoever ++ lt_cv_sys_max_cmd_len=-1; ++ ;; ++ ++ cygwin* | mingw* | cegcc*) ++ # On Win9x/ME, this test blows up -- it succeeds, but takes ++ # about 5 minutes as the teststring grows exponentially. ++ # Worse, since 9x/ME are not pre-emptively multitasking, ++ # you end up with a "frozen" computer, even though with patience ++ # the test eventually succeeds (with a max line length of 256k). ++ # Instead, let's just punt: use the minimum linelength reported by ++ # all of the supported platforms: 8192 (on NT/2K/XP). ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ mint*) ++ # On MiNT this can take a long time and run out of memory. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ amigaos*) ++ # On AmigaOS with pdksh, this test takes hours, literally. ++ # So we just punt and use a minimum line length of 8192. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) ++ # This has been around since 386BSD, at least. Likely further. ++ if test -x /sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` ++ elif test -x /usr/sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` ++ else ++ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs ++ fi ++ # And add a safety zone ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ ;; ++ ++ interix*) ++ # We know the value 262144 and hardcode it with a safety zone (like BSD) ++ lt_cv_sys_max_cmd_len=196608 ++ ;; ++ ++ osf*) ++ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure ++ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not ++ # nice to cause kernel panics so lets avoid the loop below. ++ # First set a reasonable default. ++ lt_cv_sys_max_cmd_len=16384 ++ # ++ if test -x /sbin/sysconfig; then ++ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in ++ *1*) lt_cv_sys_max_cmd_len=-1 ;; ++ esac ++ fi ++ ;; ++ sco3.2v5*) ++ lt_cv_sys_max_cmd_len=102400 ++ ;; ++ sysv5* | sco5v6* | sysv4.2uw2*) ++ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` ++ if test -n "$kargmax"; then ++ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` ++ else ++ lt_cv_sys_max_cmd_len=32768 ++ fi ++ ;; ++ *) ++ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` ++ if test -n "$lt_cv_sys_max_cmd_len"; then ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ else ++ # Make teststring a little bigger before we do anything with it. ++ # a 1K string should be a reasonable start. ++ for i in 1 2 3 4 5 6 7 8 ; do ++ teststring=$teststring$teststring ++ done ++ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ ++ = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ test $i != 17 # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ teststring=$teststring$teststring ++ done ++ # Only check the string length outside the loop. ++ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` ++ teststring= ++ # Add a significant safety factor because C++ compilers can tack on ++ # massive amounts of additional arguments before passing them to the ++ # linker. It appears as though 1/2 is a usable value. ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ++ fi ++ ;; ++ esac ++ ++fi ++ ++if test -n $lt_cv_sys_max_cmd_len ; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 ++$as_echo "$lt_cv_sys_max_cmd_len" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 ++$as_echo "none" >&6; } ++fi ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++ ++ ++ ++ ++ ++: ${CP="cp -f"} ++: ${MV="mv -f"} ++: ${RM="rm -f"} ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 ++$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } ++# Try some XSI features ++xsi_shell=no ++( _lt_dummy="a/b/c" ++ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ ++ = c,a/b,, \ ++ && eval 'test $(( 1 + 1 )) -eq 2 \ ++ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ ++ && xsi_shell=yes ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 ++$as_echo "$xsi_shell" >&6; } ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 ++$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } ++lt_shell_append=no ++( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ ++ >/dev/null 2>&1 \ ++ && lt_shell_append=yes ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 ++$as_echo "$lt_shell_append" >&6; } ++ ++ ++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then ++ lt_unset=unset ++else ++ lt_unset=false ++fi ++ ++ ++ ++ ++ ++# test EBCDIC or ASCII ++case `echo X|tr X '\101'` in ++ A) # ASCII based system ++ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr ++ lt_SP2NL='tr \040 \012' ++ lt_NL2SP='tr \015\012 \040\040' ++ ;; ++ *) # EBCDIC based system ++ lt_SP2NL='tr \100 \n' ++ lt_NL2SP='tr \r\n \100\100' ++ ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 ++$as_echo_n "checking for $LD option to reload object files... " >&6; } ++if ${lt_cv_ld_reload_flag+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_ld_reload_flag='-r' ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 ++$as_echo "$lt_cv_ld_reload_flag" >&6; } ++reload_flag=$lt_cv_ld_reload_flag ++case $reload_flag in ++"" | " "*) ;; ++*) reload_flag=" $reload_flag" ;; ++esac ++reload_cmds='$LD$reload_flag -o $output$reload_objs' ++case $host_os in ++ darwin*) ++ if test "$GCC" = yes; then ++ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' ++ else ++ reload_cmds='$LD$reload_flag -o $output$reload_objs' ++ fi ++ ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. ++set dummy ${ac_tool_prefix}objdump; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_OBJDUMP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$OBJDUMP"; then ++ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++OBJDUMP=$ac_cv_prog_OBJDUMP ++if test -n "$OBJDUMP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 ++$as_echo "$OBJDUMP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_OBJDUMP"; then ++ ac_ct_OBJDUMP=$OBJDUMP ++ # Extract the first word of "objdump", so it can be a program name with args. ++set dummy objdump; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_OBJDUMP"; then ++ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_OBJDUMP="objdump" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP ++if test -n "$ac_ct_OBJDUMP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 ++$as_echo "$ac_ct_OBJDUMP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_OBJDUMP" = x; then ++ OBJDUMP="false" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ OBJDUMP=$ac_ct_OBJDUMP ++ fi ++else ++ OBJDUMP="$ac_cv_prog_OBJDUMP" ++fi ++ ++test -z "$OBJDUMP" && OBJDUMP=objdump ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 ++$as_echo_n "checking how to recognize dependent libraries... " >&6; } ++if ${lt_cv_deplibs_check_method+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_file_magic_cmd='$MAGIC_CMD' ++lt_cv_file_magic_test_file= ++lt_cv_deplibs_check_method='unknown' ++# Need to set the preceding variable on all platforms that support ++# interlibrary dependencies. ++# 'none' -- dependencies not supported. ++# `unknown' -- same as none, but documents that we really don't know. ++# 'pass_all' -- all dependencies passed with no checks. ++# 'test_compile' -- check by making test program. ++# 'file_magic [[regex]]' -- check by looking for files in library path ++# which responds to the $file_magic_cmd with a given extended regex. ++# If you have `file' or equivalent on your system and you're not sure ++# whether `pass_all' will *always* work, you probably want this one. ++ ++case $host_os in ++aix[4-9]*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++beos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++bsdi[45]*) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' ++ lt_cv_file_magic_cmd='/usr/bin/file -L' ++ lt_cv_file_magic_test_file=/shlib/libc.so ++ ;; ++ ++cygwin*) ++ # func_win32_libid is a shell function defined in ltmain.sh ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ ;; ++ ++mingw* | pw32*) ++ # Base MSYS/MinGW do not provide the 'file' command needed by ++ # func_win32_libid shell function, so use a weaker test based on 'objdump', ++ # unless we find 'file', for example because we are cross-compiling. ++ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. ++ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ else ++ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ fi ++ ;; ++ ++cegcc*) ++ # use the weaker test based on 'objdump'. See mingw*. ++ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ ;; ++ ++darwin* | rhapsody*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++freebsd* | dragonfly*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then ++ case $host_cpu in ++ i*86 ) ++ # Not sure whether the presence of OpenBSD here was a mistake. ++ # Let's accept both of them until this is cleared up. ++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ++ ;; ++ esac ++ else ++ lt_cv_deplibs_check_method=pass_all ++ fi ++ ;; ++ ++gnu*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++haiku*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++hpux10.20* | hpux11*) ++ lt_cv_file_magic_cmd=/usr/bin/file ++ case $host_cpu in ++ ia64*) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' ++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ++ ;; ++ hppa*64*) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' ++ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ++ ;; ++ *) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' ++ lt_cv_file_magic_test_file=/usr/lib/libc.sl ++ ;; ++ esac ++ ;; ++ ++interix[3-9]*) ++ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $LD in ++ *-32|*"-32 ") libmagic=32-bit;; ++ *-n32|*"-n32 ") libmagic=N32;; ++ *-64|*"-64 ") libmagic=64-bit;; ++ *) libmagic=never-match;; ++ esac ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++# This must be Linux ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' ++ fi ++ ;; ++ ++newos6*) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=/usr/lib/libnls.so ++ ;; ++ ++*nto* | *qnx*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++openbsd*) ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' ++ fi ++ ;; ++ ++osf3* | osf4* | osf5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++rdos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++solaris*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv4 | sysv4.3*) ++ case $host_vendor in ++ motorola) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ++ ;; ++ ncr) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ sequent) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ++ ;; ++ sni) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" ++ lt_cv_file_magic_test_file=/lib/libc.so ++ ;; ++ siemens) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ pc) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ esac ++ ;; ++ ++tpf*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++esac ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 ++$as_echo "$lt_cv_deplibs_check_method" >&6; } ++file_magic_cmd=$lt_cv_file_magic_cmd ++deplibs_check_method=$lt_cv_deplibs_check_method ++test -z "$deplibs_check_method" && deplibs_check_method=unknown ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++plugin_option= ++plugin_names="liblto_plugin.so liblto_plugin-0.dll cyglto_plugin-0.dll" ++for plugin in $plugin_names; do ++ plugin_so=`${CC} ${CFLAGS} --print-prog-name $plugin` ++ if test x$plugin_so = x$plugin; then ++ plugin_so=`${CC} ${CFLAGS} --print-file-name $plugin` ++ fi ++ if test x$plugin_so != x$plugin; then ++ plugin_option="--plugin $plugin_so" ++ break ++ fi ++done ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ar; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_AR+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$AR"; then ++ ac_cv_prog_AR="$AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_AR="${ac_tool_prefix}ar" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++AR=$ac_cv_prog_AR ++if test -n "$AR"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 ++$as_echo "$AR" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_AR"; then ++ ac_ct_AR=$AR ++ # Extract the first word of "ar", so it can be a program name with args. ++set dummy ar; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_AR+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_AR"; then ++ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_AR="ar" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_AR=$ac_cv_prog_ac_ct_AR ++if test -n "$ac_ct_AR"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 ++$as_echo "$ac_ct_AR" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_AR" = x; then ++ AR="false" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ AR=$ac_ct_AR ++ fi ++else ++ AR="$ac_cv_prog_AR" ++fi ++ ++test -z "$AR" && AR=ar ++if test -n "$plugin_option"; then ++ if $AR --help 2>&1 | grep -q "\--plugin"; then ++ touch conftest.c ++ $AR $plugin_option rc conftest.a conftest.c ++ if test "$?" != 0; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5 ++$as_echo "$as_me: WARNING: Failed: $AR $plugin_option rc" >&2;} ++ else ++ AR="$AR $plugin_option" ++ fi ++ rm -f conftest.* ++ fi ++fi ++test -z "$AR_FLAGS" && AR_FLAGS=cru ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. ++set dummy ${ac_tool_prefix}strip; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_STRIP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$STRIP"; then ++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_STRIP="${ac_tool_prefix}strip" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++STRIP=$ac_cv_prog_STRIP ++if test -n "$STRIP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 ++$as_echo "$STRIP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_STRIP"; then ++ ac_ct_STRIP=$STRIP ++ # Extract the first word of "strip", so it can be a program name with args. ++set dummy strip; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_STRIP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_STRIP"; then ++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_STRIP="strip" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP ++if test -n "$ac_ct_STRIP"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 ++$as_echo "$ac_ct_STRIP" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_STRIP" = x; then ++ STRIP=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ STRIP=$ac_ct_STRIP ++ fi ++else ++ STRIP="$ac_cv_prog_STRIP" ++fi ++ ++test -z "$STRIP" && STRIP=: ++ ++ ++ ++ ++ ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ranlib; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_RANLIB+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$RANLIB"; then ++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++RANLIB=$ac_cv_prog_RANLIB ++if test -n "$RANLIB"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 ++$as_echo "$RANLIB" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_RANLIB"; then ++ ac_ct_RANLIB=$RANLIB ++ # Extract the first word of "ranlib", so it can be a program name with args. ++set dummy ranlib; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_RANLIB"; then ++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_RANLIB="ranlib" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB ++if test -n "$ac_ct_RANLIB"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 ++$as_echo "$ac_ct_RANLIB" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_RANLIB" = x; then ++ RANLIB=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ RANLIB=$ac_ct_RANLIB ++ fi ++else ++ RANLIB="$ac_cv_prog_RANLIB" ++fi ++ ++test -z "$RANLIB" && RANLIB=: ++if test -n "$plugin_option" && test "$RANLIB" != ":"; then ++ if $RANLIB --help 2>&1 | grep -q "\--plugin"; then ++ RANLIB="$RANLIB $plugin_option" ++ fi ++fi ++ ++ ++ ++ ++ ++ ++# Determine commands to create old-style static archives. ++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' ++old_postinstall_cmds='chmod 644 $oldlib' ++old_postuninstall_cmds= ++ ++if test -n "$RANLIB"; then ++ case $host_os in ++ openbsd*) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ++ ;; ++ *) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ++ ;; ++ esac ++ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" ++fi ++ ++case $host_os in ++ darwin*) ++ lock_old_archive_extraction=yes ;; ++ *) ++ lock_old_archive_extraction=no ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# Check for command to grab the raw symbol name followed by C symbol from nm. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 ++$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } ++if ${lt_cv_sys_global_symbol_pipe+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ++# These are sane defaults that work on at least a few old systems. ++# [They come from Ultrix. What could be older than Ultrix?!! ;)] ++ ++# Character class describing NM global symbol codes. ++symcode='[BCDEGRST]' ++ ++# Regexp to match symbols that can be accessed directly from C. ++sympat='\([_A-Za-z][_A-Za-z0-9]*\)' ++ ++# Define system-specific variables. ++case $host_os in ++aix*) ++ symcode='[BCDT]' ++ ;; ++cygwin* | mingw* | pw32* | cegcc*) ++ symcode='[ABCDGISTW]' ++ ;; ++hpux*) ++ if test "$host_cpu" = ia64; then ++ symcode='[ABCDEGRST]' ++ fi ++ ;; ++irix* | nonstopux*) ++ symcode='[BCDEGRST]' ++ ;; ++osf*) ++ symcode='[BCDEGQRST]' ++ ;; ++solaris*) ++ symcode='[BCDRT]' ++ ;; ++sco3.2v5*) ++ symcode='[DT]' ++ ;; ++sysv4.2uw2*) ++ symcode='[DT]' ++ ;; ++sysv5* | sco5v6* | unixware* | OpenUNIX*) ++ symcode='[ABDT]' ++ ;; ++sysv4) ++ symcode='[DFNSTU]' ++ ;; ++esac ++ ++# If we're using GNU nm, then use its standard symbol codes. ++case `$NM -V 2>&1` in ++*GNU* | *'with BFD'*) ++ symcode='[ABCDGIRSTW]' ;; ++esac ++ ++# Transform an extracted symbol line into a proper C declaration. ++# Some systems (esp. on ia64) link data and code symbols differently, ++# so use this general approach. ++lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" ++ ++# Transform an extracted symbol line into symbol name and symbol address ++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" ++ ++# Handle CRLF in mingw tool chain ++opt_cr= ++case $build_os in ++mingw*) ++ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ++ ;; ++esac ++ ++# Try without a prefix underscore, then with it. ++for ac_symprfx in "" "_"; do ++ ++ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. ++ symxfrm="\\1 $ac_symprfx\\2 \\2" ++ ++ # Write the raw and C identifiers. ++ if test "$lt_cv_nm_interface" = "MS dumpbin"; then ++ # Fake it for dumpbin and say T for any non-static function ++ # and D for any global variable. ++ # Also find C++ and __fastcall symbols from MSVC++, ++ # which start with @ or ?. ++ lt_cv_sys_global_symbol_pipe="$AWK '"\ ++" {last_section=section; section=\$ 3};"\ ++" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ ++" \$ 0!~/External *\|/{next};"\ ++" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ ++" {if(hide[section]) next};"\ ++" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ ++" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ ++" s[1]~/^[@?]/{print s[1], s[1]; next};"\ ++" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ ++" ' prfx=^$ac_symprfx" ++ else ++ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" ++ fi ++ ++ # Check to see that the pipe works correctly. ++ pipe_works=no ++ ++ rm -f conftest* ++ cat > conftest.$ac_ext <<_LT_EOF ++#ifdef __cplusplus ++extern "C" { ++#endif ++char nm_test_var; ++void nm_test_func(void); ++void nm_test_func(void){} ++#ifdef __cplusplus ++} ++#endif ++int main(){nm_test_var='a';nm_test_func();return(0);} ++_LT_EOF ++ ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ # Now try to grab the symbols. ++ nlist=conftest.nm ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 ++ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && test -s "$nlist"; then ++ # Try sorting and uniquifying the output. ++ if sort "$nlist" | uniq > "$nlist"T; then ++ mv -f "$nlist"T "$nlist" ++ else ++ rm -f "$nlist"T ++ fi ++ ++ # Make sure that we snagged all the symbols we need. ++ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then ++ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then ++ cat <<_LT_EOF > conftest.$ac_ext ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++_LT_EOF ++ # Now generate the symbol file. ++ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' ++ ++ cat <<_LT_EOF >> conftest.$ac_ext ++ ++/* The mapping between symbol names and symbols. */ ++const struct { ++ const char *name; ++ void *address; ++} ++lt__PROGRAM__LTX_preloaded_symbols[] = ++{ ++ { "@PROGRAM@", (void *) 0 }, ++_LT_EOF ++ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext ++ cat <<\_LT_EOF >> conftest.$ac_ext ++ {0, (void *) 0} ++}; ++ ++/* This works around a problem in FreeBSD linker */ ++#ifdef FREEBSD_WORKAROUND ++static const void *lt_preloaded_setup() { ++ return lt__PROGRAM__LTX_preloaded_symbols; ++} ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++_LT_EOF ++ # Now try linking the two files. ++ mv conftest.$ac_objext conftstm.$ac_objext ++ lt_save_LIBS="$LIBS" ++ lt_save_CFLAGS="$CFLAGS" ++ LIBS="conftstm.$ac_objext" ++ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && test -s conftest${ac_exeext}; then ++ pipe_works=yes ++ fi ++ LIBS="$lt_save_LIBS" ++ CFLAGS="$lt_save_CFLAGS" ++ else ++ echo "cannot find nm_test_func in $nlist" >&5 ++ fi ++ else ++ echo "cannot find nm_test_var in $nlist" >&5 ++ fi ++ else ++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 ++ fi ++ else ++ echo "$progname: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ fi ++ rm -rf conftest* conftst* ++ ++ # Do not use the global_symbol_pipe unless it works. ++ if test "$pipe_works" = yes; then ++ break ++ else ++ lt_cv_sys_global_symbol_pipe= ++ fi ++done ++ ++fi ++ ++if test -z "$lt_cv_sys_global_symbol_pipe"; then ++ lt_cv_sys_global_symbol_to_cdecl= ++fi ++if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 ++$as_echo "failed" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 ++$as_echo "ok" >&6; } ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# Check whether --enable-libtool-lock was given. ++if test "${enable_libtool_lock+set}" = set; then : ++ enableval=$enable_libtool_lock; ++fi ++ ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++# Some flags need to be propagated to the compiler or linker for good ++# libtool support. ++case $host in ++ia64-*-hpux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *ELF-32*) ++ HPUX_IA64_MODE="32" ++ ;; ++ *ELF-64*) ++ HPUX_IA64_MODE="64" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++*-*-irix6*) ++ # Find out which ABI we are using. ++ echo '#line '$LINENO' "configure"' > conftest.$ac_ext ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -melf32bsmip" ++ ;; ++ *N32*) ++ LD="${LD-ld} -melf32bmipn32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -melf64bmip" ++ ;; ++ esac ++ else ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -32" ++ ;; ++ *N32*) ++ LD="${LD-ld} -n32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -64" ++ ;; ++ esac ++ fi ++ fi ++ rm -rf conftest* ++ ;; ++ ++x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ ++s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ case `/usr/bin/file conftest.o` in ++ *32-bit*) ++ case $host in ++ x86_64-*kfreebsd*-gnu) ++ LD="${LD-ld} -m elf_i386_fbsd" ++ ;; ++ x86_64-*linux*) ++ case `/usr/bin/file conftest.o` in ++ *x86-64*) ++ LD="${LD-ld} -m elf32_x86_64" ++ ;; ++ *) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++ esac ++ ;; ++ powerpc64le-*linux*) ++ LD="${LD-ld} -m elf32lppclinux" ++ ;; ++ powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++ LD="${LD-ld} -m elf_s390" ++ ;; ++ sparc64-*linux*) ++ LD="${LD-ld} -m elf32_sparc" ++ ;; ++ esac ++ ;; ++ *64-bit*) ++ case $host in ++ x86_64-*kfreebsd*-gnu) ++ LD="${LD-ld} -m elf_x86_64_fbsd" ++ ;; ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ powerpcle-*linux*) ++ LD="${LD-ld} -m elf64lppc" ++ ;; ++ powerpc-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*|s390*-*tpf*) ++ LD="${LD-ld} -m elf64_s390" ++ ;; ++ sparc*-*linux*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++*-*-sco3.2v5*) ++ # On SCO OpenServer 5, we need -belf to get full-featured binaries. ++ SAVE_CFLAGS="$CFLAGS" ++ CFLAGS="$CFLAGS -belf" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 ++$as_echo_n "checking whether the C compiler needs -belf... " >&6; } ++if ${lt_cv_cc_needs_belf+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ lt_cv_cc_needs_belf=yes ++else ++ lt_cv_cc_needs_belf=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 ++$as_echo "$lt_cv_cc_needs_belf" >&6; } ++ if test x"$lt_cv_cc_needs_belf" != x"yes"; then ++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf ++ CFLAGS="$SAVE_CFLAGS" ++ fi ++ ;; ++sparc*-*solaris*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ case `/usr/bin/file conftest.o` in ++ *64-bit*) ++ case $lt_cv_prog_gnu_ld in ++ yes*) LD="${LD-ld} -m elf64_sparc" ;; ++ *) ++ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then ++ LD="${LD-ld} -64" ++ fi ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++esac ++ ++need_locks="$enable_libtool_lock" ++ ++ ++ case $host_os in ++ rhapsody* | darwin*) ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. ++set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_DSYMUTIL+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$DSYMUTIL"; then ++ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++DSYMUTIL=$ac_cv_prog_DSYMUTIL ++if test -n "$DSYMUTIL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 ++$as_echo "$DSYMUTIL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_DSYMUTIL"; then ++ ac_ct_DSYMUTIL=$DSYMUTIL ++ # Extract the first word of "dsymutil", so it can be a program name with args. ++set dummy dsymutil; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_DSYMUTIL"; then ++ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL ++if test -n "$ac_ct_DSYMUTIL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 ++$as_echo "$ac_ct_DSYMUTIL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_DSYMUTIL" = x; then ++ DSYMUTIL=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ DSYMUTIL=$ac_ct_DSYMUTIL ++ fi ++else ++ DSYMUTIL="$ac_cv_prog_DSYMUTIL" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. ++set dummy ${ac_tool_prefix}nmedit; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_NMEDIT+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$NMEDIT"; then ++ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++NMEDIT=$ac_cv_prog_NMEDIT ++if test -n "$NMEDIT"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 ++$as_echo "$NMEDIT" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_NMEDIT"; then ++ ac_ct_NMEDIT=$NMEDIT ++ # Extract the first word of "nmedit", so it can be a program name with args. ++set dummy nmedit; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_NMEDIT"; then ++ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_NMEDIT="nmedit" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT ++if test -n "$ac_ct_NMEDIT"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 ++$as_echo "$ac_ct_NMEDIT" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_NMEDIT" = x; then ++ NMEDIT=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ NMEDIT=$ac_ct_NMEDIT ++ fi ++else ++ NMEDIT="$ac_cv_prog_NMEDIT" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. ++set dummy ${ac_tool_prefix}lipo; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_LIPO+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$LIPO"; then ++ ac_cv_prog_LIPO="$LIPO" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_LIPO="${ac_tool_prefix}lipo" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++LIPO=$ac_cv_prog_LIPO ++if test -n "$LIPO"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 ++$as_echo "$LIPO" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_LIPO"; then ++ ac_ct_LIPO=$LIPO ++ # Extract the first word of "lipo", so it can be a program name with args. ++set dummy lipo; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_LIPO+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_LIPO"; then ++ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_LIPO="lipo" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO ++if test -n "$ac_ct_LIPO"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 ++$as_echo "$ac_ct_LIPO" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_LIPO" = x; then ++ LIPO=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ LIPO=$ac_ct_LIPO ++ fi ++else ++ LIPO="$ac_cv_prog_LIPO" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. ++set dummy ${ac_tool_prefix}otool; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_OTOOL+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$OTOOL"; then ++ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_OTOOL="${ac_tool_prefix}otool" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++OTOOL=$ac_cv_prog_OTOOL ++if test -n "$OTOOL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 ++$as_echo "$OTOOL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_OTOOL"; then ++ ac_ct_OTOOL=$OTOOL ++ # Extract the first word of "otool", so it can be a program name with args. ++set dummy otool; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_OTOOL"; then ++ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_OTOOL="otool" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL ++if test -n "$ac_ct_OTOOL"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 ++$as_echo "$ac_ct_OTOOL" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_OTOOL" = x; then ++ OTOOL=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ OTOOL=$ac_ct_OTOOL ++ fi ++else ++ OTOOL="$ac_cv_prog_OTOOL" ++fi ++ ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. ++set dummy ${ac_tool_prefix}otool64; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_OTOOL64+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$OTOOL64"; then ++ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++OTOOL64=$ac_cv_prog_OTOOL64 ++if test -n "$OTOOL64"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 ++$as_echo "$OTOOL64" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_prog_OTOOL64"; then ++ ac_ct_OTOOL64=$OTOOL64 ++ # Extract the first word of "otool64", so it can be a program name with args. ++set dummy otool64; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$ac_ct_OTOOL64"; then ++ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_OTOOL64="otool64" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 ++if test -n "$ac_ct_OTOOL64"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 ++$as_echo "$ac_ct_OTOOL64" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_ct_OTOOL64" = x; then ++ OTOOL64=":" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ OTOOL64=$ac_ct_OTOOL64 ++ fi ++else ++ OTOOL64="$ac_cv_prog_OTOOL64" ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 ++$as_echo_n "checking for -single_module linker flag... " >&6; } ++if ${lt_cv_apple_cc_single_mod+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_apple_cc_single_mod=no ++ if test -z "${LT_MULTI_MODULE}"; then ++ # By default we will add the -single_module flag. You can override ++ # by either setting the environment variable LT_MULTI_MODULE ++ # non-empty at configure time, or by adding -multi_module to the ++ # link flags. ++ rm -rf libconftest.dylib* ++ echo "int foo(void){return 1;}" > conftest.c ++ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ ++-dynamiclib -Wl,-single_module conftest.c" >&5 ++ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ ++ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err ++ _lt_result=$? ++ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then ++ lt_cv_apple_cc_single_mod=yes ++ else ++ cat conftest.err >&5 ++ fi ++ rm -rf libconftest.dylib* ++ rm -f conftest.* ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 ++$as_echo "$lt_cv_apple_cc_single_mod" >&6; } ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 ++$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } ++if ${lt_cv_ld_exported_symbols_list+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_ld_exported_symbols_list=no ++ save_LDFLAGS=$LDFLAGS ++ echo "_main" > conftest.sym ++ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ lt_cv_ld_exported_symbols_list=yes ++else ++ lt_cv_ld_exported_symbols_list=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 ++$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 ++$as_echo_n "checking for -force_load linker flag... " >&6; } ++if ${lt_cv_ld_force_load+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_ld_force_load=no ++ cat > conftest.c << _LT_EOF ++int forced_loaded() { return 2;} ++_LT_EOF ++ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 ++ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 ++ echo "$AR cru libconftest.a conftest.o" >&5 ++ $AR cru libconftest.a conftest.o 2>&5 ++ cat > conftest.c << _LT_EOF ++int main() { return 0;} ++_LT_EOF ++ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 ++ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err ++ _lt_result=$? ++ if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then ++ lt_cv_ld_force_load=yes ++ else ++ cat conftest.err >&5 ++ fi ++ rm -f conftest.err libconftest.a conftest conftest.c ++ rm -rf conftest.dSYM ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 ++$as_echo "$lt_cv_ld_force_load" >&6; } ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; ++ darwin1.*) ++ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; ++ darwin*) # darwin 5.x on ++ # if running on 10.5 or later, the deployment target defaults ++ # to the OS version, if on x86, and 10.4, the deployment ++ # target defaults to 10.4. Don't you love it? ++ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in ++ 10.0,*86*-darwin8*|10.0,*-darwin[91]*) ++ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; ++ 10.[012][,.]*) ++ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; ++ 10.*) ++ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; ++ esac ++ ;; ++ esac ++ if test "$lt_cv_apple_cc_single_mod" = "yes"; then ++ _lt_dar_single_mod='$single_module' ++ fi ++ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then ++ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' ++ else ++ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ fi ++ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then ++ _lt_dsymutil='~$DSYMUTIL $lib || :' ++ else ++ _lt_dsymutil= ++ fi ++ ;; ++ esac ++ ++for ac_header in dlfcn.h ++do : ++ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default ++" ++if test "x$ac_cv_header_dlfcn_h" = xyes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_DLFCN_H 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ ++ ++ ++ ++ ++# Set options ++ ++ ++ ++ enable_dlopen=no ++ ++ ++ enable_win32_dll=no ++ ++ ++ # Check whether --enable-shared was given. ++if test "${enable_shared+set}" = set; then : ++ enableval=$enable_shared; p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_shared=yes ;; ++ no) enable_shared=no ;; ++ *) ++ enable_shared=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_shared=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_shared=yes ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ # Check whether --enable-static was given. ++if test "${enable_static+set}" = set; then : ++ enableval=$enable_static; p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_static=yes ;; ++ no) enable_static=no ;; ++ *) ++ enable_static=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_static=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_static=yes ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# Check whether --with-pic was given. ++if test "${with_pic+set}" = set; then : ++ withval=$with_pic; pic_mode="$withval" ++else ++ pic_mode=default ++fi ++ ++ ++test -z "$pic_mode" && pic_mode=default ++ ++ ++ ++ ++ ++ ++ ++ # Check whether --enable-fast-install was given. ++if test "${enable_fast_install+set}" = set; then : ++ enableval=$enable_fast_install; p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_fast_install=yes ;; ++ no) enable_fast_install=no ;; ++ *) ++ enable_fast_install=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_fast_install=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_fast_install=yes ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# This can be used to rebuild libtool when needed ++LIBTOOL_DEPS="$ltmain" ++ ++# Always use our own libtool. ++LIBTOOL='$(SHELL) $(top_builddir)/libtool' ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++test -z "$LN_S" && LN_S="ln -s" ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 ++$as_echo_n "checking for objdir... " >&6; } ++if ${lt_cv_objdir+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ rm -f .libs 2>/dev/null ++mkdir .libs 2>/dev/null ++if test -d .libs; then ++ lt_cv_objdir=.libs ++else ++ # MS-DOS does not allow filenames that begin with a dot. ++ lt_cv_objdir=_libs ++fi ++rmdir .libs 2>/dev/null ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 ++$as_echo "$lt_cv_objdir" >&6; } ++objdir=$lt_cv_objdir ++ ++ ++ ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define LT_OBJDIR "$lt_cv_objdir/" ++_ACEOF ++ ++ ++ ++ ++case $host_os in ++aix3*) ++ # AIX sometimes has problems with the GCC collect2 program. For some ++ # reason, if we set the COLLECT_NAMES environment variable, the problems ++ # vanish in a puff of smoke. ++ if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++ fi ++ ;; ++esac ++ ++# Global variables: ++ofile=libtool ++can_build_shared=yes ++ ++# All known linkers require a `.a' archive for static linking (except MSVC, ++# which needs '.lib'). ++libext=a ++ ++with_gnu_ld="$lt_cv_prog_gnu_ld" ++ ++old_CC="$CC" ++old_CFLAGS="$CFLAGS" ++ ++# Set sane defaults for various variables ++test -z "$CC" && CC=cc ++test -z "$LTCC" && LTCC=$CC ++test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS ++test -z "$LD" && LD=ld ++test -z "$ac_objext" && ac_objext=o ++ ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++ ++ ++# Only perform the check for file, if the check method requires it ++test -z "$MAGIC_CMD" && MAGIC_CMD=file ++case $deplibs_check_method in ++file_magic*) ++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 ++$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } ++if ${lt_cv_path_MAGIC_CMD+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $MAGIC_CMD in ++[\\/*] | ?:[\\/]*) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/${ac_tool_prefix}file; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++_LT_EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac ++fi ++ ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 ++$as_echo "$MAGIC_CMD" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ ++ ++ ++if test -z "$lt_cv_path_MAGIC_CMD"; then ++ if test -n "$ac_tool_prefix"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 ++$as_echo_n "checking for file... " >&6; } ++if ${lt_cv_path_MAGIC_CMD+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $MAGIC_CMD in ++[\\/*] | ?:[\\/]*) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/file; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/file" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++_LT_EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac ++fi ++ ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 ++$as_echo "$MAGIC_CMD" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ else ++ MAGIC_CMD=: ++ fi ++fi ++ ++ fi ++ ;; ++esac ++ ++# Use C for the default configuration in the libtool script ++ ++lt_save_CC="$CC" ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++# Source file extension for C test sources. ++ac_ext=c ++ ++# Object file extension for compiled C test sources. ++objext=o ++objext=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(){return(0);}' ++ ++ ++ ++ ++ ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++# Save the default compiler, since it gets overwritten when the other ++# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. ++compiler_DEFAULT=$CC ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++echo "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$RM conftest* ++ ++ac_outfile=conftest.$ac_objext ++echo "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$RM -r conftest* ++ ++ ++## CAVEAT EMPTOR: ++## There is no encapsulation within the following macros, do not change ++## the running order or otherwise move them around unless you know exactly ++## what you are doing... ++if test -n "$compiler"; then ++ ++lt_prog_compiler_no_builtin_flag= ++ ++if test "$GCC" = yes; then ++ case $cc_basename in ++ nvcc*) ++ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; ++ *) ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; ++ esac ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 ++$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } ++if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_rtti_exceptions=no ++ ac_outfile=conftest.$ac_objext ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="-fno-rtti -fno-exceptions" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_rtti_exceptions=yes ++ fi ++ fi ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 ++$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } ++ ++if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then ++ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" ++else ++ : ++fi ++ ++fi ++ ++ ++ ++ ++ ++ ++ lt_prog_compiler_wl= ++lt_prog_compiler_pic= ++lt_prog_compiler_static= ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 ++$as_echo_n "checking for $compiler option to produce PIC... " >&6; } ++ ++ if test "$GCC" = yes; then ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_static='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static='-Bstatic' ++ fi ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ m68k) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ esac ++ ;; ++ ++ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | cygwin* | pw32* | os2* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ # Although the cygwin gcc ignores -fPIC, still need this for old-style ++ # (--disable-auto-import) libraries ++ lt_prog_compiler_pic='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic='-fno-common' ++ ;; ++ ++ haiku*) ++ # PIC is the default for Haiku. ++ # The "-static" flag exists, but is broken. ++ lt_prog_compiler_static= ++ ;; ++ ++ hpux*) ++ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit ++ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag ++ # sets the default TLS model and affects inlining. ++ case $host_cpu in ++ hppa*64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ interix[3-9]*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ lt_prog_compiler_can_build_shared=no ++ enable_shared=no ++ ;; ++ ++ *nto* | *qnx*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ lt_prog_compiler_pic='-fPIC -shared' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic=-Kconform_pic ++ fi ++ ;; ++ ++ *) ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ esac ++ ++ case $cc_basename in ++ nvcc*) # Cuda Compiler Driver 2.2 ++ lt_prog_compiler_wl='-Xlinker ' ++ lt_prog_compiler_pic='-Xcompiler -fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ lt_prog_compiler_wl='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static='-Bstatic' ++ else ++ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ ++ mingw* | cygwin* | pw32* | os2* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ lt_prog_compiler_wl='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ lt_prog_compiler_static='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ lt_prog_compiler_wl='-Wl,' ++ # PIC (with -KPIC) is the default. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ linux* | k*bsd*-gnu | kopensolaris*-gnu) ++ case $cc_basename in ++ # old Intel for x86_64 which still supported -KPIC. ++ ecc*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-static' ++ ;; ++ # icc used to be incompatible with GCC. ++ # ICC 10 doesn't accept -KPIC any more. ++ icc* | ifort*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-fPIC' ++ lt_prog_compiler_static='-static' ++ ;; ++ # Lahey Fortran 8.1. ++ lf95*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='--shared' ++ lt_prog_compiler_static='--static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-fpic' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ccc*) ++ lt_prog_compiler_wl='-Wl,' ++ # All Alpha code is PIC. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ xl* | bgxl* | bgf* | mpixl*) ++ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-qpic' ++ lt_prog_compiler_static='-qstaticlink' ++ ;; ++ *) ++ case `$CC -V 2>&1 | sed 5q` in ++ *Sun\ F* | *Sun*Fortran*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='' ++ ;; ++ *Sun\ C*) ++ # Sun C 5.9 ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ lt_prog_compiler_wl='-Wl,' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ ++ newsos6) ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ *nto* | *qnx*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ lt_prog_compiler_pic='-fPIC -shared' ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ lt_prog_compiler_wl='-Wl,' ++ # All OSF/1 code is PIC. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ rdos*) ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ solaris*) ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ lt_prog_compiler_wl='-Qoption ld ';; ++ *) ++ lt_prog_compiler_wl='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ lt_prog_compiler_wl='-Qoption ld ' ++ lt_prog_compiler_pic='-PIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ lt_prog_compiler_pic='-Kconform_pic' ++ lt_prog_compiler_static='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ unicos*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_can_build_shared=no ++ ;; ++ ++ uts4*) ++ lt_prog_compiler_pic='-pic' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ *) ++ lt_prog_compiler_can_build_shared=no ++ ;; ++ esac ++ fi ++ ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic= ++ ;; ++ *) ++ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ++ ;; ++esac ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 ++$as_echo "$lt_prog_compiler_pic" >&6; } ++ ++ ++ ++ ++ ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 ++$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } ++if ${lt_cv_prog_compiler_pic_works+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_pic_works=no ++ ac_outfile=conftest.$ac_objext ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_pic_works=yes ++ fi ++ fi ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 ++$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } ++ ++if test x"$lt_cv_prog_compiler_pic_works" = xyes; then ++ case $lt_prog_compiler_pic in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; ++ esac ++else ++ lt_prog_compiler_pic= ++ lt_prog_compiler_can_build_shared=no ++fi ++ ++fi ++ ++ ++ ++ ++ ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } ++if ${lt_cv_prog_compiler_static_works+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_static_works=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ echo "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_static_works=yes ++ fi ++ else ++ lt_cv_prog_compiler_static_works=yes ++ fi ++ fi ++ $RM -r conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 ++$as_echo "$lt_cv_prog_compiler_static_works" >&6; } ++ ++if test x"$lt_cv_prog_compiler_static_works" = xyes; then ++ : ++else ++ lt_prog_compiler_static= ++fi ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 ++$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } ++if ${lt_cv_prog_compiler_c_o+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_c_o=no ++ $RM -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $RM conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files ++ $RM out/* && rmdir out ++ cd .. ++ $RM -r conftest ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 ++$as_echo "$lt_cv_prog_compiler_c_o" >&6; } ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 ++$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } ++if ${lt_cv_prog_compiler_c_o+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_c_o=no ++ $RM -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $RM conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files ++ $RM out/* && rmdir out ++ cd .. ++ $RM -r conftest ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 ++$as_echo "$lt_cv_prog_compiler_c_o" >&6; } ++ ++ ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 ++$as_echo_n "checking if we can lock with hard links... " >&6; } ++ hard_links=yes ++ $RM conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 ++$as_echo "$hard_links" >&6; } ++ if test "$hard_links" = no; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 ++$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ++ ++ runpath_var= ++ allow_undefined_flag= ++ always_export_symbols=no ++ archive_cmds= ++ archive_expsym_cmds= ++ compiler_needs_object=no ++ enable_shared_with_static_runtimes=no ++ export_dynamic_flag_spec= ++ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ hardcode_automatic=no ++ hardcode_direct=no ++ hardcode_direct_absolute=no ++ hardcode_libdir_flag_spec= ++ hardcode_libdir_flag_spec_ld= ++ hardcode_libdir_separator= ++ hardcode_minus_L=no ++ hardcode_shlibpath_var=unsupported ++ inherit_rpath=no ++ link_all_deplibs=unknown ++ module_cmds= ++ module_expsym_cmds= ++ old_archive_from_new_cmds= ++ old_archive_from_expsyms_cmds= ++ thread_safe_flag_spec= ++ whole_archive_flag_spec= ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ include_expsyms= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ # Exclude shared library initialization/finalization symbols. ++ extract_expsyms_cmds= ++ ++ case $host_os in ++ cygwin* | mingw* | pw32* | cegcc*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ ld_shlibs=yes ++ ++ # On some targets, GNU ld is compatible enough with the native linker ++ # that we're better off using the native interface for both. ++ lt_use_gnu_ld_interface=no ++ if test "$with_gnu_ld" = yes; then ++ case $host_os in ++ aix*) ++ # The AIX port of GNU ld has always aspired to compatibility ++ # with the native linker. However, as the warning in the GNU ld ++ # block says, versions before 2.19.5* couldn't really create working ++ # shared libraries, regardless of the interface used. ++ case `$LD -v 2>&1` in ++ *\ \(GNU\ Binutils\)\ 2.19.5*) ;; ++ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; ++ *\ \(GNU\ Binutils\)\ [3-9]*) ;; ++ *) ++ lt_use_gnu_ld_interface=yes ++ ;; ++ esac ++ ;; ++ *) ++ lt_use_gnu_ld_interface=yes ++ ;; ++ esac ++ fi ++ ++ if test "$lt_use_gnu_ld_interface" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ export_dynamic_flag_spec='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>&1` in ++ *GNU\ gold*) supports_anon_versioning=yes ;; ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix[3-9]*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ ld_shlibs=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to install binutils ++*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. ++*** You will then need to restart the configuration process. ++ ++_LT_EOF ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='' ++ ;; ++ m68k) ++ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ ;; ++ esac ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec='-L$libdir' ++ export_dynamic_flag_spec='${wl}--export-all-symbols' ++ allow_undefined_flag=unsupported ++ always_export_symbols=no ++ enable_shared_with_static_runtimes=yes ++ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ haiku*) ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ link_all_deplibs=yes ++ ;; ++ ++ interix[3-9]*) ++ hardcode_direct=no ++ hardcode_shlibpath_var=no ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ ++ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) ++ tmp_diet=no ++ if test "$host_os" = linux-dietlibc; then ++ case $cc_basename in ++ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) ++ esac ++ fi ++ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ ++ && test "$tmp_diet" = no ++ then ++ tmp_addflag=' $pic_flag' ++ tmp_sharedflag='-shared' ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95* | pgfortran*) ++ # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ lf95*) # Lahey Fortran 8.1 ++ whole_archive_flag_spec= ++ tmp_sharedflag='--shared' ;; ++ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ tmp_sharedflag='-qmkshrobj' ++ tmp_addflag= ;; ++ nvcc*) # Cuda Compiler Driver 2.2 ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ compiler_needs_object=yes ++ ;; ++ esac ++ case `$CC -V 2>&1 | sed 5q` in ++ *Sun\ C*) # Sun C 5.9 ++ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ compiler_needs_object=yes ++ tmp_sharedflag='-G' ;; ++ *Sun\ F*) # Sun Fortran 8.3 ++ tmp_sharedflag='-G' ;; ++ esac ++ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test "x$supports_anon_versioning" = xyes; then ++ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ ++ case $cc_basename in ++ xlf* | bgf* | bgxlf* | mpixlf*) ++ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself ++ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' ++ hardcode_libdir_flag_spec= ++ hardcode_libdir_flag_spec_ld='-rpath $libdir' ++ archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' ++ if test "x$supports_anon_versioning" = xyes; then ++ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' ++ fi ++ ;; ++ esac ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ++ ld_shlibs=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ++ ld_shlibs=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ # For security reasons, it is highly recommended that you always ++ # use absolute paths for naming shared libraries, and exclude the ++ # DT_RUNPATH tag from executables and libraries. But doing so ++ # requires that you compile everything twice, which is a pain. ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ esac ++ ++ if test "$ld_shlibs" = no; then ++ runpath_var= ++ hardcode_libdir_flag_spec= ++ export_dynamic_flag_spec= ++ whole_archive_flag_spec= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ allow_undefined_flag=unsupported ++ always_export_symbols=yes ++ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ hardcode_minus_L=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ hardcode_direct=unsupported ++ fi ++ ;; ++ ++ aix[4-9]*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ # Also, AIX nm treats weak defined symbols like other global ++ # defined symbols, whereas GNU nm marks them as "W". ++ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds='' ++ hardcode_direct=yes ++ hardcode_direct_absolute=yes ++ hardcode_libdir_separator=':' ++ link_all_deplibs=yes ++ file_list_spec='${wl}-f,' ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && ++ strings "$collect2name" | $GREP resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ : ++ else ++ # We have old collect2 ++ hardcode_direct=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L=yes ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_libdir_separator= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ export_dynamic_flag_spec='${wl}-bexpall' ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag='-berok' ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ++lt_aix_libpath_sed=' ++ /Import File Strings/,/^$/ { ++ /^0/ { ++ s/^0 *\(.*\)$/\1/ ++ p ++ } ++ }' ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then ++ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" ++ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag="-z nodefs" ++ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ++lt_aix_libpath_sed=' ++ /Import File Strings/,/^$/ { ++ /^0/ { ++ s/^0 *\(.*\)$/\1/ ++ p ++ } ++ }' ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then ++ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag=' ${wl}-bernotok' ++ allow_undefined_flag=' ${wl}-berok' ++ if test "$with_gnu_ld" = yes; then ++ # We only use this code for GNU lds that support --whole-archive. ++ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ++ else ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' ++ fi ++ archive_cmds_need_lc=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='' ++ ;; ++ m68k) ++ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ ;; ++ esac ++ ;; ++ ++ bsdi[45]*) ++ export_dynamic_flag_spec=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ hardcode_libdir_flag_spec=' ' ++ allow_undefined_flag=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ old_archive_from_new_cmds='true' ++ # FIXME: Should let the user specify the lib program. ++ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' ++ fix_srcfile_path='`cygpath -w "$srcfile"`' ++ enable_shared_with_static_runtimes=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ ++ ++ archive_cmds_need_lc=no ++ hardcode_direct=no ++ hardcode_automatic=yes ++ hardcode_shlibpath_var=unsupported ++ if test "$lt_cv_ld_force_load" = "yes"; then ++ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' ++ else ++ whole_archive_flag_spec='' ++ fi ++ link_all_deplibs=yes ++ allow_undefined_flag="$_lt_dar_allow_undefined" ++ case $cc_basename in ++ ifort*) _lt_dar_can_shared=yes ;; ++ *) _lt_dar_can_shared=$GCC ;; ++ esac ++ if test "$_lt_dar_can_shared" = "yes"; then ++ output_verbose_link_cmd=func_echo_all ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ ++ else ++ ld_shlibs=no ++ fi ++ ++ ;; ++ ++ dgux*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2.*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes ++ hardcode_minus_L=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | dragonfly*) ++ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ hardcode_direct=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_flag_spec_ld='+b $libdir' ++ hardcode_libdir_separator=: ++ hardcode_direct=yes ++ hardcode_direct_absolute=yes ++ export_dynamic_flag_spec='${wl}-E' ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes && test "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ ++ # Older versions of the 11.00 compiler do not understand -b yet ++ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 ++$as_echo_n "checking if $CC understands -b... " >&6; } ++if ${lt_cv_prog_compiler__b+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler__b=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS -b" ++ echo "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler__b=yes ++ fi ++ else ++ lt_cv_prog_compiler__b=yes ++ fi ++ fi ++ $RM -r conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 ++$as_echo "$lt_cv_prog_compiler__b" >&6; } ++ ++if test x"$lt_cv_prog_compiler__b" = xyes; then ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++else ++ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++fi ++ ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_direct=no ++ hardcode_shlibpath_var=no ++ ;; ++ *) ++ hardcode_direct=yes ++ hardcode_direct_absolute=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ # Try to use the -exported_symbol ld option, if it does not ++ # work, assume that -exports_file does not work either and ++ # implicitly export all symbols. ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++int foo(void) {} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ++ ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS="$save_LDFLAGS" ++ else ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' ++ fi ++ archive_cmds_need_lc='no' ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ inherit_rpath=yes ++ link_all_deplibs=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ newsos6) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *nto* | *qnx*) ++ ;; ++ ++ openbsd*) ++ if test -f /usr/libexec/ld.so; then ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ hardcode_direct_absolute=yes ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec='${wl}-E' ++ else ++ case $host_os in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-R$libdir' ++ ;; ++ *) ++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ os2*) ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ allow_undefined_flag=unsupported ++ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ allow_undefined_flag=' -expect_unresolved \*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ archive_cmds_need_lc='no' ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ else ++ allow_undefined_flag=' -expect_unresolved \*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ ++ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ hardcode_libdir_flag_spec='-rpath $libdir' ++ fi ++ archive_cmds_need_lc='no' ++ hardcode_libdir_separator=: ++ ;; ++ ++ solaris*) ++ no_undefined_flag=' -z defs' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ++ else ++ case `$CC -V 2>&1` in ++ *"Compilers 5.0"*) ++ wlarc='' ++ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ++ ;; ++ *) ++ wlarc='${wl}' ++ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ++ ;; ++ esac ++ fi ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_shlibpath_var=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine and reorder linker options, ++ # but understands `-z linker_flag'. GCC discards it without `$wl', ++ # but is careful enough not to reorder. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ if test "$GCC" = yes; then ++ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ++ else ++ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ++ fi ++ ;; ++ esac ++ link_all_deplibs=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_direct=yes ++ hardcode_minus_L=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ reload_cmds='$CC -r -o $output$reload_objs' ++ hardcode_direct=no ++ ;; ++ motorola) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ sysv4.3*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var=no ++ export_dynamic_flag_spec='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ ld_shlibs=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ++ no_undefined_flag='${wl}-z,text' ++ archive_cmds_need_lc=no ++ hardcode_shlibpath_var=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag='${wl}-z,text' ++ allow_undefined_flag='${wl}-z,nodefs' ++ archive_cmds_need_lc=no ++ hardcode_shlibpath_var=no ++ hardcode_libdir_flag_spec='${wl}-R,$libdir' ++ hardcode_libdir_separator=':' ++ link_all_deplibs=yes ++ export_dynamic_flag_spec='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *) ++ ld_shlibs=no ++ ;; ++ esac ++ ++ if test x$host_vendor = xsni; then ++ case $host in ++ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ ;; ++ esac ++ fi ++ fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 ++$as_echo "$ld_shlibs" >&6; } ++test "$ld_shlibs" = no && can_build_shared=no ++ ++with_gnu_ld=$with_gnu_ld ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 ++$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } ++if ${lt_cv_archive_cmds_need_lc+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++ then ++ lt_cv_archive_cmds_need_lc=no ++ else ++ lt_cv_archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 ++$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } ++ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 ++$as_echo_n "checking dynamic linker characteristics... " >&6; } ++ ++if test "$GCC" = yes; then ++ case $host_os in ++ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; ++ *) lt_awk_arg="/^libraries:/" ;; ++ esac ++ case $host_os in ++ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; ++ *) lt_sed_strip_eq="s,=/,/,g" ;; ++ esac ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` ++ case $lt_search_path_spec in ++ *\;*) ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ++ ;; ++ *) ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ++ ;; ++ esac ++ # Ok, now we have the path, separated by spaces, we can step through it ++ # and add multilib dir if necessary. ++ lt_tmp_lt_search_path_spec= ++ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` ++ for lt_sys_path in $lt_search_path_spec; do ++ if test -d "$lt_sys_path/$lt_multi_os_dir"; then ++ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" ++ else ++ test -d "$lt_sys_path" && \ ++ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" ++ fi ++ done ++ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++BEGIN {RS=" "; FS="/|\n";} { ++ lt_foo=""; ++ lt_count=0; ++ for (lt_i = NF; lt_i > 0; lt_i--) { ++ if ($lt_i != "" && $lt_i != ".") { ++ if ($lt_i == "..") { ++ lt_count++; ++ } else { ++ if (lt_count == 0) { ++ lt_foo="/" $lt_i lt_foo; ++ } else { ++ lt_count--; ++ } ++ } ++ } ++ } ++ if (lt_foo != "") { lt_freq[lt_foo]++; } ++ if (lt_freq[lt_foo] == 1) { print lt_foo; } ++}'` ++ # AWK program above erroneously prepends '/' to C:/dos/paths ++ # for these hosts. ++ case $host_os in ++ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ ++ $SED 's,/\([A-Za-z]:\),\1,g'` ;; ++ esac ++ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix[4-9]*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ case $host_cpu in ++ powerpc) ++ # Since July 2007 AmigaOS4 officially supports .so libraries. ++ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ ;; ++ m68k) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ esac ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32* | cegcc*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \${file}`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname~ ++ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then ++ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; ++ fi' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ++ ;; ++ mingw* | cegcc*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[23].*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2.*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ *) # from 4.6 on, and DragonFly ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++haiku*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ dynamic_linker="$host_os runtime_loader" ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ postinstall_cmds='chmod 555 $lib' ++ # or fails outright, so override atomically: ++ install_override_mode=555 ++ ;; ++ ++interix[3-9]*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ ++ # Some binutils ld are patched to set DT_RUNPATH ++ if ${lt_cv_shlibpath_overrides_runpath+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_shlibpath_overrides_runpath=no ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : ++ lt_cv_shlibpath_overrides_runpath=yes ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir ++ ++fi ++ ++ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # find out which ABI we are using ++ libsuff= ++ case "$host_cpu" in ++ x86_64*|s390*|powerpc*|ppc*|sparc*) ++ echo 'int i;' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *64-bit*) ++ libsuff=64 ++ if test x"$sys_lib_search_path_spec" = x"/lib /usr/lib /usr/local/lib"; then ++ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" ++ fi ++ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ esac ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++*nto* | *qnx*) ++ version_type=qnx ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='ldqnx.so' ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++rdos*) ++ dynamic_linker=no ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++tpf*) ++ # TPF is a cross-target only. Preferred cross-host = GNU/Linux. ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 ++$as_echo "$dynamic_linker" >&6; } ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then ++ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" ++fi ++if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then ++ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 ++$as_echo_n "checking how to hardcode library paths into programs... " >&6; } ++hardcode_action= ++if test -n "$hardcode_libdir_flag_spec" || ++ test -n "$runpath_var" || ++ test "X$hardcode_automatic" = "Xyes" ; then ++ ++ # We can hardcode non-existent directories. ++ if test "$hardcode_direct" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && ++ test "$hardcode_minus_L" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action=unsupported ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 ++$as_echo "$hardcode_action" >&6; } ++ ++if test "$hardcode_action" = relink || ++ test "$inherit_rpath" = yes; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++ ++ ++ ++ ++ if test "x$enable_dlopen" != xyes; then ++ enable_dlopen=unknown ++ enable_dlopen_self=unknown ++ enable_dlopen_self_static=unknown ++else ++ lt_cv_dlopen=no ++ lt_cv_dlopen_libs= ++ ++ case $host_os in ++ beos*) ++ lt_cv_dlopen="load_add_on" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ;; ++ ++ mingw* | pw32* | cegcc*) ++ lt_cv_dlopen="LoadLibrary" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ cygwin*) ++ lt_cv_dlopen="dlopen" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ darwin*) ++ # if libdl is installed we need to link against it ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 ++$as_echo_n "checking for dlopen in -ldl... " >&6; } ++if ${ac_cv_lib_dl_dlopen+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldl $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dlopen (); ++int ++main () ++{ ++return dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_dl_dlopen=yes ++else ++ ac_cv_lib_dl_dlopen=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 ++$as_echo "$ac_cv_lib_dl_dlopen" >&6; } ++if test "x$ac_cv_lib_dl_dlopen" = xyes; then : ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" ++else ++ ++ lt_cv_dlopen="dyld" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ++fi ++ ++ ;; ++ ++ *) ++ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" ++if test "x$ac_cv_func_shl_load" = xyes; then : ++ lt_cv_dlopen="shl_load" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 ++$as_echo_n "checking for shl_load in -ldld... " >&6; } ++if ${ac_cv_lib_dld_shl_load+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldld $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char shl_load (); ++int ++main () ++{ ++return shl_load (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_dld_shl_load=yes ++else ++ ac_cv_lib_dld_shl_load=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 ++$as_echo "$ac_cv_lib_dld_shl_load" >&6; } ++if test "x$ac_cv_lib_dld_shl_load" = xyes; then : ++ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" ++else ++ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" ++if test "x$ac_cv_func_dlopen" = xyes; then : ++ lt_cv_dlopen="dlopen" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 ++$as_echo_n "checking for dlopen in -ldl... " >&6; } ++if ${ac_cv_lib_dl_dlopen+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldl $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dlopen (); ++int ++main () ++{ ++return dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_dl_dlopen=yes ++else ++ ac_cv_lib_dl_dlopen=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 ++$as_echo "$ac_cv_lib_dl_dlopen" >&6; } ++if test "x$ac_cv_lib_dl_dlopen" = xyes; then : ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 ++$as_echo_n "checking for dlopen in -lsvld... " >&6; } ++if ${ac_cv_lib_svld_dlopen+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lsvld $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dlopen (); ++int ++main () ++{ ++return dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_svld_dlopen=yes ++else ++ ac_cv_lib_svld_dlopen=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 ++$as_echo "$ac_cv_lib_svld_dlopen" >&6; } ++if test "x$ac_cv_lib_svld_dlopen" = xyes; then : ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 ++$as_echo_n "checking for dld_link in -ldld... " >&6; } ++if ${ac_cv_lib_dld_dld_link+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldld $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dld_link (); ++int ++main () ++{ ++return dld_link (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_dld_dld_link=yes ++else ++ ac_cv_lib_dld_dld_link=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 ++$as_echo "$ac_cv_lib_dld_dld_link" >&6; } ++if test "x$ac_cv_lib_dld_dld_link" = xyes; then : ++ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ;; ++ esac ++ ++ if test "x$lt_cv_dlopen" != xno; then ++ enable_dlopen=yes ++ else ++ enable_dlopen=no ++ fi ++ ++ case $lt_cv_dlopen in ++ dlopen) ++ save_CPPFLAGS="$CPPFLAGS" ++ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" ++ ++ save_LDFLAGS="$LDFLAGS" ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" ++ ++ save_LIBS="$LIBS" ++ LIBS="$lt_cv_dlopen_libs $LIBS" ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 ++$as_echo_n "checking whether a program can dlopen itself... " >&6; } ++if ${lt_cv_dlopen_self+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ lt_cv_dlopen_self=cross ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<_LT_EOF ++#line 11628 "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include ++#endif ++ ++#include ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++/* When -fvisbility=hidden is used, assume the code has been annotated ++ correspondingly for the symbols needed. */ ++#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) ++void fnord () __attribute__((visibility("default"))); ++#endif ++ ++void fnord () { int i=42; } ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else ++ { ++ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ else puts (dlerror ()); ++ } ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ return status; ++} ++_LT_EOF ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&5 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; ++ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; ++ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; ++ esac ++ else : ++ # compilation failed ++ lt_cv_dlopen_self=no ++ fi ++fi ++rm -fr conftest* ++ ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 ++$as_echo "$lt_cv_dlopen_self" >&6; } ++ ++ if test "x$lt_cv_dlopen_self" = xyes; then ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 ++$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } ++if ${lt_cv_dlopen_self_static+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ lt_cv_dlopen_self_static=cross ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<_LT_EOF ++#line 11734 "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include ++#endif ++ ++#include ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++/* When -fvisbility=hidden is used, assume the code has been annotated ++ correspondingly for the symbols needed. */ ++#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) ++void fnord () __attribute__((visibility("default"))); ++#endif ++ ++void fnord () { int i=42; } ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else ++ { ++ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ else puts (dlerror ()); ++ } ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ return status; ++} ++_LT_EOF ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&5 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; ++ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; ++ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; ++ esac ++ else : ++ # compilation failed ++ lt_cv_dlopen_self_static=no ++ fi ++fi ++rm -fr conftest* ++ ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 ++$as_echo "$lt_cv_dlopen_self_static" >&6; } ++ fi ++ ++ CPPFLAGS="$save_CPPFLAGS" ++ LDFLAGS="$save_LDFLAGS" ++ LIBS="$save_LIBS" ++ ;; ++ esac ++ ++ case $lt_cv_dlopen_self in ++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; ++ *) enable_dlopen_self=unknown ;; ++ esac ++ ++ case $lt_cv_dlopen_self_static in ++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; ++ *) enable_dlopen_self_static=unknown ;; ++ esac ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++striplib= ++old_striplib= ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 ++$as_echo_n "checking whether stripping libraries is possible... " >&6; } ++if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then ++ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" ++ test -z "$striplib" && striplib="$STRIP --strip-unneeded" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else ++# FIXME - insert some real tests, host_os isn't really good enough ++ case $host_os in ++ darwin*) ++ if test -n "$STRIP" ; then ++ striplib="$STRIP -x" ++ old_striplib="$STRIP -S" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ fi ++ ;; ++ *) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ;; ++ esac ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ # Report which library types will actually be built ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 ++$as_echo_n "checking if libtool supports shared libraries... " >&6; } ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 ++$as_echo "$can_build_shared" >&6; } ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 ++$as_echo_n "checking whether to build shared libraries... " >&6; } ++ test "$can_build_shared" = "no" && enable_shared=no ++ ++ # On AIX, shared libraries and static libraries use the same namespace, and ++ # are all built from PIC. ++ case $host_os in ++ aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ ++ aix[4-9]*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++ esac ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 ++$as_echo "$enable_shared" >&6; } ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 ++$as_echo_n "checking whether to build static libraries... " >&6; } ++ # Make sure either enable_shared or enable_static is yes. ++ test "$enable_shared" = yes || enable_static=yes ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 ++$as_echo "$enable_static" >&6; } ++ ++ ++ ++ ++fi ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ ac_ext=cpp ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 ++$as_echo_n "checking how to run the C++ preprocessor... " >&6; } ++if test -z "$CXXCPP"; then ++ if ${ac_cv_prog_CXXCPP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # Double quotes because CXXCPP needs to be expanded ++ for CXXCPP in "$CXX -E" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_cxx_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_cxx_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_cxx_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.i conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ break ++fi ++ ++ done ++ ac_cv_prog_CXXCPP=$CXXCPP ++ ++fi ++ CXXCPP=$ac_cv_prog_CXXCPP ++else ++ ac_cv_prog_CXXCPP=$CXXCPP ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 ++$as_echo "$CXXCPP" >&6; } ++ac_preproc_ok=false ++for ac_cxx_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_cxx_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_cxx_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.i conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ ++else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check ++See \`config.log' for more details" "$LINENO" 5; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++else ++ _lt_caught_CXX_error=yes ++fi ++ ++ac_ext=cpp ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++archive_cmds_need_lc_CXX=no ++allow_undefined_flag_CXX= ++always_export_symbols_CXX=no ++archive_expsym_cmds_CXX= ++compiler_needs_object_CXX=no ++export_dynamic_flag_spec_CXX= ++hardcode_direct_CXX=no ++hardcode_direct_absolute_CXX=no ++hardcode_libdir_flag_spec_CXX= ++hardcode_libdir_flag_spec_ld_CXX= ++hardcode_libdir_separator_CXX= ++hardcode_minus_L_CXX=no ++hardcode_shlibpath_var_CXX=unsupported ++hardcode_automatic_CXX=no ++inherit_rpath_CXX=no ++module_cmds_CXX= ++module_expsym_cmds_CXX= ++link_all_deplibs_CXX=unknown ++old_archive_cmds_CXX=$old_archive_cmds ++reload_flag_CXX=$reload_flag ++reload_cmds_CXX=$reload_cmds ++no_undefined_flag_CXX= ++whole_archive_flag_spec_CXX= ++enable_shared_with_static_runtimes_CXX=no ++ ++# Source file extension for C++ test sources. ++ac_ext=cpp ++ ++# Object file extension for compiled C++ test sources. ++objext=o ++objext_CXX=$objext ++ ++# No sense in running all these tests if we already determined that ++# the CXX compiler isn't working. Some variables (like enable_shared) ++# are currently assumed to apply to all compilers on this platform, ++# and will be corrupted by setting them based on a non-working compiler. ++if test "$_lt_caught_CXX_error" != yes; then ++ # Code to be used in simple compile tests ++ lt_simple_compile_test_code="int some_variable = 0;" ++ ++ # Code to be used in simple link tests ++ lt_simple_link_test_code='int main(int, char *[]) { return(0); }' ++ ++ # ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++ ++ ++ ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++ # save warnings/boilerplate of simple test code ++ ac_outfile=conftest.$ac_objext ++echo "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$RM conftest* ++ ++ ac_outfile=conftest.$ac_objext ++echo "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$RM -r conftest* ++ ++ ++ # Allow CC to be a program name with arguments. ++ lt_save_CC=$CC ++ lt_save_LD=$LD ++ lt_save_GCC=$GCC ++ GCC=$GXX ++ lt_save_with_gnu_ld=$with_gnu_ld ++ lt_save_path_LD=$lt_cv_path_LD ++ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then ++ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx ++ else ++ $as_unset lt_cv_prog_gnu_ld ++ fi ++ if test -n "${lt_cv_path_LDCXX+set}"; then ++ lt_cv_path_LD=$lt_cv_path_LDCXX ++ else ++ $as_unset lt_cv_path_LD ++ fi ++ test -z "${LDCXX+set}" || LD=$LDCXX ++ CC=${CXX-"c++"} ++ compiler=$CC ++ compiler_CXX=$CC ++ for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; ++ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++ ++ ++ if test -n "$compiler"; then ++ # We don't want -fno-exception when compiling C++ code, so set the ++ # no_builtin_flag separately ++ if test "$GXX" = yes; then ++ lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' ++ else ++ lt_prog_compiler_no_builtin_flag_CXX= ++ fi ++ ++ if test "$GXX" = yes; then ++ # Set up default GNU C++ configuration ++ ++ ++ ++# Check whether --with-gnu-ld was given. ++if test "${with_gnu_ld+set}" = set; then : ++ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes ++else ++ with_gnu_ld=no ++fi ++ ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 ++$as_echo_n "checking for ld used by $CC... " >&6; } ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [\\/]* | ?:[\\/]*) ++ re_direlt='/[^/][^/]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` ++ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 ++$as_echo_n "checking for GNU ld... " >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 ++$as_echo_n "checking for non-GNU ld... " >&6; } ++fi ++if ${lt_cv_path_LD+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 &5 ++$as_echo "$LD" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 ++$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } ++if ${lt_cv_prog_gnu_ld+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 &5 ++$as_echo "$lt_cv_prog_gnu_ld" >&6; } ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++ ++ ++ ++ ++ ++ ++ # Check if GNU C++ uses GNU ld as the underlying linker, since the ++ # archiving commands below assume that GNU ld is being used. ++ if test "$with_gnu_ld" = yes; then ++ archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to ++ # investigate it a little bit more. (MM) ++ wlarc='${wl}' ++ ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if eval "`$CC -print-prog-name=ld` --help 2>&1" | ++ $GREP 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec_CXX= ++ fi ++ else ++ with_gnu_ld=no ++ wlarc= ++ ++ # A generic and very simple default shared library creation ++ # command for GNU C++ for the case where it uses the native ++ # linker, instead of GNU ld. If possible, this setting should ++ # overridden to take advantage of the native linker features on ++ # the platform it is being used on. ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ fi ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ ++ else ++ GXX=no ++ with_gnu_ld=no ++ wlarc= ++ fi ++ ++ # PORTME: fill in a description of your system's C++ link characteristics ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ++ ld_shlibs_CXX=yes ++ case $host_os in ++ aix3*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aix[4-9]*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) ++ for ld_flag in $LDFLAGS; do ++ case $ld_flag in ++ *-brtl*) ++ aix_use_runtimelinking=yes ++ break ++ ;; ++ esac ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds_CXX='' ++ hardcode_direct_CXX=yes ++ hardcode_direct_absolute_CXX=yes ++ hardcode_libdir_separator_CXX=':' ++ link_all_deplibs_CXX=yes ++ file_list_spec_CXX='${wl}-f,' ++ ++ if test "$GXX" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && ++ strings "$collect2name" | $GREP resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ : ++ else ++ # We have old collect2 ++ hardcode_direct_CXX=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L_CXX=yes ++ hardcode_libdir_flag_spec_CXX='-L$libdir' ++ hardcode_libdir_separator_CXX= ++ fi ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ export_dynamic_flag_spec_CXX='${wl}-bexpall' ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to ++ # export. ++ always_export_symbols_CXX=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag_CXX='-berok' ++ # Determine the default libpath from the value encoded in an empty ++ # executable. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_link "$LINENO"; then : ++ ++lt_aix_libpath_sed=' ++ /Import File Strings/,/^$/ { ++ /^0/ { ++ s/^0 *\(.*\)$/\1/ ++ p ++ } ++ }' ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then ++ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" ++ ++ archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag_CXX="-z nodefs" ++ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_link "$LINENO"; then : ++ ++lt_aix_libpath_sed=' ++ /Import File Strings/,/^$/ { ++ /^0/ { ++ s/^0 *\(.*\)$/\1/ ++ p ++ } ++ }' ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then ++ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag_CXX=' ${wl}-bernotok' ++ allow_undefined_flag_CXX=' ${wl}-berok' ++ if test "$with_gnu_ld" = yes; then ++ # We only use this code for GNU lds that support --whole-archive. ++ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ++ else ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec_CXX='$convenience' ++ fi ++ archive_cmds_need_lc_CXX=yes ++ # This is similar to how AIX traditionally builds its shared ++ # libraries. ++ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag_CXX=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ ++ chorus*) ++ case $cc_basename in ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec_CXX='-L$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' ++ allow_undefined_flag_CXX=unsupported ++ always_export_symbols_CXX=no ++ enable_shared_with_static_runtimes_CXX=yes ++ ++ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ darwin* | rhapsody*) ++ ++ ++ archive_cmds_need_lc_CXX=no ++ hardcode_direct_CXX=no ++ hardcode_automatic_CXX=yes ++ hardcode_shlibpath_var_CXX=unsupported ++ if test "$lt_cv_ld_force_load" = "yes"; then ++ whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' ++ else ++ whole_archive_flag_spec_CXX='' ++ fi ++ link_all_deplibs_CXX=yes ++ allow_undefined_flag_CXX="$_lt_dar_allow_undefined" ++ case $cc_basename in ++ ifort*) _lt_dar_can_shared=yes ;; ++ *) _lt_dar_can_shared=$GCC ;; ++ esac ++ if test "$_lt_dar_can_shared" = "yes"; then ++ output_verbose_link_cmd=func_echo_all ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "$lt_cv_apple_cc_single_mod" != "yes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi ++ ++ else ++ ld_shlibs_CXX=no ++ fi ++ ++ ;; ++ ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ ++ freebsd2.*) ++ # C++ shared libraries reported to be fairly broken before ++ # switch to ELF ++ ld_shlibs_CXX=no ++ ;; ++ ++ freebsd-elf*) ++ archive_cmds_need_lc_CXX=no ++ ;; ++ ++ freebsd* | dragonfly*) ++ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF ++ # conventions ++ ld_shlibs_CXX=yes ++ ;; ++ ++ gnu*) ++ ;; ++ ++ haiku*) ++ archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ link_all_deplibs_CXX=yes ++ ;; ++ ++ hpux9*) ++ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ hardcode_direct_CXX=yes ++ hardcode_minus_L_CXX=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aCC*) ++ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ hpux10*|hpux11*) ++ if test $with_gnu_ld = no; then ++ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ ;; ++ *) ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ ;; ++ esac ++ fi ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_direct_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ ;; ++ *) ++ hardcode_direct_CXX=yes ++ hardcode_direct_absolute_CXX=yes ++ hardcode_minus_L_CXX=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ;; ++ esac ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aCC*) ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test $with_gnu_ld = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ fi ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ interix[3-9]*) ++ hardcode_direct_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ irix5* | irix6*) ++ case $cc_basename in ++ CC*) ++ # SGI C++ ++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -ar", where "CC" is the IRIX C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test "$with_gnu_ld" = no; then ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' ++ fi ++ fi ++ link_all_deplibs_CXX=yes ++ ;; ++ esac ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ inherit_rpath_CXX=yes ++ ;; ++ ++ linux* | k*bsd*-gnu | kopensolaris*-gnu) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ++ ;; ++ icpc* | ecpc* ) ++ # Intel C++ ++ with_gnu_ld=yes ++ # version 8.0 and above of icpc choke on multiply defined symbols ++ # if we add $predep_objects and $postdep_objects, however 7.1 and ++ # earlier do not add the objects themselves. ++ case `$CC -V 2>&1` in ++ *"Version 7."*) ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 8.0 or newer ++ tmp_idyn= ++ case $host_cpu in ++ ia64*) tmp_idyn=' -i_dynamic';; ++ esac ++ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ archive_cmds_need_lc_CXX=no ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ++ ;; ++ pgCC* | pgcpp*) ++ # Portland Group C++ compiler ++ case `$CC -V` in ++ *pgCC\ [1-5].* | *pgcpp\ [1-5].*) ++ prelink_cmds_CXX='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ ++ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' ++ old_archive_cmds_CXX='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ ++ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ ++ $RANLIB $oldlib' ++ archive_cmds_CXX='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ ++ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' ++ archive_expsym_cmds_CXX='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ ++ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ++ ;; ++ *) # Version 6 and above use weak symbols ++ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ++ ;; ++ esac ++ ++ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ ;; ++ cxx*) ++ # Compaq C++ ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' ++ ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec_CXX='-rpath $libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ++ ;; ++ xl* | mpixl* | bgxl*) ++ # IBM XL 8.0 on PPC, with GNU ld ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ if test "x$supports_anon_versioning" = xyes; then ++ archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ ;; ++ *) ++ case `$CC -V 2>&1 | sed 5q` in ++ *Sun\ C*) ++ # Sun C++ 5.9 ++ no_undefined_flag_CXX=' -zdefs' ++ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' ++ hardcode_libdir_flag_spec_CXX='-R$libdir' ++ whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ++ compiler_needs_object_CXX=yes ++ ++ # Not sure whether something based on ++ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 ++ # would be better. ++ output_verbose_link_cmd='func_echo_all' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ ++ lynxos*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ ++ m88k*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' ++ wlarc= ++ hardcode_libdir_flag_spec_CXX='-R$libdir' ++ hardcode_direct_CXX=yes ++ hardcode_shlibpath_var_CXX=no ++ fi ++ # Workaround some broken pre-1.5 toolchains ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ++ ;; ++ ++ *nto* | *qnx*) ++ ld_shlibs_CXX=yes ++ ;; ++ ++ openbsd2*) ++ # C++ shared libraries are fairly broken ++ ld_shlibs_CXX=no ++ ;; ++ ++ openbsd*) ++ if test -f /usr/libexec/ld.so; then ++ hardcode_direct_CXX=yes ++ hardcode_shlibpath_var_CXX=no ++ hardcode_direct_absolute_CXX=yes ++ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ fi ++ output_verbose_link_cmd=func_echo_all ++ else ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Archives containing C++ object files must be created using ++ # the KAI C++ compiler. ++ case $host in ++ osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; ++ *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; ++ esac ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ cxx*) ++ case $host in ++ osf3*) ++ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' ++ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ ;; ++ *) ++ allow_undefined_flag_CXX=' -expect_unresolved \*' ++ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ ++ echo "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ ++ $RM $lib.exp' ++ hardcode_libdir_flag_spec_CXX='-rpath $libdir' ++ ;; ++ esac ++ ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' ++ case $host in ++ osf3*) ++ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ;; ++ esac ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ psos*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ lcc*) ++ # Lucid ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ archive_cmds_need_lc_CXX=yes ++ no_undefined_flag_CXX=' -zdefs' ++ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ hardcode_libdir_flag_spec_CXX='-R$libdir' ++ hardcode_shlibpath_var_CXX=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine and reorder linker options, ++ # but understands `-z linker_flag'. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ++ ;; ++ esac ++ link_all_deplibs_CXX=yes ++ ++ output_verbose_link_cmd='func_echo_all' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ ++ # The C++ compiler must be used to create the archive. ++ old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ++ ;; ++ *) ++ # GNU C++ compiler with Solaris linker ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ no_undefined_flag_CXX=' ${wl}-z ${wl}defs' ++ if $CC --version | $GREP -v '^2\.7' > /dev/null; then ++ archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ else ++ # g++ 2.7 appears to require `-G' NOT `-shared' on this ++ # platform. ++ archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ++ no_undefined_flag_CXX='${wl}-z,text' ++ archive_cmds_need_lc_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag_CXX='${wl}-z,text' ++ allow_undefined_flag_CXX='${wl}-z,nodefs' ++ archive_cmds_need_lc_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' ++ hardcode_libdir_separator_CXX=':' ++ link_all_deplibs_CXX=yes ++ export_dynamic_flag_spec_CXX='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ ++ '"$old_archive_cmds_CXX" ++ reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ ++ '"$reload_cmds_CXX" ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ ++ vxworks*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 ++$as_echo "$ld_shlibs_CXX" >&6; } ++ test "$ld_shlibs_CXX" = no && can_build_shared=no ++ ++ GCC_CXX="$GXX" ++ LD_CXX="$LD" ++ ++ ## CAVEAT EMPTOR: ++ ## There is no encapsulation within the following macros, do not change ++ ## the running order or otherwise move them around unless you know exactly ++ ## what you are doing... ++ # Dependencies to place before and after the object being linked: ++predep_objects_CXX= ++postdep_objects_CXX= ++predeps_CXX= ++postdeps_CXX= ++compiler_lib_search_path_CXX= ++ ++cat > conftest.$ac_ext <<_LT_EOF ++class Foo ++{ ++public: ++ Foo (void) { a = 0; } ++private: ++ int a; ++}; ++_LT_EOF ++ ++if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ # Parse the compiler output and extract the necessary ++ # objects, libraries and library flags. ++ ++ # Sentinel used to keep track of whether or not we are before ++ # the conftest object file. ++ pre_test_object_deps_done=no ++ ++ for p in `eval "$output_verbose_link_cmd"`; do ++ case $p in ++ ++ -L* | -R* | -l*) ++ # Some compilers place space between "-{L,R}" and the path. ++ # Remove the space. ++ if test $p = "-L" || ++ test $p = "-R"; then ++ prev=$p ++ continue ++ else ++ prev= ++ fi ++ ++ if test "$pre_test_object_deps_done" = no; then ++ case $p in ++ -L* | -R*) ++ # Internal compiler library paths should come after those ++ # provided the user. The postdeps already come after the ++ # user supplied libs so there is no need to process them. ++ if test -z "$compiler_lib_search_path_CXX"; then ++ compiler_lib_search_path_CXX="${prev}${p}" ++ else ++ compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" ++ fi ++ ;; ++ # The "-l" case would never come before the object being ++ # linked, so don't bother handling this case. ++ esac ++ else ++ if test -z "$postdeps_CXX"; then ++ postdeps_CXX="${prev}${p}" ++ else ++ postdeps_CXX="${postdeps_CXX} ${prev}${p}" ++ fi ++ fi ++ ;; ++ ++ *.$objext) ++ # This assumes that the test object file only shows up ++ # once in the compiler output. ++ if test "$p" = "conftest.$objext"; then ++ pre_test_object_deps_done=yes ++ continue ++ fi ++ ++ if test "$pre_test_object_deps_done" = no; then ++ if test -z "$predep_objects_CXX"; then ++ predep_objects_CXX="$p" ++ else ++ predep_objects_CXX="$predep_objects_CXX $p" ++ fi ++ else ++ if test -z "$postdep_objects_CXX"; then ++ postdep_objects_CXX="$p" ++ else ++ postdep_objects_CXX="$postdep_objects_CXX $p" ++ fi ++ fi ++ ;; ++ ++ *) ;; # Ignore the rest. ++ ++ esac ++ done ++ ++ # Clean up. ++ rm -f a.out a.exe ++else ++ echo "libtool.m4: error: problem compiling CXX test program" ++fi ++ ++$RM -f confest.$objext ++ ++# PORTME: override above test on systems where it is broken ++case $host_os in ++interix[3-9]*) ++ # Interix 3.5 installs completely hosed .la files for C++, so rather than ++ # hack all around it, let's just trust "g++" to DTRT. ++ predep_objects_CXX= ++ postdep_objects_CXX= ++ postdeps_CXX= ++ ;; ++ ++linux*) ++ case `$CC -V 2>&1 | sed 5q` in ++ *Sun\ C*) ++ # Sun C++ 5.9 ++ ++ # The more standards-conforming stlport4 library is ++ # incompatible with the Cstd library. Avoid specifying ++ # it if it's in CXXFLAGS. Ignore libCrun as ++ # -library=stlport4 depends on it. ++ case " $CXX $CXXFLAGS " in ++ *" -library=stlport4 "*) ++ solaris_use_stlport4=yes ++ ;; ++ esac ++ ++ if test "$solaris_use_stlport4" != yes; then ++ postdeps_CXX='-library=Cstd -library=Crun' ++ fi ++ ;; ++ esac ++ ;; ++ ++solaris*) ++ case $cc_basename in ++ CC*) ++ # The more standards-conforming stlport4 library is ++ # incompatible with the Cstd library. Avoid specifying ++ # it if it's in CXXFLAGS. Ignore libCrun as ++ # -library=stlport4 depends on it. ++ case " $CXX $CXXFLAGS " in ++ *" -library=stlport4 "*) ++ solaris_use_stlport4=yes ++ ;; ++ esac ++ ++ # Adding this requires a known-good setup of shared libraries for ++ # Sun compiler versions before 5.6, else PIC objects from an old ++ # archive will be linked into the output, leading to subtle bugs. ++ if test "$solaris_use_stlport4" != yes; then ++ postdeps_CXX='-library=Cstd -library=Crun' ++ fi ++ ;; ++ esac ++ ;; ++esac ++ ++ ++case " $postdeps_CXX " in ++*" -lc "*) archive_cmds_need_lc_CXX=no ;; ++esac ++ compiler_lib_search_dirs_CXX= ++if test -n "${compiler_lib_search_path_CXX}"; then ++ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ lt_prog_compiler_wl_CXX= ++lt_prog_compiler_pic_CXX= ++lt_prog_compiler_static_CXX= ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 ++$as_echo_n "checking for $compiler option to produce PIC... " >&6; } ++ ++ # C++ specific cases for pic, static, wl, etc. ++ if test "$GXX" = yes; then ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_CXX='-Bstatic' ++ fi ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ m68k) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ esac ++ ;; ++ ++ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ mingw* | cygwin* | os2* | pw32* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ # Although the cygwin gcc ignores -fPIC, still need this for old-style ++ # (--disable-auto-import) libraries ++ lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ++ ;; ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic_CXX='-fno-common' ++ ;; ++ *djgpp*) ++ # DJGPP does not support shared libraries at all ++ lt_prog_compiler_pic_CXX= ++ ;; ++ haiku*) ++ # PIC is the default for Haiku. ++ # The "-static" flag exists, but is broken. ++ lt_prog_compiler_static_CXX= ++ ;; ++ interix[3-9]*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic_CXX=-Kconform_pic ++ fi ++ ;; ++ hpux*) ++ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit ++ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag ++ # sets the default TLS model and affects inlining. ++ case $host_cpu in ++ hppa*64*) ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ esac ++ ;; ++ *qnx* | *nto*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ lt_prog_compiler_pic_CXX='-fPIC -shared' ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ esac ++ else ++ case $host_os in ++ aix[4-9]*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_CXX='-Bstatic' ++ else ++ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ chorus*) ++ case $cc_basename in ++ cxch68*) ++ # Green Hills C++ Compiler ++ # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ++ ;; ++ esac ++ ;; ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ lt_prog_compiler_pic_CXX='-KPIC' ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ freebsd* | dragonfly*) ++ # FreeBSD uses GNU C++ ++ ;; ++ hpux9* | hpux10* | hpux11*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' ++ if test "$host_cpu" != ia64; then ++ lt_prog_compiler_pic_CXX='+Z' ++ fi ++ ;; ++ aCC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='+Z' ++ ;; ++ esac ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ interix*) ++ # This is c89, which is MS Visual C++ (no shared libs) ++ # Anyone wants to do a port? ++ ;; ++ irix5* | irix6* | nonstopux*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='-non_shared' ++ # CC pic flag -KPIC is the default. ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ linux* | k*bsd*-gnu | kopensolaris*-gnu) ++ case $cc_basename in ++ KCC*) ++ # KAI C++ Compiler ++ lt_prog_compiler_wl_CXX='--backend -Wl,' ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ ecpc* ) ++ # old Intel C++ for x86_64 which still supported -KPIC. ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-static' ++ ;; ++ icpc* ) ++ # Intel C++, used to be incompatible with GCC. ++ # ICC 10 doesn't accept -KPIC any more. ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-fPIC' ++ lt_prog_compiler_static_CXX='-static' ++ ;; ++ pgCC* | pgcpp*) ++ # Portland Group C++ compiler ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-fpic' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ cxx*) ++ # Compaq C++ ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_static_CXX='-non_shared' ++ ;; ++ xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) ++ # IBM XL 8.0, 9.0 on PPC and BlueGene ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-qpic' ++ lt_prog_compiler_static_CXX='-qstaticlink' ++ ;; ++ *) ++ case `$CC -V 2>&1 | sed 5q` in ++ *Sun\ C*) ++ # Sun C++ 5.9 ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ lt_prog_compiler_wl_CXX='-Qoption ld ' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ lynxos*) ++ ;; ++ m88k*) ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ lt_prog_compiler_pic_CXX='-W c,exportall' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ netbsd*) ++ ;; ++ *qnx* | *nto*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ lt_prog_compiler_pic_CXX='-fPIC -shared' ++ ;; ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ lt_prog_compiler_wl_CXX='--backend -Wl,' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ cxx*) ++ # Digital/Compaq C++ ++ lt_prog_compiler_wl_CXX='-Wl,' ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_static_CXX='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ psos*) ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ lt_prog_compiler_wl_CXX='-Qoption ld ' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ lt_prog_compiler_pic_CXX='-PIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ lt_prog_compiler_pic_CXX='-pic' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ lcc*) ++ # Lucid ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ lt_prog_compiler_pic_CXX='-KPIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ vxworks*) ++ ;; ++ *) ++ lt_prog_compiler_can_build_shared_CXX=no ++ ;; ++ esac ++ fi ++ ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic_CXX= ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ++ ;; ++esac ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5 ++$as_echo "$lt_prog_compiler_pic_CXX" >&6; } ++ ++ ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic_CXX"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 ++$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } ++if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_pic_works_CXX=no ++ ac_outfile=conftest.$ac_objext ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_pic_works_CXX=yes ++ fi ++ fi ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 ++$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } ++ ++if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then ++ case $lt_prog_compiler_pic_CXX in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; ++ esac ++else ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_can_build_shared_CXX=no ++fi ++ ++fi ++ ++ ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } ++if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_static_works_CXX=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ echo "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_static_works_CXX=yes ++ fi ++ else ++ lt_cv_prog_compiler_static_works_CXX=yes ++ fi ++ fi ++ $RM -r conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 ++$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } ++ ++if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then ++ : ++else ++ lt_prog_compiler_static_CXX= ++fi ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 ++$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } ++if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_c_o_CXX=no ++ $RM -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o_CXX=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $RM conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files ++ $RM out/* && rmdir out ++ cd .. ++ $RM -r conftest ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 ++$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 ++$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } ++if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_prog_compiler_c_o_CXX=no ++ $RM -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o_CXX=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $RM conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files ++ $RM out/* && rmdir out ++ cd .. ++ $RM -r conftest ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 ++$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } ++ ++ ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 ++$as_echo_n "checking if we can lock with hard links... " >&6; } ++ hard_links=yes ++ $RM conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 ++$as_echo "$hard_links" >&6; } ++ if test "$hard_links" = no; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 ++$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ++ ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ case $host_os in ++ aix[4-9]*) ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ # Also, AIX nm treats weak defined symbols like other global defined ++ # symbols, whereas GNU nm marks them as "W". ++ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then ++ export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' ++ fi ++ ;; ++ pw32*) ++ export_symbols_cmds_CXX="$ltdll_cmds" ++ ;; ++ cygwin* | mingw* | cegcc*) ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' ++ ;; ++ *) ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ ;; ++ esac ++ exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 ++$as_echo "$ld_shlibs_CXX" >&6; } ++test "$ld_shlibs_CXX" = no && can_build_shared=no ++ ++with_gnu_ld_CXX=$with_gnu_ld ++ ++ ++ ++ ++ ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc_CXX" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc_CXX=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds_CXX in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 ++$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } ++if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ $RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl_CXX ++ pic_flag=$lt_prog_compiler_pic_CXX ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX ++ allow_undefined_flag_CXX= ++ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 ++ (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++ then ++ lt_cv_archive_cmds_need_lc_CXX=no ++ else ++ lt_cv_archive_cmds_need_lc_CXX=yes ++ fi ++ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 ++$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } ++ archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 ++$as_echo_n "checking dynamic linker characteristics... " >&6; } ++ ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix[4-9]*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ case $host_cpu in ++ powerpc) ++ # Since July 2007 AmigaOS4 officially supports .so libraries. ++ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ ;; ++ m68k) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ esac ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32* | cegcc*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \${file}`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname~ ++ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then ++ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; ++ fi' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ++ ;; ++ mingw* | cegcc*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[23].*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2.*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ *) # from 4.6 on, and DragonFly ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++haiku*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ dynamic_linker="$host_os runtime_loader" ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ postinstall_cmds='chmod 555 $lib' ++ # or fails outright, so override atomically: ++ install_override_mode=555 ++ ;; ++ ++interix[3-9]*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ ++ # Some binutils ld are patched to set DT_RUNPATH ++ if ${lt_cv_shlibpath_overrides_runpath+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ lt_cv_shlibpath_overrides_runpath=no ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ ++ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_link "$LINENO"; then : ++ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : ++ lt_cv_shlibpath_overrides_runpath=yes ++fi ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir ++ ++fi ++ ++ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++*nto* | *qnx*) ++ version_type=qnx ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='ldqnx.so' ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++rdos*) ++ dynamic_linker=no ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++tpf*) ++ # TPF is a cross-target only. Preferred cross-host = GNU/Linux. ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 ++$as_echo "$dynamic_linker" >&6; } ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then ++ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" ++fi ++if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then ++ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 ++$as_echo_n "checking how to hardcode library paths into programs... " >&6; } ++hardcode_action_CXX= ++if test -n "$hardcode_libdir_flag_spec_CXX" || ++ test -n "$runpath_var_CXX" || ++ test "X$hardcode_automatic_CXX" = "Xyes" ; then ++ ++ # We can hardcode non-existent directories. ++ if test "$hardcode_direct_CXX" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && ++ test "$hardcode_minus_L_CXX" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action_CXX=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action_CXX=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action_CXX=unsupported ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 ++$as_echo "$hardcode_action_CXX" >&6; } ++ ++if test "$hardcode_action_CXX" = relink || ++ test "$inherit_rpath_CXX" = yes; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++ ++ ++ ++ ++ ++ fi # test -n "$compiler" ++ ++ CC=$lt_save_CC ++ LDCXX=$LD ++ LD=$lt_save_LD ++ GCC=$lt_save_GCC ++ with_gnu_ld=$lt_save_with_gnu_ld ++ lt_cv_path_LDCXX=$lt_cv_path_LD ++ lt_cv_path_LD=$lt_save_path_LD ++ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld ++ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ++fi # test "$_lt_caught_CXX_error" != yes ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ac_config_commands="$ac_config_commands libtool" ++ ++ ++ ++ ++# Only expand once: ++ ++ ++ ++# The tests for host and target for $enable_largefile require ++# canonical names. ++ ++ ++ ++# As the $enable_largefile decision depends on --enable-plugins we must set it ++# even in directories otherwise not depending on the $plugins option. ++ ++ ++ maybe_plugins=no ++ for ac_header in dlfcn.h ++do : ++ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default ++" ++if test "x$ac_cv_header_dlfcn_h" = xyes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_DLFCN_H 1 ++_ACEOF ++ maybe_plugins=yes ++fi ++ ++done ++ ++ for ac_header in windows.h ++do : ++ ac_fn_c_check_header_compile "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default ++" ++if test "x$ac_cv_header_windows_h" = xyes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_WINDOWS_H 1 ++_ACEOF ++ maybe_plugins=yes ++fi ++ ++done ++ ++ ++ # Check whether --enable-plugins was given. ++if test "${enable_plugins+set}" = set; then : ++ enableval=$enable_plugins; case "${enableval}" in ++ no) plugins=no ;; ++ *) plugins=yes ++ if test "$maybe_plugins" != "yes" ; then ++ as_fn_error $? "Building with plugin support requires a host that supports dlopen." "$LINENO" 5 ++ fi ;; ++ esac ++else ++ plugins=$maybe_plugins ++ ++fi ++ ++ if test "$plugins" = "yes"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlsym" >&5 ++$as_echo_n "checking for library containing dlsym... " >&6; } ++if ${ac_cv_search_dlsym+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_func_search_save_LIBS=$LIBS ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dlsym (); ++int ++main () ++{ ++return dlsym (); ++ ; ++ return 0; ++} ++_ACEOF ++for ac_lib in '' dl; do ++ if test -z "$ac_lib"; then ++ ac_res="none required" ++ else ++ ac_res=-l$ac_lib ++ LIBS="-l$ac_lib $ac_func_search_save_LIBS" ++ fi ++ if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_search_dlsym=$ac_res ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext ++ if ${ac_cv_search_dlsym+:} false; then : ++ break ++fi ++done ++if ${ac_cv_search_dlsym+:} false; then : ++ ++else ++ ac_cv_search_dlsym=no ++fi ++rm conftest.$ac_ext ++LIBS=$ac_func_search_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlsym" >&5 ++$as_echo "$ac_cv_search_dlsym" >&6; } ++ac_res=$ac_cv_search_dlsym ++if test "$ac_res" != no; then : ++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ++ ++fi ++ ++ fi ++ ++ ++case "${host}" in ++ sparc-*-solaris*|i?86-*-solaris*) ++ # On native 32-bit Solaris/SPARC and x86, large-file and procfs support ++ # were mutually exclusive until Solaris 11.3. Without procfs support, ++ # the bfd/ elf module cannot provide certain routines such as ++ # elfcore_write_prpsinfo or elfcore_write_prstatus. So unless the user ++ # explicitly requested large-file support through the ++ # --enable-largefile switch, disable large-file support in favor of ++ # procfs support. ++ # ++ # Check if is incompatible with large-file support. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#define _FILE_OFFSET_BITS 64 ++#define _STRUCTURED_PROC 1 ++#include ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ acx_cv_procfs_lfs=yes ++else ++ acx_cv_procfs_lfs=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ # ++ # Forcefully disable large-file support only if necessary, gdb is in ++ # tree and enabled. ++ if test "${target}" = "${host}" -a "$acx_cv_procfs_lfs" = no \ ++ -a -d $srcdir/../gdb -a "$enable_gdb" != no; then ++ : ${enable_largefile="no"} ++ if test "$plugins" = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ++plugin support disabled; require large-file support which is incompatible with GDB." >&5 ++$as_echo "$as_me: WARNING: ++plugin support disabled; require large-file support which is incompatible with GDB." >&2;} ++ plugins=no ++ fi ++ fi ++ # ++ # Explicitly undef _FILE_OFFSET_BITS if enable_largefile=no for the ++ # benefit of g++ 9+ which predefines it on Solaris. ++ if test "$enable_largefile" = no; then ++ LARGEFILE_CPPFLAGS="-U_FILE_OFFSET_BITS" ++ ++ fi ++ ;; ++esac ++ ++# Check whether --enable-largefile was given. ++if test "${enable_largefile+set}" = set; then : ++ enableval=$enable_largefile; ++fi ++ ++if test "$enable_largefile" != no; then ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 ++$as_echo_n "checking for special C compiler options needed for large files... " >&6; } ++if ${ac_cv_sys_largefile_CC+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_cv_sys_largefile_CC=no ++ if test "$GCC" != yes; then ++ ac_save_CC=$CC ++ while :; do ++ # IRIX 6.2 and later do not support large files by default, ++ # so use the C compiler's -n32 option if that helps. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ /* Check that off_t can represent 2**63 - 1 correctly. ++ We can't simply define LARGE_OFF_T to be 9223372036854775807, ++ since some C++ compilers masquerading as C compilers ++ incorrectly reject 9223372036854775807. */ ++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) ++ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 ++ && LARGE_OFF_T % 2147483647 == 1) ++ ? 1 : -1]; ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++ if ac_fn_c_try_compile "$LINENO"; then : ++ break ++fi ++rm -f core conftest.err conftest.$ac_objext ++ CC="$CC -n32" ++ if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_sys_largefile_CC=' -n32'; break ++fi ++rm -f core conftest.err conftest.$ac_objext ++ break ++ done ++ CC=$ac_save_CC ++ rm -f conftest.$ac_ext ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 ++$as_echo "$ac_cv_sys_largefile_CC" >&6; } ++ if test "$ac_cv_sys_largefile_CC" != no; then ++ CC=$CC$ac_cv_sys_largefile_CC ++ fi ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 ++$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } ++if ${ac_cv_sys_file_offset_bits+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ while :; do ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ /* Check that off_t can represent 2**63 - 1 correctly. ++ We can't simply define LARGE_OFF_T to be 9223372036854775807, ++ since some C++ compilers masquerading as C compilers ++ incorrectly reject 9223372036854775807. */ ++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) ++ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 ++ && LARGE_OFF_T % 2147483647 == 1) ++ ? 1 : -1]; ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_sys_file_offset_bits=no; break ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#define _FILE_OFFSET_BITS 64 ++#include ++ /* Check that off_t can represent 2**63 - 1 correctly. ++ We can't simply define LARGE_OFF_T to be 9223372036854775807, ++ since some C++ compilers masquerading as C compilers ++ incorrectly reject 9223372036854775807. */ ++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) ++ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 ++ && LARGE_OFF_T % 2147483647 == 1) ++ ? 1 : -1]; ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_sys_file_offset_bits=64; break ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ac_cv_sys_file_offset_bits=unknown ++ break ++done ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 ++$as_echo "$ac_cv_sys_file_offset_bits" >&6; } ++case $ac_cv_sys_file_offset_bits in #( ++ no | unknown) ;; ++ *) ++cat >>confdefs.h <<_ACEOF ++#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits ++_ACEOF ++;; ++esac ++rm -rf conftest* ++ if test $ac_cv_sys_file_offset_bits = unknown; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 ++$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } ++if ${ac_cv_sys_large_files+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ while :; do ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ /* Check that off_t can represent 2**63 - 1 correctly. ++ We can't simply define LARGE_OFF_T to be 9223372036854775807, ++ since some C++ compilers masquerading as C compilers ++ incorrectly reject 9223372036854775807. */ ++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) ++ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 ++ && LARGE_OFF_T % 2147483647 == 1) ++ ? 1 : -1]; ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_sys_large_files=no; break ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#define _LARGE_FILES 1 ++#include ++ /* Check that off_t can represent 2**63 - 1 correctly. ++ We can't simply define LARGE_OFF_T to be 9223372036854775807, ++ since some C++ compilers masquerading as C compilers ++ incorrectly reject 9223372036854775807. */ ++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) ++ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 ++ && LARGE_OFF_T % 2147483647 == 1) ++ ? 1 : -1]; ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_sys_large_files=1; break ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ac_cv_sys_large_files=unknown ++ break ++done ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 ++$as_echo "$ac_cv_sys_large_files" >&6; } ++case $ac_cv_sys_large_files in #( ++ no | unknown) ;; ++ *) ++cat >>confdefs.h <<_ACEOF ++#define _LARGE_FILES $ac_cv_sys_large_files ++_ACEOF ++;; ++esac ++rm -rf conftest* ++ fi ++ ++ ++fi ++ ++ ++ ++ac_checking= ++. ${srcdir}/../bfd/development.sh ++test "$development" = true && ac_checking=yes ++# Check whether --enable-checking was given. ++if test "${enable_checking+set}" = set; then : ++ enableval=$enable_checking; case "${enableval}" in ++ no|none) ac_checking= ;; ++ *) ac_checking=yes ;; ++esac ++fi ++if test x$ac_checking != x ; then ++ ++$as_echo "#define ENABLE_CHECKING 1" >>confdefs.h ++ ++fi ++ ++ ++# Check whether --with-lib-path was given. ++if test "${with_lib_path+set}" = set; then : ++ withval=$with_lib_path; LIB_PATH=$withval ++fi ++ ++# Check whether --enable-targets was given. ++if test "${enable_targets+set}" = set; then : ++ enableval=$enable_targets; case "${enableval}" in ++ yes | "") as_fn_error $? "enable-targets option must specify target names or 'all'" "$LINENO" 5 ++ ;; ++ no) enable_targets= ;; ++ *) enable_targets=$enableval ;; ++esac ++fi ++ ++# Check whether --enable-64-bit-bfd was given. ++if test "${enable_64_bit_bfd+set}" = set; then : ++ enableval=$enable_64_bit_bfd; case $enableval in #( ++ yes|no) : ++ ;; #( ++ *) : ++ as_fn_error $? "bad value ${enableval} for 64-bit-bfd option" "$LINENO" 5 ;; #( ++ *) : ++ ;; ++esac ++else ++ enable_64_bit_bfd=no ++fi ++ ++ ++if test "x$enable_64_bit_bfd" = "xno"; then : ++ # The cast to long int works around a bug in the HP C Compiler ++# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects ++# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. ++# This bug is HP SR number 8606223364. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 ++$as_echo_n "checking size of void *... " >&6; } ++if ${ac_cv_sizeof_void_p+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : ++ ++else ++ if test "$ac_cv_type_void_p" = yes; then ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error 77 "cannot compute sizeof (void *) ++See \`config.log' for more details" "$LINENO" 5; } ++ else ++ ac_cv_sizeof_void_p=0 ++ fi ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 ++$as_echo "$ac_cv_sizeof_void_p" >&6; } ++ ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define SIZEOF_VOID_P $ac_cv_sizeof_void_p ++_ACEOF ++ ++ ++ if test "x$ac_cv_sizeof_void_p" = "x8"; then : ++ enable_64_bit_bfd=yes ++fi ++ ++fi ++ ++ if test "x$enable_64_bit_bfd" = "xyes"; then ++ ENABLE_BFD_64_BIT_TRUE= ++ ENABLE_BFD_64_BIT_FALSE='#' ++else ++ ENABLE_BFD_64_BIT_TRUE='#' ++ ENABLE_BFD_64_BIT_FALSE= ++fi ++ ++ ++ ++ ++# Check whether --with-sysroot was given. ++if test "${with_sysroot+set}" = set; then : ++ withval=$with_sysroot; ++ case ${with_sysroot} in ++ yes) TARGET_SYSTEM_ROOT='${exec_prefix}/${target_alias}/sys-root' ;; ++ *) TARGET_SYSTEM_ROOT=$with_sysroot ;; ++ esac ++ ++ TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"' ++ use_sysroot=yes ++ ++ if test "x$prefix" = xNONE; then ++ test_prefix=/usr/local ++ else ++ test_prefix=$prefix ++ fi ++ if test "x$exec_prefix" = xNONE; then ++ test_exec_prefix=$test_prefix ++ else ++ test_exec_prefix=$exec_prefix ++ fi ++ case ${TARGET_SYSTEM_ROOT} in ++ "${test_prefix}"|"${test_prefix}/"*|\ ++ "${test_exec_prefix}"|"${test_exec_prefix}/"*|\ ++ '${prefix}'|'${prefix}/'*|\ ++ '${exec_prefix}'|'${exec_prefix}/'*) ++ t="$TARGET_SYSTEM_ROOT_DEFINE -DTARGET_SYSTEM_ROOT_RELOCATABLE" ++ TARGET_SYSTEM_ROOT_DEFINE="$t" ++ ;; ++ esac ++ ++else ++ ++ use_sysroot=no ++ TARGET_SYSTEM_ROOT= ++ TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"\"' ++ ++fi ++ ++ ++ ++ ++ ++# Check whether --enable-gold was given. ++if test "${enable_gold+set}" = set; then : ++ enableval=$enable_gold; case "${enableval}" in ++ default) ++ install_as_default=no ++ installed_linker=ld.bfd ++ ;; ++ yes|no) ++ install_as_default=yes ++ installed_linker=ld.bfd ++ ;; ++ *) ++ as_fn_error $? "invalid --enable-gold argument" "$LINENO" 5 ++ ;; ++ esac ++else ++ install_as_default=yes ++ installed_linker=ld.bfd ++fi ++ ++ ++ ++ ++# Check whether --enable-got was given. ++if test "${enable_got+set}" = set; then : ++ enableval=$enable_got; case "${enableval}" in ++ target | single | negative | multigot) got_handling=$enableval ;; ++ *) as_fn_error $? "bad value ${enableval} for --enable-got option" "$LINENO" 5 ;; ++esac ++else ++ got_handling=target ++fi ++ ++ ++case "${got_handling}" in ++ target) ++ ++$as_echo "#define GOT_HANDLING_DEFAULT GOT_HANDLING_TARGET_DEFAULT" >>confdefs.h ++ ;; ++ single) ++ ++$as_echo "#define GOT_HANDLING_DEFAULT GOT_HANDLING_SINGLE" >>confdefs.h ++ ;; ++ negative) ++ ++$as_echo "#define GOT_HANDLING_DEFAULT GOT_HANDLING_NEGATIVE" >>confdefs.h ++ ;; ++ multigot) ++ ++$as_echo "#define GOT_HANDLING_DEFAULT GOT_HANDLING_MULTIGOT" >>confdefs.h ++ ;; ++ *) as_fn_error $? "bad value ${got_handling} for --enable-got option" "$LINENO" 5 ;; ++esac ++ ++# PR gas/19109 ++# Decide the default method for compressing debug sections. ++ac_default_compressed_debug_sections=unset ++# Provide a configure time option to override our default. ++# Check whether --enable-compressed_debug_sections was given. ++if test "${enable_compressed_debug_sections+set}" = set; then : ++ enableval=$enable_compressed_debug_sections; case ,"${enableval}", in ++ ,yes, | ,all, | *,ld,*) ac_default_compressed_debug_sections=yes ;; ++ ,no, | ,none,) ac_default_compressed_debug_sections=no ;; ++esac ++fi ++ ++# Select default compression algorithm. ++ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB ++# Check whether --enable-default_compressed_debug_sections_algorithm was given. ++if test "${enable_default_compressed_debug_sections_algorithm+set}" = set; then : ++ enableval=$enable_default_compressed_debug_sections_algorithm; case "${enableval}" in ++ zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; ++esac ++fi ++ ++# Decide setting DT_RUNPATH instead of DT_RPATH by default ++ac_default_new_dtags=unset ++# Provide a configure time option to override our default. ++# Check whether --enable-new_dtags was given. ++if test "${enable_new_dtags+set}" = set; then : ++ enableval=$enable_new_dtags; case "${enableval}" in ++ yes) ac_default_new_dtags=1 ;; ++ no) ac_default_new_dtags=0 ;; ++esac ++fi ++ ++# Decide if -z relro should be enabled in ELF linker by default. ++ac_default_ld_z_relro=unset ++# Provide a configure time option to override our default. ++# Check whether --enable-relro was given. ++if test "${enable_relro+set}" = set; then : ++ enableval=$enable_relro; case "${enableval}" in ++ yes) ac_default_ld_z_relro=1 ;; ++ no) ac_default_ld_z_relro=0 ;; ++esac ++fi ++ ++# Decide if DT_TEXTREL check should be enabled in ELF linker. ++ac_default_ld_textrel_check=unset ++# Check whether --enable-textrel-check was given. ++if test "${enable_textrel_check+set}" = set; then : ++ enableval=$enable_textrel_check; case "${enableval}" in ++ yes|no|warning|error) ac_default_ld_textrel_check=${enableval} ;; ++esac ++fi ++ ++ ++# Decide if -z separate-code should be enabled in ELF linker by default. ++ac_default_ld_z_separate_code=unset ++# Check whether --enable-separate-code was given. ++if test "${enable_separate_code+set}" = set; then : ++ enableval=$enable_separate_code; case "${enableval}" in ++ yes) ac_default_ld_z_separate_code=1 ;; ++ no) ac_default_ld_z_separate_code=0 ;; ++esac ++fi ++ ++ ++ ++# By default warn when an executable stack is created due to object files ++# requesting such, not when the user specifies -z execstack. ++ac_default_ld_warn_execstack=2 ++# Check whether --enable-warn-execstack was given. ++if test "${enable_warn_execstack+set}" = set; then : ++ enableval=$enable_warn_execstack; case "${enableval}" in ++ yes) ac_default_ld_warn_execstack=1 ;; ++ no) ac_default_ld_warn_execstack=0 ;; ++esac ++fi ++ ++ ++ac_default_ld_warn_rwx_segments=unset ++# Check whether --enable-warn-rwx-segments was given. ++if test "${enable_warn_rwx_segments+set}" = set; then : ++ enableval=$enable_warn_rwx_segments; case "${enableval}" in ++ yes) ac_default_ld_warn_rwx_segments=1 ;; ++ no) ac_default_ld_warn_rwx_segments=0 ;; ++esac ++fi ++ ++ ++ac_default_ld_default_execstack=unset ++# Check whether --enable-default-execstack was given. ++if test "${enable_default_execstack+set}" = set; then : ++ enableval=$enable_default_execstack; case "${enableval}" in ++ yes) ac_default_ld_default_execstack=1 ;; ++ no) ac_default_ld_default_execstack=0 ;; ++esac ++fi ++ ++ ++ ++# Decide if --error-handling-script should be supported. ++ac_support_error_handling_script=unset ++# Check whether --enable-error-handling-script was given. ++if test "${enable_error_handling_script+set}" = set; then : ++ enableval=$enable_error_handling_script; case "${enableval}" in ++ yes) ac_support_error_handling_script=1 ;; ++ no) ac_support_error_handling_script=0 ;; ++esac ++fi ++ ++ ++# Decide which "--hash-style" to use by default ++# Provide a configure time option to override our default. ++# Check whether --enable-default-hash-style was given. ++if test "${enable_default_hash_style+set}" = set; then : ++ enableval=$enable_default_hash_style; case "${enable_default_hash_style}" in ++ sysv | gnu | both) ;; ++ *) as_fn_error $? "bad value ${enable_default_hash_style} for enable-default-hash-style option" "$LINENO" 5 ;; ++esac ++else ++ case "${target}" in ++ # Enable gnu hash only on GNU targets, but not mips ++ mips*-*-*) enable_default_hash_style=sysv ;; ++ *-*-gnu* | *-*-linux* | *-*-nacl*) enable_default_hash_style=both ;; ++ *) enable_default_hash_style=sysv ;; ++esac ++fi ++ ++ ++case "${enable_default_hash_style}" in ++ sysv | both) ac_default_emit_sysv_hash=1 ;; ++ *) ac_default_emit_sysv_hash=0 ;; ++esac ++ ++case "${enable_default_hash_style}" in ++ gnu | both) ac_default_emit_gnu_hash=1 ;; ++ *) ac_default_emit_gnu_hash=0 ;; ++esac ++ ++# Check whether --enable-initfini-array was given. ++if test "${enable_initfini_array+set}" = set; then : ++ enableval=$enable_initfini_array; case "${enableval}" in ++ yes|no) ;; ++ *) as_fn_error $? "invalid --enable-initfini-array argument" "$LINENO" 5 ;; ++ esac ++else ++ enable_initfini_array=yes ++fi ++ ++ ++if test $enable_initfini_array = yes; then ++ ++$as_echo "#define HAVE_INITFINI_ARRAY 1" >>confdefs.h ++ ++fi ++ ++ # Check whether --enable-libctf was given. ++if test "${enable_libctf+set}" = set; then : ++ enableval=$enable_libctf; ++ case "$enableval" in ++ yes|no) ;; ++ *) as_fn_error $? "Argument to enable/disable libctf must be yes or no" "$LINENO" 5 ;; ++ esac ++ ++else ++ enable_libctf=yes ++fi ++ ++ ++if test "${enable_libctf}" = yes; then ++ ++$as_echo "#define ENABLE_LIBCTF 1" >>confdefs.h ++ ++fi ++ if test "${enable_libctf}" = yes; then ++ ENABLE_LIBCTF_TRUE= ++ ENABLE_LIBCTF_FALSE='#' ++else ++ ENABLE_LIBCTF_TRUE='#' ++ ENABLE_LIBCTF_FALSE= ++fi ++ ++ ++ ++# Used to validate --package-metadata= input. Disabled by default. ++# Check whether --enable-jansson was given. ++if test "${enable_jansson+set}" = set; then : ++ enableval=$enable_jansson; enable_jansson=$enableval ++else ++ enable_jansson="no" ++fi ++ ++ ++if test "x$enable_jansson" != "xno"; then : ++ ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for jansson" >&5 ++$as_echo_n "checking for jansson... " >&6; } ++ ++if test -n "$JANSSON_CFLAGS"; then ++ pkg_cv_JANSSON_CFLAGS="$JANSSON_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jansson\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "jansson") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_JANSSON_CFLAGS=`$PKG_CONFIG --cflags "jansson" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++if test -n "$JANSSON_LIBS"; then ++ pkg_cv_JANSSON_LIBS="$JANSSON_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jansson\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "jansson") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_JANSSON_LIBS=`$PKG_CONFIG --libs "jansson" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++ ++if test $pkg_failed = no; then ++ pkg_save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $pkg_cv_JANSSON_LIBS" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ++else ++ pkg_failed=yes ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS=$pkg_save_LDFLAGS ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ JANSSON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "jansson" 2>&1` ++ else ++ JANSSON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "jansson" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$JANSSON_PKG_ERRORS" >&5 ++ ++ as_fn_error $? "Cannot find jansson library" "$LINENO" 5 ++elif test $pkg_failed = untried; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ as_fn_error $? "Cannot find jansson library" "$LINENO" 5 ++else ++ JANSSON_CFLAGS=$pkg_cv_JANSSON_CFLAGS ++ JANSSON_LIBS=$pkg_cv_JANSSON_LIBS ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++ ++$as_echo "#define HAVE_JANSSON 1" >>confdefs.h ++ ++ ++ ++ ++fi ++ ++fi ++ ++ ++# Set the 'development' global. ++. $srcdir/../bfd/development.sh ++ ++# Set acp_cpp_for_build variable ++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD" ++ ++# Default set of GCC warnings to enable. ++GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes" ++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes" ++ ++# Add -Wshadow if the compiler is a sufficiently recent version of GCC. ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__GNUC__ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "(^[0-3]$|^__GNUC__$)" >/dev/null 2>&1; then : ++ ++else ++ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wshadow" ++fi ++rm -f conftest* ++ ++ ++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC. ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__GNUC__ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "(^[0-4]$|^__GNUC__$)" >/dev/null 2>&1; then : ++ ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__clang__ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "^__clang__$" >/dev/null 2>&1; then : ++ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wstack-usage=262144" ++fi ++rm -f conftest* ++ ++fi ++rm -f conftest* ++ ++ ++# Set WARN_WRITE_STRINGS if the compiler supports -Wwrite-strings. ++WARN_WRITE_STRINGS="" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__GNUC__ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "(^[0-3]$|^__GNUC__$)" >/dev/null 2>&1; then : ++ ++else ++ WARN_WRITE_STRINGS="-Wwrite-strings" ++fi ++rm -f conftest* ++ ++ ++# Verify CC_FOR_BUILD to be compatible with warning flags ++ ++# Add -Wshadow if the compiler is a sufficiently recent version of GCC. ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__GNUC__ ++_ACEOF ++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 | ++ $EGREP "(^[0-3]$|^__GNUC__$)" >/dev/null 2>&1; then : ++ ++else ++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow" ++fi ++rm -f conftest* ++ ++ ++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC. ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__GNUC__ ++_ACEOF ++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 | ++ $EGREP "(^[0-4]$|^__GNUC__$)" >/dev/null 2>&1; then : ++ ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++__clang__ ++_ACEOF ++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 | ++ $EGREP "^__clang__$" >/dev/null 2>&1; then : ++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144" ++fi ++rm -f conftest* ++ ++fi ++rm -f conftest* ++ ++ ++# Check whether --enable-werror was given. ++if test "${enable_werror+set}" = set; then : ++ enableval=$enable_werror; case "${enableval}" in ++ yes | y) ERROR_ON_WARNING="yes" ;; ++ no | n) ERROR_ON_WARNING="no" ;; ++ *) as_fn_error $? "bad value ${enableval} for --enable-werror" "$LINENO" 5 ;; ++ esac ++fi ++ ++ ++# Disable -Wformat by default when using gcc on mingw ++case "${host}" in ++ *-*-mingw32*) ++ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then ++ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format" ++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format" ++ fi ++ ;; ++ *) ;; ++esac ++ ++# Enable -Werror by default when using gcc. Turn it off for releases. ++if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" -a "$development" = true ; then ++ ERROR_ON_WARNING=yes ++fi ++ ++NO_WERROR= ++if test "${ERROR_ON_WARNING}" = yes ; then ++ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror" ++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror" ++ NO_WERROR="-Wno-error" ++fi ++ ++if test "${GCC}" = yes ; then ++ WARN_CFLAGS="${GCC_WARN_CFLAGS}" ++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}" ++fi ++ ++# Check whether --enable-build-warnings was given. ++if test "${enable_build_warnings+set}" = set; then : ++ enableval=$enable_build_warnings; case "${enableval}" in ++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}" ++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";; ++ no) if test "${GCC}" = yes ; then ++ WARN_CFLAGS="-w" ++ WARN_CFLAGS_FOR_BUILD="-w" ++ fi;; ++ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` ++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}" ++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";; ++ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` ++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}" ++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";; ++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"` ++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;; ++esac ++fi ++ ++ ++if test x"$silent" != x"yes" && test x"$WARN_CFLAGS" != x""; then ++ echo "Setting warning flags = $WARN_CFLAGS" 6>&1 ++fi ++ ++ ++ ++ ++ ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5 ++$as_echo_n "checking for LC_MESSAGES... " >&6; } ++if ${am_cv_val_LC_MESSAGES+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++int ++main () ++{ ++return LC_MESSAGES ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ am_cv_val_LC_MESSAGES=yes ++else ++ am_cv_val_LC_MESSAGES=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_val_LC_MESSAGES" >&5 ++$as_echo "$am_cv_val_LC_MESSAGES" >&6; } ++ if test $am_cv_val_LC_MESSAGES = yes; then ++ ++$as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h ++ ++ fi ++ ++ ++ac_config_headers="$ac_config_headers config.h:config.in" ++ ++ ++# PR 14072 ++ ++ ++if test -z "$target" ; then ++ as_fn_error $? "Unrecognized target system type; please check config.sub." "$LINENO" 5 ++fi ++if test -z "$host" ; then ++ as_fn_error $? "Unrecognized host system type; please check config.sub." "$LINENO" 5 ++fi ++ ++# host-specific stuff: ++ ++ALL_LINGUAS="bg da de es fi fr ga id it ja pt_BR ru sr sv tr uk vi zh_CN zh_TW" ++# If we haven't got the data from the intl directory, ++# assume NLS is disabled. ++USE_NLS=no ++LIBINTL= ++LIBINTL_DEP= ++INCINTL= ++XGETTEXT= ++GMSGFMT= ++POSUB= ++ ++if test -f ../intl/config.intl; then ++ . ../intl/config.intl ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 ++$as_echo_n "checking whether NLS is requested... " >&6; } ++if test x"$USE_NLS" != xyes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++$as_echo "#define ENABLE_NLS 1" >>confdefs.h ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5 ++$as_echo_n "checking for catalogs to be installed... " >&6; } ++ # Look for .po and .gmo files in the source directory. ++ CATALOGS= ++ XLINGUAS= ++ for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do ++ # If there aren't any .gmo files the shell will give us the ++ # literal string "../path/to/srcdir/po/*.gmo" which has to be ++ # weeded out. ++ case "$cat" in *\**) ++ continue;; ++ esac ++ # The quadruple backslash is collapsed to a double backslash ++ # by the backticks, then collapsed again by the double quotes, ++ # leaving us with one backslash in the sed expression (right ++ # before the dot that mustn't act as a wildcard). ++ cat=`echo $cat | sed -e "s!$srcdir/po/!!" -e "s!\\\\.po!.gmo!"` ++ lang=`echo $cat | sed -e "s!\\\\.gmo!!"` ++ # The user is allowed to set LINGUAS to a list of languages to ++ # install catalogs for. If it's empty that means "all of them." ++ if test "x$LINGUAS" = x; then ++ CATALOGS="$CATALOGS $cat" ++ XLINGUAS="$XLINGUAS $lang" ++ else ++ case "$LINGUAS" in *$lang*) ++ CATALOGS="$CATALOGS $cat" ++ XLINGUAS="$XLINGUAS $lang" ++ ;; ++ esac ++ fi ++ done ++ LINGUAS="$XLINGUAS" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5 ++$as_echo "$LINGUAS" >&6; } ++ ++ ++ DATADIRNAME=share ++ ++ INSTOBJEXT=.mo ++ ++ GENCAT=gencat ++ ++ CATOBJEXT=.gmo ++ ++fi ++ ++ MKINSTALLDIRS= ++ if test -n "$ac_aux_dir"; then ++ case "$ac_aux_dir" in ++ /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; ++ *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; ++ esac ++ fi ++ if test -z "$MKINSTALLDIRS"; then ++ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" ++ fi ++ ++ ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 ++$as_echo_n "checking whether NLS is requested... " >&6; } ++ # Check whether --enable-nls was given. ++if test "${enable_nls+set}" = set; then : ++ enableval=$enable_nls; USE_NLS=$enableval ++else ++ USE_NLS=yes ++fi ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 ++$as_echo "$USE_NLS" >&6; } ++ ++ ++ ++ ++ ++ ++# Prepare PATH_SEPARATOR. ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ ++# Find out how to test for executable files. Don't use a zero-byte file, ++# as systems may use methods other than mode bits to determine executability. ++cat >conf$$.file <<_ASEOF ++#! /bin/sh ++exit 0 ++_ASEOF ++chmod +x conf$$.file ++if test -x conf$$.file >/dev/null 2>&1; then ++ ac_executable_p="test -x" ++else ++ ac_executable_p="test -f" ++fi ++rm -f conf$$.file ++ ++# Extract the first word of "msgfmt", so it can be a program name with args. ++set dummy msgfmt; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_MSGFMT+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case "$MSGFMT" in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ++ ;; ++ *) ++ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$ac_save_IFS" ++ test -z "$ac_dir" && ac_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then ++ if $ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && ++ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ++ ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" ++ break 2 ++ fi ++ fi ++ done ++ done ++ IFS="$ac_save_IFS" ++ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" ++ ;; ++esac ++fi ++MSGFMT="$ac_cv_path_MSGFMT" ++if test "$MSGFMT" != ":"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 ++$as_echo "$MSGFMT" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ # Extract the first word of "gmsgfmt", so it can be a program name with args. ++set dummy gmsgfmt; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_GMSGFMT+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $GMSGFMT in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ++ ;; ++esac ++fi ++GMSGFMT=$ac_cv_path_GMSGFMT ++if test -n "$GMSGFMT"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 ++$as_echo "$GMSGFMT" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ ++ ++# Prepare PATH_SEPARATOR. ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ ++# Find out how to test for executable files. Don't use a zero-byte file, ++# as systems may use methods other than mode bits to determine executability. ++cat >conf$$.file <<_ASEOF ++#! /bin/sh ++exit 0 ++_ASEOF ++chmod +x conf$$.file ++if test -x conf$$.file >/dev/null 2>&1; then ++ ac_executable_p="test -x" ++else ++ ac_executable_p="test -f" ++fi ++rm -f conf$$.file ++ ++# Extract the first word of "xgettext", so it can be a program name with args. ++set dummy xgettext; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_XGETTEXT+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case "$XGETTEXT" in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ++ ;; ++ *) ++ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$ac_save_IFS" ++ test -z "$ac_dir" && ac_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then ++ if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && ++ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ++ ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" ++ break 2 ++ fi ++ fi ++ done ++ done ++ IFS="$ac_save_IFS" ++ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ++ ;; ++esac ++fi ++XGETTEXT="$ac_cv_path_XGETTEXT" ++if test "$XGETTEXT" != ":"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 ++$as_echo "$XGETTEXT" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ rm -f messages.po ++ ++ ++# Prepare PATH_SEPARATOR. ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ ++# Find out how to test for executable files. Don't use a zero-byte file, ++# as systems may use methods other than mode bits to determine executability. ++cat >conf$$.file <<_ASEOF ++#! /bin/sh ++exit 0 ++_ASEOF ++chmod +x conf$$.file ++if test -x conf$$.file >/dev/null 2>&1; then ++ ac_executable_p="test -x" ++else ++ ac_executable_p="test -f" ++fi ++rm -f conf$$.file ++ ++# Extract the first word of "msgmerge", so it can be a program name with args. ++set dummy msgmerge; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_MSGMERGE+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case "$MSGMERGE" in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ++ ;; ++ *) ++ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$ac_save_IFS" ++ test -z "$ac_dir" && ac_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then ++ if $ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1; then ++ ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" ++ break 2 ++ fi ++ fi ++ done ++ done ++ IFS="$ac_save_IFS" ++ test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" ++ ;; ++esac ++fi ++MSGMERGE="$ac_cv_path_MSGMERGE" ++if test "$MSGMERGE" != ":"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 ++$as_echo "$MSGMERGE" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ if test "$GMSGFMT" != ":"; then ++ if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && ++ (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ++ : ; ++ else ++ GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $GMSGFMT program is not GNU msgfmt; ignore it" >&5 ++$as_echo "found $GMSGFMT program is not GNU msgfmt; ignore it" >&6; } ++ GMSGFMT=":" ++ fi ++ fi ++ ++ if test "$XGETTEXT" != ":"; then ++ if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && ++ (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ++ : ; ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found xgettext program is not GNU xgettext; ignore it" >&5 ++$as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; } ++ XGETTEXT=":" ++ fi ++ rm -f messages.po ++ fi ++ ++ ac_config_commands="$ac_config_commands default-1" ++ ++ ++ ++ ++ ++for ac_prog in 'bison -y' byacc ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_YACC+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$YACC"; then ++ ac_cv_prog_YACC="$YACC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_YACC="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++YACC=$ac_cv_prog_YACC ++if test -n "$YACC"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 ++$as_echo "$YACC" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$YACC" && break ++done ++test -n "$YACC" || YACC="yacc" ++ ++for ac_prog in flex lex ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_prog_LEX+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -n "$LEX"; then ++ ac_cv_prog_LEX="$LEX" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_LEX="$ac_prog" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++fi ++fi ++LEX=$ac_cv_prog_LEX ++if test -n "$LEX"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 ++$as_echo "$LEX" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++ test -n "$LEX" && break ++done ++test -n "$LEX" || LEX=":" ++ ++case "$LEX" in ++ :|*"missing "*) ;; ++ *) cat >conftest.l <<_ACEOF ++%% ++a { ECHO; } ++b { REJECT; } ++c { yymore (); } ++d { yyless (1); } ++e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ ++ yyless ((input () != 0)); } ++f { unput (yytext[0]); } ++. { BEGIN INITIAL; } ++%% ++#ifdef YYTEXT_POINTER ++extern char *yytext; ++#endif ++int ++main (void) ++{ ++ return ! yylex () + ! yywrap (); ++} ++_ACEOF ++{ { ac_try="$LEX conftest.l" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$LEX conftest.l") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 ++$as_echo_n "checking lex output file root... " >&6; } ++if ${ac_cv_prog_lex_root+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ++if test -f lex.yy.c; then ++ ac_cv_prog_lex_root=lex.yy ++elif test -f lexyy.c; then ++ ac_cv_prog_lex_root=lexyy ++else ++ as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 ++fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 ++$as_echo "$ac_cv_prog_lex_root" >&6; } ++LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root ++ ++if test -z "${LEXLIB+set}"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 ++$as_echo_n "checking lex library... " >&6; } ++if ${ac_cv_lib_lex+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ++ ac_save_LIBS=$LIBS ++ ac_cv_lib_lex='none needed' ++ for ac_lib in '' -lfl -ll; do ++ LIBS="$ac_lib $ac_save_LIBS" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++`cat $LEX_OUTPUT_ROOT.c` ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_lex=$ac_lib ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ test "$ac_cv_lib_lex" != 'none needed' && break ++ done ++ LIBS=$ac_save_LIBS ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 ++$as_echo "$ac_cv_lib_lex" >&6; } ++ test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 ++$as_echo_n "checking whether yytext is a pointer... " >&6; } ++if ${ac_cv_prog_lex_yytext_pointer+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # POSIX says lex can declare yytext either as a pointer or an array; the ++# default is implementation-dependent. Figure out which it is, since ++# not all implementations provide the %pointer and %array declarations. ++ac_cv_prog_lex_yytext_pointer=no ++ac_save_LIBS=$LIBS ++LIBS="$LEXLIB $ac_save_LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++ #define YYTEXT_POINTER 1 ++`cat $LEX_OUTPUT_ROOT.c` ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_prog_lex_yytext_pointer=yes ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_save_LIBS ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 ++$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } ++if test $ac_cv_prog_lex_yytext_pointer = yes; then ++ ++$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h ++ ++fi ++rm -f conftest.l $LEX_OUTPUT_ROOT.c ++ ;; ++esac ++if test "$LEX" = :; then ++ LEX=${am_missing_run}flex ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 ++$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } ++ # Check whether --enable-maintainer-mode was given. ++if test "${enable_maintainer_mode+set}" = set; then : ++ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval ++else ++ USE_MAINTAINER_MODE=no ++fi ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 ++$as_echo "$USE_MAINTAINER_MODE" >&6; } ++ if test $USE_MAINTAINER_MODE = yes; then ++ MAINTAINER_MODE_TRUE= ++ MAINTAINER_MODE_FALSE='#' ++else ++ MAINTAINER_MODE_TRUE='#' ++ MAINTAINER_MODE_FALSE= ++fi ++ ++ MAINT=$MAINTAINER_MODE_TRUE ++ ++ ++ if false; then ++ GENINSRC_NEVER_TRUE= ++ GENINSRC_NEVER_FALSE='#' ++else ++ GENINSRC_NEVER_TRUE='#' ++ GENINSRC_NEVER_FALSE= ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to compare bootstrapped objects" >&5 ++$as_echo_n "checking how to compare bootstrapped objects... " >&6; } ++if ${gcc_cv_prog_cmp_skip+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ echo abfoo >t1 ++ echo cdfoo >t2 ++ gcc_cv_prog_cmp_skip='tail -c +17 $$f1 > tmp-foo1; tail -c +17 $$f2 > tmp-foo2; cmp tmp-foo1 tmp-foo2' ++ if cmp t1 t2 2 2 > /dev/null 2>&1; then ++ if cmp t1 t2 1 1 > /dev/null 2>&1; then ++ : ++ else ++ gcc_cv_prog_cmp_skip='cmp $$f1 $$f2 16 16' ++ fi ++ fi ++ if cmp --ignore-initial=2 t1 t2 > /dev/null 2>&1; then ++ if cmp --ignore-initial=1 t1 t2 > /dev/null 2>&1; then ++ : ++ else ++ gcc_cv_prog_cmp_skip='cmp --ignore-initial=16 $$f1 $$f2' ++ fi ++ fi ++ rm t1 t2 ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_prog_cmp_skip" >&5 ++$as_echo "$gcc_cv_prog_cmp_skip" >&6; } ++do_compare="$gcc_cv_prog_cmp_skip" ++ ++ ++ ++. ${srcdir}/configure.host ++ ++ ++ ++ ++# We use headers from include/ that check various HAVE_*_H macros, thus ++# should ensure they are set by configure. This is true even when C99 ++# guarantees they are available. ++# sha1.h and md4.h test HAVE_LIMITS_H, HAVE_SYS_TYPES_H and HAVE_STDINT_H ++# plugin-api.h tests HAVE_STDINT_H and HAVE_INTTYPES_H ++# Besides those, we need to check anything used in ld/ not in C99. ++for ac_header in fcntl.h elf-hints.h limits.h inttypes.h stdint.h \ ++ sys/file.h sys/mman.h sys/param.h sys/stat.h sys/time.h \ ++ sys/types.h unistd.h ++do : ++ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ++ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ++if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++for ac_func in close glob lseek mkstemp open realpath waitpid ++do : ++ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ++ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ++if eval test \"x\$"$as_ac_var"\" = x"yes"; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++done ++ ++ ++ ++case "${host}" in ++*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) ++ ++$as_echo "#define USE_BINARY_FOPEN 1" >>confdefs.h ++ ;; ++esac ++ ++ac_fn_c_check_decl "$LINENO" "asprintf" "ac_cv_have_decl_asprintf" "$ac_includes_default" ++if test "x$ac_cv_have_decl_asprintf" = xyes; then : ++ ac_have_decl=1 ++else ++ ac_have_decl=0 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_DECL_ASPRINTF $ac_have_decl ++_ACEOF ++ac_fn_c_check_decl "$LINENO" "environ" "ac_cv_have_decl_environ" "$ac_includes_default" ++if test "x$ac_cv_have_decl_environ" = xyes; then : ++ ac_have_decl=1 ++else ++ ac_have_decl=0 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_DECL_ENVIRON $ac_have_decl ++_ACEOF ++ ++ ++ ++ ++ ++ for ac_header in $ac_header_list ++do : ++ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ++ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default ++" ++if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ ++ ++ ++ ++ ++ ++ ++for ac_func in getpagesize ++do : ++ ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" ++if test "x$ac_cv_func_getpagesize" = xyes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_GETPAGESIZE 1 ++_ACEOF ++ ++fi ++done ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 ++$as_echo_n "checking for working mmap... " >&6; } ++if ${ac_cv_func_mmap_fixed_mapped+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ ac_cv_func_mmap_fixed_mapped=no ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$ac_includes_default ++/* malloc might have been renamed as rpl_malloc. */ ++#undef malloc ++ ++/* Thanks to Mike Haertel and Jim Avera for this test. ++ Here is a matrix of mmap possibilities: ++ mmap private not fixed ++ mmap private fixed at somewhere currently unmapped ++ mmap private fixed at somewhere already mapped ++ mmap shared not fixed ++ mmap shared fixed at somewhere currently unmapped ++ mmap shared fixed at somewhere already mapped ++ For private mappings, we should verify that changes cannot be read() ++ back from the file, nor mmap's back from the file at a different ++ address. (There have been systems where private was not correctly ++ implemented like the infamous i386 svr4.0, and systems where the ++ VM page cache was not coherent with the file system buffer cache ++ like early versions of FreeBSD and possibly contemporary NetBSD.) ++ For shared mappings, we should conversely verify that changes get ++ propagated back to all the places they're supposed to be. ++ ++ Grep wants private fixed already mapped. ++ The main things grep needs to know about mmap are: ++ * does it exist and is it safe to write into the mmap'd area ++ * how to use it (BSD variants) */ ++ ++#include ++#include ++ ++#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H ++char *malloc (); ++#endif ++ ++/* This mess was copied from the GNU getpagesize.h. */ ++#ifndef HAVE_GETPAGESIZE ++# ifdef _SC_PAGESIZE ++# define getpagesize() sysconf(_SC_PAGESIZE) ++# else /* no _SC_PAGESIZE */ ++# ifdef HAVE_SYS_PARAM_H ++# include ++# ifdef EXEC_PAGESIZE ++# define getpagesize() EXEC_PAGESIZE ++# else /* no EXEC_PAGESIZE */ ++# ifdef NBPG ++# define getpagesize() NBPG * CLSIZE ++# ifndef CLSIZE ++# define CLSIZE 1 ++# endif /* no CLSIZE */ ++# else /* no NBPG */ ++# ifdef NBPC ++# define getpagesize() NBPC ++# else /* no NBPC */ ++# ifdef PAGESIZE ++# define getpagesize() PAGESIZE ++# endif /* PAGESIZE */ ++# endif /* no NBPC */ ++# endif /* no NBPG */ ++# endif /* no EXEC_PAGESIZE */ ++# else /* no HAVE_SYS_PARAM_H */ ++# define getpagesize() 8192 /* punt totally */ ++# endif /* no HAVE_SYS_PARAM_H */ ++# endif /* no _SC_PAGESIZE */ ++ ++#endif /* no HAVE_GETPAGESIZE */ ++ ++int ++main () ++{ ++ char *data, *data2, *data3; ++ const char *cdata2; ++ int i, pagesize; ++ int fd, fd2; ++ ++ pagesize = getpagesize (); ++ ++ /* First, make a file with some known garbage in it. */ ++ data = (char *) malloc (pagesize); ++ if (!data) ++ return 1; ++ for (i = 0; i < pagesize; ++i) ++ *(data + i) = rand (); ++ umask (0); ++ fd = creat ("conftest.mmap", 0600); ++ if (fd < 0) ++ return 2; ++ if (write (fd, data, pagesize) != pagesize) ++ return 3; ++ close (fd); ++ ++ /* Next, check that the tail of a page is zero-filled. File must have ++ non-zero length, otherwise we risk SIGBUS for entire page. */ ++ fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); ++ if (fd2 < 0) ++ return 4; ++ cdata2 = ""; ++ if (write (fd2, cdata2, 1) != 1) ++ return 5; ++ data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); ++ if (data2 == MAP_FAILED) ++ return 6; ++ for (i = 0; i < pagesize; ++i) ++ if (*(data2 + i)) ++ return 7; ++ close (fd2); ++ if (munmap (data2, pagesize)) ++ return 8; ++ ++ /* Next, try to mmap the file at a fixed address which already has ++ something else allocated at it. If we can, also make sure that ++ we see the same garbage. */ ++ fd = open ("conftest.mmap", O_RDWR); ++ if (fd < 0) ++ return 9; ++ if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_FIXED, fd, 0L)) ++ return 10; ++ for (i = 0; i < pagesize; ++i) ++ if (*(data + i) != *(data2 + i)) ++ return 11; ++ ++ /* Finally, make sure that changes to the mapped area do not ++ percolate back to the file as seen by read(). (This is a bug on ++ some variants of i386 svr4.0.) */ ++ for (i = 0; i < pagesize; ++i) ++ *(data2 + i) = *(data2 + i) + 1; ++ data3 = (char *) malloc (pagesize); ++ if (!data3) ++ return 12; ++ if (read (fd, data3, pagesize) != pagesize) ++ return 13; ++ for (i = 0; i < pagesize; ++i) ++ if (*(data + i) != *(data3 + i)) ++ return 14; ++ close (fd); ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ ac_cv_func_mmap_fixed_mapped=yes ++else ++ ac_cv_func_mmap_fixed_mapped=no ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 ++$as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } ++if test $ac_cv_func_mmap_fixed_mapped = yes; then ++ ++$as_echo "#define HAVE_MMAP 1" >>confdefs.h ++ ++fi ++rm -f conftest.mmap conftest.txt ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 ++$as_echo_n "checking for library containing dlopen... " >&6; } ++if ${ac_cv_search_dlopen+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_func_search_save_LIBS=$LIBS ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dlopen (); ++int ++main () ++{ ++return dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++for ac_lib in '' dl; do ++ if test -z "$ac_lib"; then ++ ac_res="none required" ++ else ++ ac_res=-l$ac_lib ++ LIBS="-l$ac_lib $ac_func_search_save_LIBS" ++ fi ++ if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_search_dlopen=$ac_res ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext ++ if ${ac_cv_search_dlopen+:} false; then : ++ break ++fi ++done ++if ${ac_cv_search_dlopen+:} false; then : ++ ++else ++ ac_cv_search_dlopen=no ++fi ++rm conftest.$ac_ext ++LIBS=$ac_func_search_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 ++$as_echo "$ac_cv_search_dlopen" >&6; } ++ac_res=$ac_cv_search_dlopen ++if test "$ac_res" != no; then : ++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ++ ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a known getopt prototype in unistd.h" >&5 ++$as_echo_n "checking for a known getopt prototype in unistd.h... " >&6; } ++if ${ld_cv_decl_getopt_unistd_h+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++int ++main () ++{ ++extern int getopt (int, char *const*, const char *); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ld_cv_decl_getopt_unistd_h=yes ++else ++ ld_cv_decl_getopt_unistd_h=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_cv_decl_getopt_unistd_h" >&5 ++$as_echo "$ld_cv_decl_getopt_unistd_h" >&6; } ++if test $ld_cv_decl_getopt_unistd_h = yes; then ++ ++$as_echo "#define HAVE_DECL_GETOPT 1" >>confdefs.h ++ ++fi ++ ++# Link in zlib/zstd if we can. This allows us to read and write ++# compressed debug sections. ++ ++ # Use the system's zlib library. ++ zlibdir="-L\$(top_builddir)/../zlib" ++ zlibinc="-I\$(top_srcdir)/../zlib" ++ ++# Check whether --with-system-zlib was given. ++if test "${with_system_zlib+set}" = set; then : ++ withval=$with_system_zlib; if test x$with_system_zlib = xyes ; then ++ zlibdir= ++ zlibinc= ++ fi ++ ++fi ++ ++ ++ ++ ++ ++ ++# Check whether --with-zstd was given. ++if test "${with_zstd+set}" = set; then : ++ withval=$with_zstd; ++else ++ with_zstd=auto ++fi ++ ++ ++if test "$with_zstd" != no; then : ++ ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libzstd >= 1.4.0" >&5 ++$as_echo_n "checking for libzstd >= 1.4.0... " >&6; } ++ ++if test -n "$ZSTD_CFLAGS"; then ++ pkg_cv_ZSTD_CFLAGS="$ZSTD_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd >= 1.4.0\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libzstd >= 1.4.0") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_ZSTD_CFLAGS=`$PKG_CONFIG --cflags "libzstd >= 1.4.0" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++if test -n "$ZSTD_LIBS"; then ++ pkg_cv_ZSTD_LIBS="$ZSTD_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd >= 1.4.0\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libzstd >= 1.4.0") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_ZSTD_LIBS=`$PKG_CONFIG --libs "libzstd >= 1.4.0" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++ ++if test $pkg_failed = no; then ++ pkg_save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $pkg_cv_ZSTD_LIBS" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ++else ++ pkg_failed=yes ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ LDFLAGS=$pkg_save_LDFLAGS ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ ZSTD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libzstd >= 1.4.0" 2>&1` ++ else ++ ZSTD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libzstd >= 1.4.0" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$ZSTD_PKG_ERRORS" >&5 ++ ++ ++ if test "$with_zstd" = yes; then ++ as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5 ++ fi ++ ++elif test $pkg_failed = untried; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++ if test "$with_zstd" = yes; then ++ as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5 ++ fi ++ ++else ++ ZSTD_CFLAGS=$pkg_cv_ZSTD_CFLAGS ++ ZSTD_LIBS=$pkg_cv_ZSTD_LIBS ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++ ++$as_echo "#define HAVE_ZSTD 1" >>confdefs.h ++ ++ ++fi ++ ++fi ++ ++ ++# When converting linker scripts into strings for use in emulation ++# files, use astring.sed if the compiler supports ANSI string ++# concatenation, or ostring.sed otherwise. This is to support the ++# broken Microsoft MSVC compiler, which limits the length of string ++# constants, while still supporting pre-ANSI compilers which do not ++# support string concatenation. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ANSI C string concatenation works" >&5 ++$as_echo_n "checking whether ANSI C string concatenation works... " >&6; } ++if ${ld_cv_string_concatenation+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++char *a = "a" "a"; ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ld_cv_string_concatenation=yes ++else ++ ld_cv_string_concatenation=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_cv_string_concatenation" >&5 ++$as_echo "$ld_cv_string_concatenation" >&6; } ++if test "$ld_cv_string_concatenation" = "yes"; then ++ STRINGIFY=astring.sed ++else ++ STRINGIFY=ostring.sed ++fi ++ ++ ++# target-specific stuff: ++ ++all_targets= ++EMUL= ++all_emuls= ++all_emul_extras= ++all_libpath= ++TDIRS= ++ ++elf_list_options=false ++elf_shlib_list_options=false ++elf_plt_unwind_list_options=false ++for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'` ++do ++ if test "$targ_alias" = "all"; then ++ all_targets=true ++ elf_list_options=true ++ elf_shlib_list_options=true ++ elf_plt_unwind_list_options=true ++ else ++ # Canonicalize the secondary target names. ++ result=`$ac_config_sub $targ_alias 2>/dev/null` ++ if test -n "$result"; then ++ targ=$result ++ else ++ targ=$targ_alias ++ fi ++ ++ . ${srcdir}/configure.tgt ++ ++ if test "$targ" = "$target"; then ++ EMUL=$targ_emul ++ fi ++ ++ if test x${enable_64_bit_bfd} = xno; then ++ . ${srcdir}/../bfd/config.bfd ++ fi ++ ++ if test x${enable_64_bit_bfd} = xyes; then ++ targ_extra_emuls="$targ_extra_emuls $targ64_extra_emuls" ++ targ_extra_libpath="$targ_extra_libpath $targ64_extra_libpath" ++ fi ++ ++ for i in $targ_emul $targ_extra_emuls $targ_extra_libpath; do ++ case " $all_emuls " in ++ *" e${i}.o "*) ;; ++ *) ++ all_emuls="$all_emuls e${i}.o" ++ eval result=\$tdir_$i ++ test -z "$result" && result=$targ_alias ++ TDIRS="$TDIRS ++tdir_$i=$result" ++ case "${i}" in ++ *elf*) ++ elf_list_options=true ++ ;; ++ *) ++ if $GREP "TEMPLATE_NAME=elf" ${srcdir}/emulparams/${i}.sh >/dev/null 2>/dev/null; then ++ elf_list_options=true ++ fi ++ ;; ++ esac ++ if test "$elf_list_options" = "true"; then ++ source_sh() ++ { ++ . $1 ++ } ++ source_sh ${srcdir}/emulparams/${i}.sh ++ if test x${GENERATE_SHLIB_SCRIPT} = xyes; then ++ elf_shlib_list_options=true ++ fi ++ if test x${PLT_UNWIND} = xyes; then ++ elf_plt_unwind_list_options=true ++ fi ++ fi ++ ;; ++ esac ++ done ++ ++ for i in $targ_emul $targ_extra_libpath; do ++ case " $all_libpath " in ++ *" ${i} "*) ;; ++ *) ++ if test -z "$all_libpath"; then ++ all_libpath=${i} ++ else ++ all_libpath="$all_libpath ${i}" ++ fi ++ ;; ++ esac ++ done ++ ++ for i in $targ_extra_ofiles; do ++ case " $all_emul_extras " in ++ *" ${i} "*) ;; ++ *) ++ all_emul_extras="$all_emul_extras ${i}" ++ ;; ++ esac ++ done ++ ++ fi ++done ++ ++if test x$ac_default_compressed_debug_sections = xyes ; then ++ ++$as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h ++ ++fi ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_COMPRESSED_DEBUG_ALGORITHM $ac_default_compressed_debug_sections_algorithm ++_ACEOF ++ ++ ++if test "${ac_default_new_dtags}" = unset; then ++ ac_default_new_dtags=0 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_NEW_DTAGS $ac_default_new_dtags ++_ACEOF ++ ++ ++if test "${ac_default_ld_z_relro}" = unset; then ++ ac_default_ld_z_relro=0 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_Z_RELRO $ac_default_ld_z_relro ++_ACEOF ++ ++ ++ac_default_ld_textrel_check_warning=0 ++case "${ac_default_ld_textrel_check}" in ++ unset|no) ++ ac_default_ld_textrel_check=textrel_check_none ++ ;; ++ yes|warning) ++ ac_default_ld_textrel_check=textrel_check_warning ++ ac_default_ld_textrel_check_warning=1 ++ ;; ++ error) ++ ac_default_ld_textrel_check=textrel_check_error ++ ;; ++esac ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_TEXTREL_CHECK $ac_default_ld_textrel_check ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_TEXTREL_CHECK_WARNING $ac_default_ld_textrel_check_warning ++_ACEOF ++ ++ ++if test "${ac_default_ld_z_separate_code}" = unset; then ++ ac_default_ld_z_separate_code=0 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_Z_SEPARATE_CODE $ac_default_ld_z_separate_code ++_ACEOF ++ ++ ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_WARN_EXECSTACK $ac_default_ld_warn_execstack ++_ACEOF ++ ++ ++if test "${ac_default_ld_warn_rwx_segments}" = unset; then ++ ac_default_ld_warn_rwx_segments=1 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_WARN_RWX_SEGMENTS $ac_default_ld_warn_rwx_segments ++_ACEOF ++ ++ ++if test "${ac_default_ld_default_execstack}" = unset; then ++ ac_default_ld_default_execstack=1 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_LD_EXECSTACK $ac_default_ld_default_execstack ++_ACEOF ++ ++ ++ ++if test "${ac_support_error_handling_script}" = unset; then ++ ac_support_error_handling_script=1 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define SUPPORT_ERROR_HANDLING_SCRIPT $ac_support_error_handling_script ++_ACEOF ++ ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_EMIT_SYSV_HASH $ac_default_emit_sysv_hash ++_ACEOF ++ ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_EMIT_GNU_HASH $ac_default_emit_gnu_hash ++_ACEOF ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++if test x${all_targets} = xtrue; then ++ if test x${enable_64_bit_bfd} = xyes; then ++ EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)' ++ EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES) $(ALL_64_EMUL_EXTRA_OFILES)' ++ else ++ EMULATION_OFILES='$(ALL_EMULATIONS)' ++ EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES)' ++ fi ++else ++ EMULATION_OFILES=$all_emuls ++ EMUL_EXTRA_OFILES=$all_emul_extras ++fi ++ ++ ++ ++ ++EMULATION_LIBPATH=$all_libpath ++ ++ ++if test x${enable_static} = xno; then ++ TESTBFDLIB="-Wl,--rpath,../bfd/.libs ../bfd/.libs/libbfd.so" ++ TESTCTFLIB="-Wl,--rpath,../libctf/.libs ../libctf/.libs/libctf.so" ++ TESTSFRAMELIB="-Wl,--rpath,../libsframe/.libs ../libsframe/.libs/libsframe.so" ++else ++ TESTBFDLIB="../bfd/.libs/libbfd.a" ++ TESTCTFLIB="../libctf/.libs/libctf.a" ++ TESTSFRAMELIB="../libsframe/.libs/libsframe.a" ++fi ++if test "${enable_libctf}" = no; then ++ TESTCTFLIB= ++fi ++ ++ ++ ++ ++target_vendor=${target_vendor=$host_vendor} ++case "$target_vendor" in ++ hp) EXTRA_SHLIB_EXTENSION=".sl" ;; ++ *) EXTRA_SHLIB_EXTENSION= ;; ++esac ++ ++case "$target_os" in ++ lynxos) EXTRA_SHLIB_EXTENSION=".a" ;; ++esac ++ ++if test x${EXTRA_SHLIB_EXTENSION} != x ; then ++ ++cat >>confdefs.h <<_ACEOF ++#define EXTRA_SHLIB_EXTENSION "$EXTRA_SHLIB_EXTENSION" ++_ACEOF ++ ++fi ++ ++ac_config_commands="$ac_config_commands default" ++ ++ ++ ++ ++ ++ ++ ++ac_config_files="$ac_config_files Makefile po/Makefile.in:po/Make-in" ++ ++cat >confcache <<\_ACEOF ++# This file is a shell script that caches the results of configure ++# tests run on this system so they can be shared between configure ++# scripts and configure runs, see configure's option --config-cache. ++# It is not useful on other systems. If it contains results you don't ++# want to keep, you may remove or edit it. ++# ++# config.status only pays attention to the cache file if you give it ++# the --recheck option to rerun configure. ++# ++# `ac_cv_env_foo' variables (set or unset) will be overridden when ++# loading this file, other *unset* `ac_cv_foo' will be assigned the ++# following values. ++ ++_ACEOF ++ ++# The following way of writing the cache mishandles newlines in values, ++# but we know of no workaround that is simple, portable, and efficient. ++# So, we kill variables containing newlines. ++# Ultrix sh set writes to stderr and can't be redirected directly, ++# and sets the high bit in the cache file unless we assign to the vars. ++( ++ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do ++ eval ac_val=\$$ac_var ++ case $ac_val in #( ++ *${as_nl}*) ++ case $ac_var in #( ++ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 ++$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ++ esac ++ case $ac_var in #( ++ _ | IFS | as_nl) ;; #( ++ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( ++ *) { eval $ac_var=; unset $ac_var;} ;; ++ esac ;; ++ esac ++ done ++ ++ (set) 2>&1 | ++ case $as_nl`(ac_space=' '; set) 2>&1` in #( ++ *${as_nl}ac_space=\ *) ++ # `set' does not quote correctly, so add quotes: double-quote ++ # substitution turns \\\\ into \\, and sed turns \\ into \. ++ sed -n \ ++ "s/'/'\\\\''/g; ++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ++ ;; #( ++ *) ++ # `set' quotes correctly as required by POSIX, so do not add quotes. ++ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ++ ;; ++ esac | ++ sort ++) | ++ sed ' ++ /^ac_cv_env_/b end ++ t clear ++ :clear ++ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ ++ t end ++ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ ++ :end' >>confcache ++if diff "$cache_file" confcache >/dev/null 2>&1; then :; else ++ if test -w "$cache_file"; then ++ if test "x$cache_file" != "x/dev/null"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 ++$as_echo "$as_me: updating cache $cache_file" >&6;} ++ if test ! -f "$cache_file" || test -h "$cache_file"; then ++ cat confcache >"$cache_file" ++ else ++ case $cache_file in #( ++ */* | ?:*) ++ mv -f confcache "$cache_file"$$ && ++ mv -f "$cache_file"$$ "$cache_file" ;; #( ++ *) ++ mv -f confcache "$cache_file" ;; ++ esac ++ fi ++ fi ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 ++$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} ++ fi ++fi ++rm -f confcache ++ ++test "x$prefix" = xNONE && prefix=$ac_default_prefix ++# Let make expand exec_prefix. ++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' ++ ++DEFS=-DHAVE_CONFIG_H ++ ++ac_libobjs= ++ac_ltlibobjs= ++U= ++for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue ++ # 1. Remove the extension, and $U if already installed. ++ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ++ ac_i=`$as_echo "$ac_i" | sed "$ac_script"` ++ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR ++ # will be set to the directory where LIBOBJS objects are built. ++ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" ++ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' ++done ++LIBOBJS=$ac_libobjs ++ ++LTLIBOBJS=$ac_ltlibobjs ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 ++$as_echo_n "checking that generated files are newer than configure... " >&6; } ++ if test -n "$am_sleep_pid"; then ++ # Hide warnings about reused PIDs. ++ wait $am_sleep_pid 2>/dev/null ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 ++$as_echo "done" >&6; } ++ if test -n "$EXEEXT"; then ++ am__EXEEXT_TRUE= ++ am__EXEEXT_FALSE='#' ++else ++ am__EXEEXT_TRUE='#' ++ am__EXEEXT_FALSE= ++fi ++ ++if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then ++ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then ++ as_fn_error $? "conditional \"AMDEP\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then ++ as_fn_error $? "conditional \"am__fastdepCC\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then ++ as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${ENABLE_BFD_64_BIT_TRUE}" && test -z "${ENABLE_BFD_64_BIT_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_BFD_64_BIT\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${ENABLE_LIBCTF_TRUE}" && test -z "${ENABLE_LIBCTF_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_LIBCTF\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then ++ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++if test -z "${GENINSRC_NEVER_TRUE}" && test -z "${GENINSRC_NEVER_FALSE}"; then ++ as_fn_error $? "conditional \"GENINSRC_NEVER\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi ++ ++: "${CONFIG_STATUS=./config.status}" ++ac_write_fail=0 ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files $CONFIG_STATUS" ++{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 ++$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} ++as_write_fail=0 ++cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 ++#! $SHELL ++# Generated by $as_me. ++# Run this file to recreate the current configuration. ++# Compiler output produced by configure, useful for debugging ++# configure, is in config.log if it exists. ++ ++debug=false ++ac_cs_recheck=false ++ac_cs_silent=false ++ ++SHELL=\${CONFIG_SHELL-$SHELL} ++export SHELL ++_ASEOF ++cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ++## -------------------- ## ++## M4sh Initialization. ## ++## -------------------- ## ++ ++# Be more Bourne compatible ++DUALCASE=1; export DUALCASE # for MKS sh ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : ++ emulate sh ++ NULLCMD=: ++ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++ setopt NO_GLOB_SUBST ++else ++ case `(set -o) 2>/dev/null` in #( ++ *posix*) : ++ set -o posix ;; #( ++ *) : ++ ;; ++esac ++fi ++ ++ ++as_nl=' ++' ++export as_nl ++# Printing a long string crashes Solaris 7 /usr/bin/printf. ++as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo ++# Prefer a ksh shell builtin over an external printf program on Solaris, ++# but without wasting forks for bash or zsh. ++if test -z "$BASH_VERSION$ZSH_VERSION" \ ++ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='print -r --' ++ as_echo_n='print -rn --' ++elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='printf %s\n' ++ as_echo_n='printf %s' ++else ++ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then ++ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' ++ as_echo_n='/usr/ucb/echo -n' ++ else ++ as_echo_body='eval expr "X$1" : "X\\(.*\\)"' ++ as_echo_n_body='eval ++ arg=$1; ++ case $arg in #( ++ *"$as_nl"*) ++ expr "X$arg" : "X\\(.*\\)$as_nl"; ++ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; ++ esac; ++ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ++ ' ++ export as_echo_n_body ++ as_echo_n='sh -c $as_echo_n_body as_echo' ++ fi ++ export as_echo_body ++ as_echo='sh -c $as_echo_body as_echo' ++fi ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ PATH_SEPARATOR=: ++ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { ++ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || ++ PATH_SEPARATOR=';' ++ } ++fi ++ ++ ++# IFS ++# We need space, tab and new line, in precisely that order. Quoting is ++# there to prevent editors from complaining about space-tab. ++# (If _AS_PATH_WALK were called with IFS unset, it would disable word ++# splitting by setting IFS to empty value.) ++IFS=" "" $as_nl" ++ ++# Find who we are. Look in the path if we contain no directory separator. ++as_myself= ++case $0 in #(( ++ *[\\/]* ) as_myself=$0 ;; ++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++# We did not find ourselves, most probably we were run as `sh COMMAND' ++# in which case we are not to be found in the path. ++if test "x$as_myself" = x; then ++ as_myself=$0 ++fi ++if test ! -f "$as_myself"; then ++ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 ++ exit 1 ++fi ++ ++# Unset variables that we do not need and which cause bugs (e.g. in ++# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" ++# suppresses any "Segmentation fault" message there. '((' could ++# trigger a bug in pdksh 5.2.14. ++for as_var in BASH_ENV ENV MAIL MAILPATH ++do eval test x\${$as_var+set} = xset \ ++ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : ++done ++PS1='$ ' ++PS2='> ' ++PS4='+ ' ++ ++# NLS nuisances. ++LC_ALL=C ++export LC_ALL ++LANGUAGE=C ++export LANGUAGE ++ ++# CDPATH. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++ ++# as_fn_error STATUS ERROR [LINENO LOG_FD] ++# ---------------------------------------- ++# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are ++# provided, also output the error to LOG_FD, referencing LINENO. Then exit the ++# script with STATUS, using 1 if that was 0. ++as_fn_error () ++{ ++ as_status=$1; test $as_status -eq 0 && as_status=1 ++ if test "$4"; then ++ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 ++ fi ++ $as_echo "$as_me: error: $2" >&2 ++ as_fn_exit $as_status ++} # as_fn_error ++ ++ ++# as_fn_set_status STATUS ++# ----------------------- ++# Set $? to STATUS, without forking. ++as_fn_set_status () ++{ ++ return $1 ++} # as_fn_set_status ++ ++# as_fn_exit STATUS ++# ----------------- ++# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. ++as_fn_exit () ++{ ++ set +e ++ as_fn_set_status $1 ++ exit $1 ++} # as_fn_exit ++ ++# as_fn_unset VAR ++# --------------- ++# Portably unset VAR. ++as_fn_unset () ++{ ++ { eval $1=; unset $1;} ++} ++as_unset=as_fn_unset ++# as_fn_append VAR VALUE ++# ---------------------- ++# Append the text in VALUE to the end of the definition contained in VAR. Take ++# advantage of any shell optimizations that allow amortized linear growth over ++# repeated appends, instead of the typical quadratic growth present in naive ++# implementations. ++if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : ++ eval 'as_fn_append () ++ { ++ eval $1+=\$2 ++ }' ++else ++ as_fn_append () ++ { ++ eval $1=\$$1\$2 ++ } ++fi # as_fn_append ++ ++# as_fn_arith ARG... ++# ------------------ ++# Perform arithmetic evaluation on the ARGs, and store the result in the ++# global $as_val. Take advantage of shells that can avoid forks. The arguments ++# must be portable across $(()) and expr. ++if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : ++ eval 'as_fn_arith () ++ { ++ as_val=$(( $* )) ++ }' ++else ++ as_fn_arith () ++ { ++ as_val=`expr "$@" || test $? -eq 1` ++ } ++fi # as_fn_arith ++ ++ ++if expr a : '\(a\)' >/dev/null 2>&1 && ++ test "X`expr 00001 : '.*\(...\)'`" = X001; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then ++ as_basename=basename ++else ++ as_basename=false ++fi ++ ++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then ++ as_dirname=dirname ++else ++ as_dirname=false ++fi ++ ++as_me=`$as_basename -- "$0" || ++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ ++ X"$0" : 'X\(//\)$' \| \ ++ X"$0" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X/"$0" | ++ sed '/^.*\/\([^/][^/]*\)\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\/\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\/\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ ++# Avoid depending upon Character Ranges. ++as_cr_letters='abcdefghijklmnopqrstuvwxyz' ++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ++as_cr_Letters=$as_cr_letters$as_cr_LETTERS ++as_cr_digits='0123456789' ++as_cr_alnum=$as_cr_Letters$as_cr_digits ++ ++ECHO_C= ECHO_N= ECHO_T= ++case `echo -n x` in #((((( ++-n*) ++ case `echo 'xy\c'` in ++ *c*) ECHO_T=' ';; # ECHO_T is single tab character. ++ xy) ECHO_C='\c';; ++ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ++ ECHO_T=' ';; ++ esac;; ++*) ++ ECHO_N='-n';; ++esac ++ ++rm -f conf$$ conf$$.exe conf$$.file ++if test -d conf$$.dir; then ++ rm -f conf$$.dir/conf$$.file ++else ++ rm -f conf$$.dir ++ mkdir conf$$.dir 2>/dev/null ++fi ++if (echo >conf$$.file) 2>/dev/null; then ++ if ln -s conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s='ln -s' ++ # ... but there are two gotchas: ++ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. ++ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. ++ # In both cases, we have to default to `cp -pR'. ++ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ++ as_ln_s='cp -pR' ++ elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++ else ++ as_ln_s='cp -pR' ++ fi ++else ++ as_ln_s='cp -pR' ++fi ++rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file ++rmdir conf$$.dir 2>/dev/null ++ ++ ++# as_fn_mkdir_p ++# ------------- ++# Create "$as_dir" as a directory, including parents if necessary. ++as_fn_mkdir_p () ++{ ++ ++ case $as_dir in #( ++ -*) as_dir=./$as_dir;; ++ esac ++ test -d "$as_dir" || eval $as_mkdir_p || { ++ as_dirs= ++ while :; do ++ case $as_dir in #( ++ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( ++ *) as_qdir=$as_dir;; ++ esac ++ as_dirs="'$as_qdir' $as_dirs" ++ as_dir=`$as_dirname -- "$as_dir" || ++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_dir" : 'X\(//\)[^/]' \| \ ++ X"$as_dir" : 'X\(//\)$' \| \ ++ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$as_dir" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ test -d "$as_dir" && break ++ done ++ test -z "$as_dirs" || eval "mkdir $as_dirs" ++ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" ++ ++ ++} # as_fn_mkdir_p ++if mkdir -p . 2>/dev/null; then ++ as_mkdir_p='mkdir -p "$as_dir"' ++else ++ test -d ./-p && rmdir ./-p ++ as_mkdir_p=false ++fi ++ ++ ++# as_fn_executable_p FILE ++# ----------------------- ++# Test if FILE is an executable regular file. ++as_fn_executable_p () ++{ ++ test -f "$1" && test -x "$1" ++} # as_fn_executable_p ++as_test_x='test -x' ++as_executable_p=as_fn_executable_p ++ ++# Sed expression to map a string onto a valid CPP name. ++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" ++ ++# Sed expression to map a string onto a valid variable name. ++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" ++ ++ ++exec 6>&1 ++## ----------------------------------- ## ++## Main body of $CONFIG_STATUS script. ## ++## ----------------------------------- ## ++_ASEOF ++test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++# Save the log message, to keep $0 and so on meaningful, and to ++# report actual input values of CONFIG_FILES etc. instead of their ++# values after options handling. ++ac_log=" ++This file was extended by ld $as_me 2.41, which was ++generated by GNU Autoconf 2.69. Invocation command line was ++ ++ CONFIG_FILES = $CONFIG_FILES ++ CONFIG_HEADERS = $CONFIG_HEADERS ++ CONFIG_LINKS = $CONFIG_LINKS ++ CONFIG_COMMANDS = $CONFIG_COMMANDS ++ $ $0 $@ ++ ++on `(hostname || uname -n) 2>/dev/null | sed 1q` ++" ++ ++_ACEOF ++ ++case $ac_config_files in *" ++"*) set x $ac_config_files; shift; ac_config_files=$*;; ++esac ++ ++case $ac_config_headers in *" ++"*) set x $ac_config_headers; shift; ac_config_headers=$*;; ++esac ++ ++ ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++# Files that config.status was made for. ++config_files="$ac_config_files" ++config_headers="$ac_config_headers" ++config_commands="$ac_config_commands" ++ ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++ac_cs_usage="\ ++\`$as_me' instantiates files and other configuration actions ++from templates according to the current configuration. Unless the files ++and actions are specified as TAGs, all are instantiated by default. ++ ++Usage: $0 [OPTION]... [TAG]... ++ ++ -h, --help print this help, then exit ++ -V, --version print version number and configuration settings, then exit ++ --config print configuration, then exit ++ -q, --quiet, --silent ++ do not print progress messages ++ -d, --debug don't remove temporary files ++ --recheck update $as_me by reconfiguring in the same conditions ++ --file=FILE[:TEMPLATE] ++ instantiate the configuration file FILE ++ --header=FILE[:TEMPLATE] ++ instantiate the configuration header FILE ++ ++Configuration files: ++$config_files ++ ++Configuration headers: ++$config_headers ++ ++Configuration commands: ++$config_commands ++ ++Report bugs to the package provider." ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ++ac_cs_version="\\ ++ld config.status 2.41 ++configured by $0, generated by GNU Autoconf 2.69, ++ with options \\"\$ac_cs_config\\" ++ ++Copyright (C) 2012 Free Software Foundation, Inc. ++This config.status script is free software; the Free Software Foundation ++gives unlimited permission to copy, distribute and modify it." ++ ++ac_pwd='$ac_pwd' ++srcdir='$srcdir' ++INSTALL='$INSTALL' ++MKDIR_P='$MKDIR_P' ++AWK='$AWK' ++test -n "\$AWK" || AWK=awk ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++# The default lists apply if the user does not specify any file. ++ac_need_defaults=: ++while test $# != 0 ++do ++ case $1 in ++ --*=?*) ++ ac_option=`expr "X$1" : 'X\([^=]*\)='` ++ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ++ ac_shift=: ++ ;; ++ --*=) ++ ac_option=`expr "X$1" : 'X\([^=]*\)='` ++ ac_optarg= ++ ac_shift=: ++ ;; ++ *) ++ ac_option=$1 ++ ac_optarg=$2 ++ ac_shift=shift ++ ;; ++ esac ++ ++ case $ac_option in ++ # Handling of the options. ++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ++ ac_cs_recheck=: ;; ++ --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) ++ $as_echo "$ac_cs_version"; exit ;; ++ --config | --confi | --conf | --con | --co | --c ) ++ $as_echo "$ac_cs_config"; exit ;; ++ --debug | --debu | --deb | --de | --d | -d ) ++ debug=: ;; ++ --file | --fil | --fi | --f ) ++ $ac_shift ++ case $ac_optarg in ++ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ '') as_fn_error $? "missing file argument" ;; ++ esac ++ as_fn_append CONFIG_FILES " '$ac_optarg'" ++ ac_need_defaults=false;; ++ --header | --heade | --head | --hea ) ++ $ac_shift ++ case $ac_optarg in ++ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ esac ++ as_fn_append CONFIG_HEADERS " '$ac_optarg'" ++ ac_need_defaults=false;; ++ --he | --h) ++ # Conflict between --help and --header ++ as_fn_error $? "ambiguous option: \`$1' ++Try \`$0 --help' for more information.";; ++ --help | --hel | -h ) ++ $as_echo "$ac_cs_usage"; exit ;; ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil | --si | --s) ++ ac_cs_silent=: ;; ++ ++ # This is an error. ++ -*) as_fn_error $? "unrecognized option: \`$1' ++Try \`$0 --help' for more information." ;; ++ ++ *) as_fn_append ac_config_targets " $1" ++ ac_need_defaults=false ;; ++ ++ esac ++ shift ++done ++ ++ac_configure_extra_args= ++ ++if $ac_cs_silent; then ++ exec 6>/dev/null ++ ac_configure_extra_args="$ac_configure_extra_args --silent" ++fi ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++if \$ac_cs_recheck; then ++ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion ++ shift ++ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 ++ CONFIG_SHELL='$SHELL' ++ export CONFIG_SHELL ++ exec "\$@" ++fi ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++exec 5>>config.log ++{ ++ echo ++ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ++## Running $as_me. ## ++_ASBOX ++ $as_echo "$ac_log" ++} >&5 ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++# ++# INIT-COMMANDS ++# ++AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" ++ ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++sed_quote_subst='$sed_quote_subst' ++double_quote_subst='$double_quote_subst' ++delay_variable_subst='$delay_variable_subst' ++macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' ++macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' ++enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' ++enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' ++pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' ++enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' ++SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ++ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' ++host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' ++host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' ++host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' ++build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' ++build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' ++build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' ++SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' ++Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' ++GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' ++EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' ++FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' ++LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' ++NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' ++LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' ++max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ++ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' ++exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' ++lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' ++lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' ++lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' ++reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' ++reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' ++OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' ++deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' ++file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' ++AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' ++AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' ++STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' ++RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' ++old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' ++old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' ++old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' ++lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' ++CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' ++CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' ++compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' ++GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' ++objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' ++MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' ++lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' ++lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' ++lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' ++need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' ++DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' ++NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' ++LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' ++OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' ++OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' ++libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' ++shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' ++extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' ++archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' ++export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' ++whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' ++compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' ++old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' ++archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' ++archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' ++module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' ++module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' ++with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' ++allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' ++no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' ++hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' ++hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' ++hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' ++hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' ++hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' ++hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' ++inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' ++link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' ++fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' ++always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' ++export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' ++exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' ++include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' ++prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' ++file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' ++variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' ++need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' ++need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' ++version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' ++runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' ++shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' ++shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' ++libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' ++library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' ++soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' ++install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' ++postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' ++postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' ++finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' ++finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' ++hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' ++sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' ++sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' ++hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' ++enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' ++enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' ++enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' ++old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' ++striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' ++compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' ++predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' ++postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' ++predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' ++postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' ++compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' ++LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' ++reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' ++reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' ++GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' ++lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' ++lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' ++lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' ++lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' ++lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' ++archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' ++enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' ++export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' ++whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' ++compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' ++old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' ++allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' ++no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' ++inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' ++link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' ++fix_srcfile_path_CXX='`$ECHO "$fix_srcfile_path_CXX" | $SED "$delay_single_quote_subst"`' ++always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' ++export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' ++include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' ++prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' ++file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' ++hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' ++compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' ++predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' ++postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' ++predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' ++postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' ++compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' ++ ++LTCC='$LTCC' ++LTCFLAGS='$LTCFLAGS' ++compiler='$compiler_DEFAULT' ++ ++# A function that is used when there is no print builtin or printf. ++func_fallback_echo () ++{ ++ eval 'cat <<_LTECHO_EOF ++\$1 ++_LTECHO_EOF' ++} ++ ++# Quote evaled strings. ++for var in SHELL \ ++ECHO \ ++SED \ ++GREP \ ++EGREP \ ++FGREP \ ++LD \ ++NM \ ++LN_S \ ++lt_SP2NL \ ++lt_NL2SP \ ++reload_flag \ ++OBJDUMP \ ++deplibs_check_method \ ++file_magic_cmd \ ++AR \ ++AR_FLAGS \ ++STRIP \ ++RANLIB \ ++CC \ ++CFLAGS \ ++compiler \ ++lt_cv_sys_global_symbol_pipe \ ++lt_cv_sys_global_symbol_to_cdecl \ ++lt_cv_sys_global_symbol_to_c_name_address \ ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ ++lt_prog_compiler_no_builtin_flag \ ++lt_prog_compiler_wl \ ++lt_prog_compiler_pic \ ++lt_prog_compiler_static \ ++lt_cv_prog_compiler_c_o \ ++need_locks \ ++DSYMUTIL \ ++NMEDIT \ ++LIPO \ ++OTOOL \ ++OTOOL64 \ ++shrext_cmds \ ++export_dynamic_flag_spec \ ++whole_archive_flag_spec \ ++compiler_needs_object \ ++with_gnu_ld \ ++allow_undefined_flag \ ++no_undefined_flag \ ++hardcode_libdir_flag_spec \ ++hardcode_libdir_flag_spec_ld \ ++hardcode_libdir_separator \ ++fix_srcfile_path \ ++exclude_expsyms \ ++include_expsyms \ ++file_list_spec \ ++variables_saved_for_relink \ ++libname_spec \ ++library_names_spec \ ++soname_spec \ ++install_override_mode \ ++finish_eval \ ++old_striplib \ ++striplib \ ++compiler_lib_search_dirs \ ++predep_objects \ ++postdep_objects \ ++predeps \ ++postdeps \ ++compiler_lib_search_path \ ++LD_CXX \ ++reload_flag_CXX \ ++compiler_CXX \ ++lt_prog_compiler_no_builtin_flag_CXX \ ++lt_prog_compiler_wl_CXX \ ++lt_prog_compiler_pic_CXX \ ++lt_prog_compiler_static_CXX \ ++lt_cv_prog_compiler_c_o_CXX \ ++export_dynamic_flag_spec_CXX \ ++whole_archive_flag_spec_CXX \ ++compiler_needs_object_CXX \ ++with_gnu_ld_CXX \ ++allow_undefined_flag_CXX \ ++no_undefined_flag_CXX \ ++hardcode_libdir_flag_spec_CXX \ ++hardcode_libdir_flag_spec_ld_CXX \ ++hardcode_libdir_separator_CXX \ ++fix_srcfile_path_CXX \ ++exclude_expsyms_CXX \ ++include_expsyms_CXX \ ++file_list_spec_CXX \ ++compiler_lib_search_dirs_CXX \ ++predep_objects_CXX \ ++postdep_objects_CXX \ ++predeps_CXX \ ++postdeps_CXX \ ++compiler_lib_search_path_CXX; do ++ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ *[\\\\\\\`\\"\\\$]*) ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ++ ;; ++ *) ++ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ++ ;; ++ esac ++done ++ ++# Double-quote double-evaled strings. ++for var in reload_cmds \ ++old_postinstall_cmds \ ++old_postuninstall_cmds \ ++old_archive_cmds \ ++extract_expsyms_cmds \ ++old_archive_from_new_cmds \ ++old_archive_from_expsyms_cmds \ ++archive_cmds \ ++archive_expsym_cmds \ ++module_cmds \ ++module_expsym_cmds \ ++export_symbols_cmds \ ++prelink_cmds \ ++postinstall_cmds \ ++postuninstall_cmds \ ++finish_cmds \ ++sys_lib_search_path_spec \ ++sys_lib_dlsearch_path_spec \ ++reload_cmds_CXX \ ++old_archive_cmds_CXX \ ++old_archive_from_new_cmds_CXX \ ++old_archive_from_expsyms_cmds_CXX \ ++archive_cmds_CXX \ ++archive_expsym_cmds_CXX \ ++module_cmds_CXX \ ++module_expsym_cmds_CXX \ ++export_symbols_cmds_CXX \ ++prelink_cmds_CXX; do ++ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ *[\\\\\\\`\\"\\\$]*) ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ++ ;; ++ *) ++ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ++ ;; ++ esac ++done ++ ++ac_aux_dir='$ac_aux_dir' ++xsi_shell='$xsi_shell' ++lt_shell_append='$lt_shell_append' ++ ++# See if we are running on zsh, and set the options which allow our ++# commands through without removal of \ escapes INIT. ++if test -n "\${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++fi ++ ++ ++ PACKAGE='$PACKAGE' ++ VERSION='$VERSION' ++ TIMESTAMP='$TIMESTAMP' ++ RM='$RM' ++ ofile='$ofile' ++ ++ ++ ++ ++ ++# Capture the value of obsolete ALL_LINGUAS because we need it to compute ++ # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it ++ # from automake. ++ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' ++ # Capture the value of LINGUAS because we need it to compute CATALOGS. ++ LINGUAS="${LINGUAS-%UNSET%}" ++ ++ ++ ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++ ++# Handling of arguments. ++for ac_config_target in $ac_config_targets ++do ++ case $ac_config_target in ++ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; ++ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; ++ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;; ++ "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; ++ "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; ++ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; ++ "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in:po/Make-in" ;; ++ ++ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; ++ esac ++done ++ ++ ++# If the user did not use the arguments to specify the items to instantiate, ++# then the envvar interface is used. Set only those that are not. ++# We use the long form for the default assignment because of an extremely ++# bizarre bug on SunOS 4.1.3. ++if $ac_need_defaults; then ++ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files ++ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers ++ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands ++fi ++ ++# Have a temporary directory for convenience. Make it in the build tree ++# simply because there is no reason against having it here, and in addition, ++# creating and moving files from /tmp can sometimes cause problems. ++# Hook for its removal unless debugging. ++# Note that there is a small window in which the directory will not be cleaned: ++# after its creation but before its name has been assigned to `$tmp'. ++$debug || ++{ ++ tmp= ac_tmp= ++ trap 'exit_status=$? ++ : "${ac_tmp:=$tmp}" ++ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ++' 0 ++ trap 'as_fn_exit 1' 1 2 13 15 ++} ++# Create a (secure) tmp directory for tmp files. ++ ++{ ++ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && ++ test -d "$tmp" ++} || ++{ ++ tmp=./conf$$-$RANDOM ++ (umask 077 && mkdir "$tmp") ++} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ++ac_tmp=$tmp ++ ++# Set up the scripts for CONFIG_FILES section. ++# No need to generate them if there are no CONFIG_FILES. ++# This happens for instance with `./config.status config.h'. ++if test -n "$CONFIG_FILES"; then ++ ++ ++ac_cr=`echo X | tr X '\015'` ++# On cygwin, bash can eat \r inside `` if the user requested igncr. ++# But we know of no other shell where ac_cr would be empty at this ++# point, so we can use a bashism as a fallback. ++if test "x$ac_cr" = x; then ++ eval ac_cr=\$\'\\r\' ++fi ++ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` ++if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ++ ac_cs_awk_cr='\\r' ++else ++ ac_cs_awk_cr=$ac_cr ++fi ++ ++echo 'BEGIN {' >"$ac_tmp/subs1.awk" && ++_ACEOF ++ ++ ++{ ++ echo "cat >conf$$subs.awk <<_ACEOF" && ++ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && ++ echo "_ACEOF" ++} >conf$$subs.sh || ++ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ++ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ++ac_delim='%!_!# ' ++for ac_last_try in false false false false false :; do ++ . ./conf$$subs.sh || ++ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ++ ++ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` ++ if test $ac_delim_n = $ac_delim_num; then ++ break ++ elif $ac_last_try; then ++ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ++ else ++ ac_delim="$ac_delim!$ac_delim _$ac_delim!! " ++ fi ++done ++rm -f conf$$subs.sh ++ ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && ++_ACEOF ++sed -n ' ++h ++s/^/S["/; s/!.*/"]=/ ++p ++g ++s/^[^!]*!// ++:repl ++t repl ++s/'"$ac_delim"'$// ++t delim ++:nl ++h ++s/\(.\{148\}\)..*/\1/ ++t more1 ++s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ ++p ++n ++b repl ++:more1 ++s/["\\]/\\&/g; s/^/"/; s/$/"\\/ ++p ++g ++s/.\{148\}// ++t nl ++:delim ++h ++s/\(.\{148\}\)..*/\1/ ++t more2 ++s/["\\]/\\&/g; s/^/"/; s/$/"/ ++p ++b ++:more2 ++s/["\\]/\\&/g; s/^/"/; s/$/"\\/ ++p ++g ++s/.\{148\}// ++t delim ++' >$CONFIG_STATUS || ac_write_fail=1 ++rm -f conf$$subs.awk ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++_ACAWK ++cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && ++ for (key in S) S_is_set[key] = 1 ++ FS = "" ++ ++} ++{ ++ line = $ 0 ++ nfields = split(line, field, "@") ++ substed = 0 ++ len = length(field[1]) ++ for (i = 2; i < nfields; i++) { ++ key = field[i] ++ keylen = length(key) ++ if (S_is_set[key]) { ++ value = S[key] ++ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) ++ len += length(value) + length(field[++i]) ++ substed = 1 ++ } else ++ len += 1 + keylen ++ } ++ ++ print line ++} ++ ++_ACAWK ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then ++ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" ++else ++ cat ++fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ ++ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 ++_ACEOF ++ ++# VPATH may cause trouble with some makes, so we remove sole $(srcdir), ++# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and ++# trailing colons and then remove the whole line if VPATH becomes empty ++# (actually we leave an empty line to preserve line numbers). ++if test "x$srcdir" = x.; then ++ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ ++h ++s/// ++s/^/:/ ++s/[ ]*$/:/ ++s/:\$(srcdir):/:/g ++s/:\${srcdir}:/:/g ++s/:@srcdir@:/:/g ++s/^:*// ++s/:*$// ++x ++s/\(=[ ]*\).*/\1/ ++G ++s/\n// ++s/^[^=]*=[ ]*$// ++}' ++fi ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++fi # test -n "$CONFIG_FILES" ++ ++# Set up the scripts for CONFIG_HEADERS section. ++# No need to generate them if there are no CONFIG_HEADERS. ++# This happens for instance with `./config.status Makefile'. ++if test -n "$CONFIG_HEADERS"; then ++cat >"$ac_tmp/defines.awk" <<\_ACAWK || ++BEGIN { ++_ACEOF ++ ++# Transform confdefs.h into an awk script `defines.awk', embedded as ++# here-document in config.status, that substitutes the proper values into ++# config.h.in to produce config.h. ++ ++# Create a delimiter string that does not exist in confdefs.h, to ease ++# handling of long lines. ++ac_delim='%!_!# ' ++for ac_last_try in false false :; do ++ ac_tt=`sed -n "/$ac_delim/p" confdefs.h` ++ if test -z "$ac_tt"; then ++ break ++ elif $ac_last_try; then ++ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 ++ else ++ ac_delim="$ac_delim!$ac_delim _$ac_delim!! " ++ fi ++done ++ ++# For the awk script, D is an array of macro values keyed by name, ++# likewise P contains macro parameters if any. Preserve backslash ++# newline sequences. ++ ++ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* ++sed -n ' ++s/.\{148\}/&'"$ac_delim"'/g ++t rset ++:rset ++s/^[ ]*#[ ]*define[ ][ ]*/ / ++t def ++d ++:def ++s/\\$// ++t bsnl ++s/["\\]/\\&/g ++s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ ++D["\1"]=" \3"/p ++s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p ++d ++:bsnl ++s/["\\]/\\&/g ++s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ ++D["\1"]=" \3\\\\\\n"\\/p ++t cont ++s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p ++t cont ++d ++:cont ++n ++s/.\{148\}/&'"$ac_delim"'/g ++t clear ++:clear ++s/\\$// ++t bsnlc ++s/["\\]/\\&/g; s/^/"/; s/$/"/p ++d ++:bsnlc ++s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p ++b cont ++' >$CONFIG_STATUS || ac_write_fail=1 ++ ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ for (key in D) D_is_set[key] = 1 ++ FS = "" ++} ++/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { ++ line = \$ 0 ++ split(line, arg, " ") ++ if (arg[1] == "#") { ++ defundef = arg[2] ++ mac1 = arg[3] ++ } else { ++ defundef = substr(arg[1], 2) ++ mac1 = arg[2] ++ } ++ split(mac1, mac2, "(") #) ++ macro = mac2[1] ++ prefix = substr(line, 1, index(line, defundef) - 1) ++ if (D_is_set[macro]) { ++ # Preserve the white space surrounding the "#". ++ print prefix "define", macro P[macro] D[macro] ++ next ++ } else { ++ # Replace #undef with comments. This is necessary, for example, ++ # in the case of _POSIX_SOURCE, which is predefined and required ++ # on some systems where configure will not decide to define it. ++ if (defundef == "undef") { ++ print "/*", prefix defundef, macro, "*/" ++ next ++ } ++ } ++} ++{ print } ++_ACAWK ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 ++fi # test -n "$CONFIG_HEADERS" ++ ++ ++eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" ++shift ++for ac_tag ++do ++ case $ac_tag in ++ :[FHLC]) ac_mode=$ac_tag; continue;; ++ esac ++ case $ac_mode$ac_tag in ++ :[FHL]*:*);; ++ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; ++ :[FH]-) ac_tag=-:-;; ++ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; ++ esac ++ ac_save_IFS=$IFS ++ IFS=: ++ set x $ac_tag ++ IFS=$ac_save_IFS ++ shift ++ ac_file=$1 ++ shift ++ ++ case $ac_mode in ++ :L) ac_source=$1;; ++ :[FH]) ++ ac_file_inputs= ++ for ac_f ++ do ++ case $ac_f in ++ -) ac_f="$ac_tmp/stdin";; ++ *) # Look for the file first in the build tree, then in the source tree ++ # (if the path is not absolute). The absolute path cannot be DOS-style, ++ # because $ac_f cannot contain `:'. ++ test -f "$ac_f" || ++ case $ac_f in ++ [\\/$]*) false;; ++ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; ++ esac || ++ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; ++ esac ++ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ++ as_fn_append ac_file_inputs " '$ac_f'" ++ done ++ ++ # Let's still pretend it is `configure' which instantiates (i.e., don't ++ # use $as_me), people would be surprised to read: ++ # /* config.h. Generated by config.status. */ ++ configure_input='Generated from '` ++ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' ++ `' by configure.' ++ if test x"$ac_file" != x-; then ++ configure_input="$ac_file. $configure_input" ++ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 ++$as_echo "$as_me: creating $ac_file" >&6;} ++ fi ++ # Neutralize special characters interpreted by sed in replacement strings. ++ case $configure_input in #( ++ *\&* | *\|* | *\\* ) ++ ac_sed_conf_input=`$as_echo "$configure_input" | ++ sed 's/[\\\\&|]/\\\\&/g'`;; #( ++ *) ac_sed_conf_input=$configure_input;; ++ esac ++ ++ case $ac_tag in ++ *:-:* | *:-) cat >"$ac_tmp/stdin" \ ++ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; ++ esac ++ ;; ++ esac ++ ++ ac_dir=`$as_dirname -- "$ac_file" || ++$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$ac_file" : 'X\(//\)[^/]' \| \ ++ X"$ac_file" : 'X\(//\)$' \| \ ++ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$ac_file" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ as_dir="$ac_dir"; as_fn_mkdir_p ++ ac_builddir=. ++ ++case "$ac_dir" in ++.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; ++*) ++ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` ++ # A ".." for each directory in $ac_dir_suffix. ++ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` ++ case $ac_top_builddir_sub in ++ "") ac_top_builddir_sub=. ac_top_build_prefix= ;; ++ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; ++ esac ;; ++esac ++ac_abs_top_builddir=$ac_pwd ++ac_abs_builddir=$ac_pwd$ac_dir_suffix ++# for backward compatibility: ++ac_top_builddir=$ac_top_build_prefix ++ ++case $srcdir in ++ .) # We are building in place. ++ ac_srcdir=. ++ ac_top_srcdir=$ac_top_builddir_sub ++ ac_abs_top_srcdir=$ac_pwd ;; ++ [\\/]* | ?:[\\/]* ) # Absolute name. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ++ ac_abs_top_srcdir=$srcdir ;; ++ *) # Relative name. ++ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_build_prefix$srcdir ++ ac_abs_top_srcdir=$ac_pwd/$srcdir ;; ++esac ++ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix ++ ++ ++ case $ac_mode in ++ :F) ++ # ++ # CONFIG_FILE ++ # ++ ++ case $INSTALL in ++ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; ++ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; ++ esac ++ ac_MKDIR_P=$MKDIR_P ++ case $MKDIR_P in ++ [\\/$]* | ?:[\\/]* ) ;; ++ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; ++ esac ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++# If the template does not know about datarootdir, expand it. ++# FIXME: This hack should be removed a few years after 2.60. ++ac_datarootdir_hack=; ac_datarootdir_seen= ++ac_sed_dataroot=' ++/datarootdir/ { ++ p ++ q ++} ++/@datadir@/p ++/@docdir@/p ++/@infodir@/p ++/@localedir@/p ++/@mandir@/p' ++case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in ++*datarootdir*) ac_datarootdir_seen=yes;; ++*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 ++$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ ac_datarootdir_hack=' ++ s&@datadir@&$datadir&g ++ s&@docdir@&$docdir&g ++ s&@infodir@&$infodir&g ++ s&@localedir@&$localedir&g ++ s&@mandir@&$mandir&g ++ s&\\\${datarootdir}&$datarootdir&g' ;; ++esac ++_ACEOF ++ ++# Neutralize VPATH when `$srcdir' = `.'. ++# Shell code in configure.ac might set extrasub. ++# FIXME: do we really want to maintain this feature? ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ac_sed_extra="$ac_vpsub ++$extrasub ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++:t ++/@[a-zA-Z_][a-zA-Z_0-9]*@/!b ++s|@configure_input@|$ac_sed_conf_input|;t t ++s&@top_builddir@&$ac_top_builddir_sub&;t t ++s&@top_build_prefix@&$ac_top_build_prefix&;t t ++s&@srcdir@&$ac_srcdir&;t t ++s&@abs_srcdir@&$ac_abs_srcdir&;t t ++s&@top_srcdir@&$ac_top_srcdir&;t t ++s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t ++s&@builddir@&$ac_builddir&;t t ++s&@abs_builddir@&$ac_abs_builddir&;t t ++s&@abs_top_builddir@&$ac_abs_top_builddir&;t t ++s&@INSTALL@&$ac_INSTALL&;t t ++s&@MKDIR_P@&$ac_MKDIR_P&;t t ++$ac_datarootdir_hack ++" ++eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ ++ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ++ ++test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && ++ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && ++ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ ++ "$ac_tmp/out"`; test -z "$ac_out"; } && ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' ++which seems to be undefined. Please make sure it is defined" >&5 ++$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' ++which seems to be undefined. Please make sure it is defined" >&2;} ++ ++ rm -f "$ac_tmp/stdin" ++ case $ac_file in ++ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; ++ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; ++ esac \ ++ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ++ ;; ++ :H) ++ # ++ # CONFIG_HEADER ++ # ++ if test x"$ac_file" != x-; then ++ { ++ $as_echo "/* $configure_input */" \ ++ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" ++ } >"$ac_tmp/config.h" \ ++ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ++ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 ++$as_echo "$as_me: $ac_file is unchanged" >&6;} ++ else ++ rm -f "$ac_file" ++ mv "$ac_tmp/config.h" "$ac_file" \ ++ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ++ fi ++ else ++ $as_echo "/* $configure_input */" \ ++ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ ++ || as_fn_error $? "could not create -" "$LINENO" 5 ++ fi ++# Compute "$ac_file"'s index in $config_headers. ++_am_arg="$ac_file" ++_am_stamp_count=1 ++for _am_header in $config_headers :; do ++ case $_am_header in ++ $_am_arg | $_am_arg:* ) ++ break ;; ++ * ) ++ _am_stamp_count=`expr $_am_stamp_count + 1` ;; ++ esac ++done ++echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || ++$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$_am_arg" : 'X\(//\)[^/]' \| \ ++ X"$_am_arg" : 'X\(//\)$' \| \ ++ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$_am_arg" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'`/stamp-h$_am_stamp_count ++ ;; ++ ++ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 ++$as_echo "$as_me: executing $ac_file commands" >&6;} ++ ;; ++ esac ++ ++ ++ case $ac_file$ac_mode in ++ "depfiles":C) test x"$AMDEP_TRUE" != x"" || { ++ # Older Autoconf quotes --file arguments for eval, but not when files ++ # are listed without --file. Let's play safe and only enable the eval ++ # if we detect the quoting. ++ case $CONFIG_FILES in ++ *\'*) eval set x "$CONFIG_FILES" ;; ++ *) set x $CONFIG_FILES ;; ++ esac ++ shift ++ for mf ++ do ++ # Strip MF so we end up with the name of the file. ++ mf=`echo "$mf" | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile or not. ++ # We used to match only the files named 'Makefile.in', but ++ # some people rename them; so instead we look at the file content. ++ # Grep'ing the first line is not enough: some people post-process ++ # each Makefile.in and add a new line on top of each file to say so. ++ # Grep'ing the whole file is not good either: AIX grep has a line ++ # limit of 2048, but all sed's we know have understand at least 4000. ++ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then ++ dirpart=`$as_dirname -- "$mf" || ++$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$mf" : 'X\(//\)[^/]' \| \ ++ X"$mf" : 'X\(//\)$' \| \ ++ X"$mf" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$mf" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ else ++ continue ++ fi ++ # Extract the definition of DEPDIR, am__include, and am__quote ++ # from the Makefile without running 'make'. ++ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` ++ test -z "$DEPDIR" && continue ++ am__include=`sed -n 's/^am__include = //p' < "$mf"` ++ test -z "$am__include" && continue ++ am__quote=`sed -n 's/^am__quote = //p' < "$mf"` ++ # Find all dependency output files, they are included files with ++ # $(DEPDIR) in their names. We invoke sed twice because it is the ++ # simplest approach to changing $(DEPDIR) to its actual value in the ++ # expansion. ++ for file in `sed -n " ++ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ ++ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do ++ # Make sure the directory exists. ++ test -f "$dirpart/$file" && continue ++ fdir=`$as_dirname -- "$file" || ++$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$file" : 'X\(//\)[^/]' \| \ ++ X"$file" : 'X\(//\)$' \| \ ++ X"$file" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$file" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q'` ++ as_dir=$dirpart/$fdir; as_fn_mkdir_p ++ # echo "creating $dirpart/$file" ++ echo '# dummy' > "$dirpart/$file" ++ done ++ done ++} ++ ;; ++ "libtool":C) ++ ++ # See if we are running on zsh, and set the options which allow our ++ # commands through without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ ++ cfgfile="${ofile}T" ++ trap "$RM \"$cfgfile\"; exit 1" 1 2 15 ++ $RM "$cfgfile" ++ ++ cat <<_LT_EOF >> "$cfgfile" ++#! $SHELL ++ ++# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. ++# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++# NOTE: Changes made to this file will be lost: look at ltmain.sh. ++# ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, ++# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ++# Written by Gordon Matzigkeit, 1996 ++# ++# This file is part of GNU Libtool. ++# ++# GNU Libtool is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License as ++# published by the Free Software Foundation; either version 2 of ++# the License, or (at your option) any later version. ++# ++# As a special exception to the GNU General Public License, ++# if you distribute this file as part of a program or library that ++# is built using GNU Libtool, you may include this file under the ++# same distribution terms that you use for the rest of that program. ++# ++# GNU Libtool is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GNU Libtool; see the file COPYING. If not, a copy ++# can be downloaded from http://www.gnu.org/licenses/gpl.html, or ++# obtained by writing to the Free Software Foundation, Inc., ++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ ++# The names of the tagged configurations supported by this script. ++available_tags="CXX " ++ ++# ### BEGIN LIBTOOL CONFIG ++ ++# Which release of libtool.m4 was used? ++macro_version=$macro_version ++macro_revision=$macro_revision ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# What type of objects to build. ++pic_mode=$pic_mode ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# An echo program that protects backslashes. ++ECHO=$lt_ECHO ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# A sed program that does not truncate output. ++SED=$lt_SED ++ ++# Sed that helps us avoid accidentally triggering echo(1) options like -n. ++Xsed="\$SED -e 1s/^X//" ++ ++# A grep program that handles long lines. ++GREP=$lt_GREP ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# A literal string matcher. ++FGREP=$lt_FGREP ++ ++# A BSD- or MS-compatible name lister. ++NM=$lt_NM ++ ++# Whether we need soft or hard links. ++LN_S=$lt_LN_S ++ ++# What is the maximum length of a command? ++max_cmd_len=$max_cmd_len ++ ++# Object file suffix (normally "o"). ++objext=$ac_objext ++ ++# Executable file suffix (normally ""). ++exeext=$exeext ++ ++# whether the shell understands "unset". ++lt_unset=$lt_unset ++ ++# turn spaces into newlines. ++SP2NL=$lt_lt_SP2NL ++ ++# turn newlines into spaces. ++NL2SP=$lt_lt_NL2SP ++ ++# An object symbol dumper. ++OBJDUMP=$lt_OBJDUMP ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == "file_magic". ++file_magic_cmd=$lt_file_magic_cmd ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A symbol stripping program. ++STRIP=$lt_STRIP ++ ++# Commands used to install an old-style archive. ++RANLIB=$lt_RANLIB ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Whether to use a lock for old archive extraction. ++lock_old_archive_extraction=$lock_old_archive_extraction ++ ++# A C compiler. ++LTCC=$lt_CC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_CFLAGS ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration. ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair. ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# Transform the output of nm in a C name address pair when lib prefix is needed. ++global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# Used to examine libraries when file_magic_cmd begins with "file". ++MAGIC_CMD=$MAGIC_CMD ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Tool to manipulate archived DWARF debug symbol files on Mac OS X. ++DSYMUTIL=$lt_DSYMUTIL ++ ++# Tool to change global to local symbols on Mac OS X. ++NMEDIT=$lt_NMEDIT ++ ++# Tool to manipulate fat objects and archives on Mac OS X. ++LIPO=$lt_LIPO ++ ++# ldd/readelf like tool for Mach-O binaries on Mac OS X. ++OTOOL=$lt_OTOOL ++ ++# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. ++OTOOL64=$lt_OTOOL64 ++ ++# Old archive suffix (normally "a"). ++libext=$libext ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds=$lt_shrext_cmds ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at link time. ++variables_saved_for_relink=$lt_variables_saved_for_relink ++ ++# Do we need the "lib" prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# Shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Permission mode override for installation of shared libraries. ++install_override_mode=$lt_install_override_mode ++ ++# Command to use after installation of a shared archive. ++postinstall_cmds=$lt_postinstall_cmds ++ ++# Command to use after uninstallation of a shared archive. ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# As "finish_cmds", except a single script fragment to be evaled but ++# not shown. ++finish_eval=$lt_finish_eval ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Compile-time system search path for libraries. ++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec ++ ++# Run-time system search path for libraries. ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++ ++# The linker used to build libraries. ++LD=$lt_LD ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# Commands used to build an old-style archive. ++old_archive_cmds=$lt_old_archive_cmds ++ ++# A language specific compiler. ++CC=$lt_compiler ++ ++# Is the compiler the GNU compiler? ++with_gcc=$GCC ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc ++ ++# Whether or not to disallow shared libs when runtime libs are static. ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec ++ ++# Whether the compiler copes with passing no objects directly. ++compiler_needs_object=$lt_compiler_needs_object ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds ++ ++# Commands used to build a shared archive. ++archive_cmds=$lt_archive_cmds ++archive_expsym_cmds=$lt_archive_expsym_cmds ++ ++# Commands used to build a loadable module if different from building ++# a shared archive. ++module_cmds=$lt_module_cmds ++module_expsym_cmds=$lt_module_expsym_cmds ++ ++# Whether we are building with GNU ld or not. ++with_gnu_ld=$lt_with_gnu_ld ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag ++ ++# Flag that enforces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec ++ ++# If ld is used when linking, flag to hardcode \$libdir into a binary ++# during linking. This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld ++ ++# Whether we need a single "-rpath" flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator ++ ++# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes ++# DIR into the resulting binary. ++hardcode_direct=$hardcode_direct ++ ++# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes ++# DIR into the resulting binary and the resulting library dependency is ++# "absolute",i.e impossible to change by setting \${shlibpath_var} if the ++# library is relocated. ++hardcode_direct_absolute=$hardcode_direct_absolute ++ ++# Set to "yes" if using the -LDIR flag during linking hardcodes DIR ++# into the resulting binary. ++hardcode_minus_L=$hardcode_minus_L ++ ++# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR ++# into the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var ++ ++# Set to "yes" if building a shared library automatically hardcodes DIR ++# into the library and all subsequent libraries and executables linked ++# against it. ++hardcode_automatic=$hardcode_automatic ++ ++# Set to yes if linker adds runtime paths of dependent libraries ++# to runtime path list. ++inherit_rpath=$inherit_rpath ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path=$lt_fix_srcfile_path ++ ++# Set to "yes" if exported symbols are required. ++always_export_symbols=$always_export_symbols ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms ++ ++# Commands necessary for linking programs (against libraries) with templates. ++prelink_cmds=$lt_prelink_cmds ++ ++# Specify filename containing input files. ++file_list_spec=$lt_file_list_spec ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action ++ ++# The directories searched by this compiler when creating a shared library. ++compiler_lib_search_dirs=$lt_compiler_lib_search_dirs ++ ++# Dependencies to place before and after the objects being linked to ++# create a shared library. ++predep_objects=$lt_predep_objects ++postdep_objects=$lt_postdep_objects ++predeps=$lt_predeps ++postdeps=$lt_postdeps ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=$lt_compiler_lib_search_path ++ ++# ### END LIBTOOL CONFIG ++ ++_LT_EOF ++ ++ case $host_os in ++ aix3*) ++ cat <<\_LT_EOF >> "$cfgfile" ++# AIX sometimes has problems with the GCC collect2 program. For some ++# reason, if we set the COLLECT_NAMES environment variable, the problems ++# vanish in a puff of smoke. ++if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++fi ++_LT_EOF ++ ;; ++ esac ++ ++ ++ltmain="$ac_aux_dir/ltmain.sh" ++ ++ ++ # We use sed instead of cat because bash on DJGPP gets confused if ++ # if finds mixed CR/LF and LF-only lines. Since sed operates in ++ # text mode, it properly converts lines to CR/LF. This bash problem ++ # is reportedly fixed, but why not run on old versions too? ++ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ ++ || (rm -f "$cfgfile"; exit 1) ++ ++ case $xsi_shell in ++ yes) ++ cat << \_LT_EOF >> "$cfgfile" ++ ++# func_dirname file append nondir_replacement ++# Compute the dirname of FILE. If nonempty, add APPEND to the result, ++# otherwise set result to NONDIR_REPLACEMENT. ++func_dirname () ++{ ++ case ${1} in ++ */*) func_dirname_result="${1%/*}${2}" ;; ++ * ) func_dirname_result="${3}" ;; ++ esac ++} ++ ++# func_basename file ++func_basename () ++{ ++ func_basename_result="${1##*/}" ++} ++ ++# func_dirname_and_basename file append nondir_replacement ++# perform func_basename and func_dirname in a single function ++# call: ++# dirname: Compute the dirname of FILE. If nonempty, ++# add APPEND to the result, otherwise set result ++# to NONDIR_REPLACEMENT. ++# value returned in "$func_dirname_result" ++# basename: Compute filename of FILE. ++# value retuned in "$func_basename_result" ++# Implementation must be kept synchronized with func_dirname ++# and func_basename. For efficiency, we do not delegate to ++# those functions but instead duplicate the functionality here. ++func_dirname_and_basename () ++{ ++ case ${1} in ++ */*) func_dirname_result="${1%/*}${2}" ;; ++ * ) func_dirname_result="${3}" ;; ++ esac ++ func_basename_result="${1##*/}" ++} ++ ++# func_stripname prefix suffix name ++# strip PREFIX and SUFFIX off of NAME. ++# PREFIX and SUFFIX must not contain globbing or regex special ++# characters, hashes, percent signs, but SUFFIX may contain a leading ++# dot (in which case that matches only a dot). ++func_stripname () ++{ ++ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are ++ # positional parameters, so assign one to ordinary parameter first. ++ func_stripname_result=${3} ++ func_stripname_result=${func_stripname_result#"${1}"} ++ func_stripname_result=${func_stripname_result%"${2}"} ++} ++ ++# func_opt_split ++func_opt_split () ++{ ++ func_opt_split_opt=${1%%=*} ++ func_opt_split_arg=${1#*=} ++} ++ ++# func_lo2o object ++func_lo2o () ++{ ++ case ${1} in ++ *.lo) func_lo2o_result=${1%.lo}.${objext} ;; ++ *) func_lo2o_result=${1} ;; ++ esac ++} ++ ++# func_xform libobj-or-source ++func_xform () ++{ ++ func_xform_result=${1%.*}.lo ++} ++ ++# func_arith arithmetic-term... ++func_arith () ++{ ++ func_arith_result=$(( $* )) ++} ++ ++# func_len string ++# STRING may not start with a hyphen. ++func_len () ++{ ++ func_len_result=${#1} ++} ++ ++_LT_EOF ++ ;; ++ *) # Bourne compatible functions. ++ cat << \_LT_EOF >> "$cfgfile" ++ ++# func_dirname file append nondir_replacement ++# Compute the dirname of FILE. If nonempty, add APPEND to the result, ++# otherwise set result to NONDIR_REPLACEMENT. ++func_dirname () ++{ ++ # Extract subdirectory from the argument. ++ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` ++ if test "X$func_dirname_result" = "X${1}"; then ++ func_dirname_result="${3}" ++ else ++ func_dirname_result="$func_dirname_result${2}" ++ fi ++} ++ ++# func_basename file ++func_basename () ++{ ++ func_basename_result=`$ECHO "${1}" | $SED "$basename"` ++} ++ ++ ++# func_stripname prefix suffix name ++# strip PREFIX and SUFFIX off of NAME. ++# PREFIX and SUFFIX must not contain globbing or regex special ++# characters, hashes, percent signs, but SUFFIX may contain a leading ++# dot (in which case that matches only a dot). ++# func_strip_suffix prefix name ++func_stripname () ++{ ++ case ${2} in ++ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; ++ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; ++ esac ++} ++ ++# sed scripts: ++my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' ++my_sed_long_arg='1s/^-[^=]*=//' ++ ++# func_opt_split ++func_opt_split () ++{ ++ func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` ++ func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` ++} ++ ++# func_lo2o object ++func_lo2o () ++{ ++ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` ++} ++ ++# func_xform libobj-or-source ++func_xform () ++{ ++ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` ++} ++ ++# func_arith arithmetic-term... ++func_arith () ++{ ++ func_arith_result=`expr "$@"` ++} ++ ++# func_len string ++# STRING may not start with a hyphen. ++func_len () ++{ ++ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` ++} ++ ++_LT_EOF ++esac ++ ++case $lt_shell_append in ++ yes) ++ cat << \_LT_EOF >> "$cfgfile" ++ ++# func_append var value ++# Append VALUE to the end of shell variable VAR. ++func_append () ++{ ++ eval "$1+=\$2" ++} ++_LT_EOF ++ ;; ++ *) ++ cat << \_LT_EOF >> "$cfgfile" ++ ++# func_append var value ++# Append VALUE to the end of shell variable VAR. ++func_append () ++{ ++ eval "$1=\$$1\$2" ++} ++ ++_LT_EOF ++ ;; ++ esac ++ ++ ++ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ ++ || (rm -f "$cfgfile"; exit 1) ++ ++ mv -f "$cfgfile" "$ofile" || ++ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") ++ chmod +x "$ofile" ++ ++ ++ cat <<_LT_EOF >> "$ofile" ++ ++# ### BEGIN LIBTOOL TAG CONFIG: CXX ++ ++# The linker used to build libraries. ++LD=$lt_LD_CXX ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag_CXX ++reload_cmds=$lt_reload_cmds_CXX ++ ++# Commands used to build an old-style archive. ++old_archive_cmds=$lt_old_archive_cmds_CXX ++ ++# A language specific compiler. ++CC=$lt_compiler_CXX ++ ++# Is the compiler the GNU compiler? ++with_gcc=$GCC_CXX ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_CXX ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_CXX ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_CXX ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_CXX ++ ++# Whether or not to disallow shared libs when runtime libs are static. ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX ++ ++# Whether the compiler copes with passing no objects directly. ++compiler_needs_object=$lt_compiler_needs_object_CXX ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX ++ ++# Commands used to build a shared archive. ++archive_cmds=$lt_archive_cmds_CXX ++archive_expsym_cmds=$lt_archive_expsym_cmds_CXX ++ ++# Commands used to build a loadable module if different from building ++# a shared archive. ++module_cmds=$lt_module_cmds_CXX ++module_expsym_cmds=$lt_module_expsym_cmds_CXX ++ ++# Whether we are building with GNU ld or not. ++with_gnu_ld=$lt_with_gnu_ld_CXX ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_CXX ++ ++# Flag that enforces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_CXX ++ ++# Flag to hardcode \$libdir into a binary during linking. ++# This must work even if \$libdir does not exist ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX ++ ++# If ld is used when linking, flag to hardcode \$libdir into a binary ++# during linking. This must work even if \$libdir does not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX ++ ++# Whether we need a single "-rpath" flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX ++ ++# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes ++# DIR into the resulting binary. ++hardcode_direct=$hardcode_direct_CXX ++ ++# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes ++# DIR into the resulting binary and the resulting library dependency is ++# "absolute",i.e impossible to change by setting \${shlibpath_var} if the ++# library is relocated. ++hardcode_direct_absolute=$hardcode_direct_absolute_CXX ++ ++# Set to "yes" if using the -LDIR flag during linking hardcodes DIR ++# into the resulting binary. ++hardcode_minus_L=$hardcode_minus_L_CXX ++ ++# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR ++# into the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX ++ ++# Set to "yes" if building a shared library automatically hardcodes DIR ++# into the library and all subsequent libraries and executables linked ++# against it. ++hardcode_automatic=$hardcode_automatic_CXX ++ ++# Set to yes if linker adds runtime paths of dependent libraries ++# to runtime path list. ++inherit_rpath=$inherit_rpath_CXX ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_CXX ++ ++# Fix the shell variable \$srcfile for the compiler. ++fix_srcfile_path=$lt_fix_srcfile_path_CXX ++ ++# Set to "yes" if exported symbols are required. ++always_export_symbols=$always_export_symbols_CXX ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_CXX ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_CXX ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_CXX ++ ++# Commands necessary for linking programs (against libraries) with templates. ++prelink_cmds=$lt_prelink_cmds_CXX ++ ++# Specify filename containing input files. ++file_list_spec=$lt_file_list_spec_CXX ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_CXX ++ ++# The directories searched by this compiler when creating a shared library. ++compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX ++ ++# Dependencies to place before and after the objects being linked to ++# create a shared library. ++predep_objects=$lt_predep_objects_CXX ++postdep_objects=$lt_postdep_objects_CXX ++predeps=$lt_predeps_CXX ++postdeps=$lt_postdeps_CXX ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=$lt_compiler_lib_search_path_CXX ++ ++# ### END LIBTOOL TAG CONFIG: CXX ++_LT_EOF ++ ++ ;; ++ "default-1":C) ++ for ac_file in $CONFIG_FILES; do ++ # Support "outfile[:infile[:infile...]]" ++ case "$ac_file" in ++ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; ++ esac ++ # PO directories have a Makefile.in generated from Makefile.in.in. ++ case "$ac_file" in */Makefile.in) ++ # Adjust a relative srcdir. ++ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ++ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ++ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` ++ # In autoconf-2.13 it is called $ac_given_srcdir. ++ # In autoconf-2.50 it is called $srcdir. ++ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" ++ case "$ac_given_srcdir" in ++ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; ++ /*) top_srcdir="$ac_given_srcdir" ;; ++ *) top_srcdir="$ac_dots$ac_given_srcdir" ;; ++ esac ++ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then ++ rm -f "$ac_dir/POTFILES" ++ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" ++ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" ++ POMAKEFILEDEPS="POTFILES.in" ++ # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend ++ # on $ac_dir but don't depend on user-specified configuration ++ # parameters. ++ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then ++ # The LINGUAS file contains the set of available languages. ++ if test -n "$OBSOLETE_ALL_LINGUAS"; then ++ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.ac is obsolete" || echo "setting ALL_LINGUAS in configure.ac is obsolete" ++ fi ++ ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` ++ # Hide the ALL_LINGUAS assigment from automake. ++ eval 'ALL_LINGUAS''=$ALL_LINGUAS_' ++ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" ++ else ++ # The set of available languages was given in configure.ac. ++ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' ++ fi ++ case "$ac_given_srcdir" in ++ .) srcdirpre= ;; ++ *) srcdirpre='$(srcdir)/' ;; ++ esac ++ POFILES= ++ GMOFILES= ++ UPDATEPOFILES= ++ DUMMYPOFILES= ++ for lang in $ALL_LINGUAS; do ++ POFILES="$POFILES $srcdirpre$lang.po" ++ GMOFILES="$GMOFILES $srcdirpre$lang.gmo" ++ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" ++ DUMMYPOFILES="$DUMMYPOFILES $lang.nop" ++ done ++ # CATALOGS depends on both $ac_dir and the user's LINGUAS ++ # environment variable. ++ INST_LINGUAS= ++ if test -n "$ALL_LINGUAS"; then ++ for presentlang in $ALL_LINGUAS; do ++ useit=no ++ if test "%UNSET%" != "$LINGUAS"; then ++ desiredlanguages="$LINGUAS" ++ else ++ desiredlanguages="$ALL_LINGUAS" ++ fi ++ for desiredlang in $desiredlanguages; do ++ # Use the presentlang catalog if desiredlang is ++ # a. equal to presentlang, or ++ # b. a variant of presentlang (because in this case, ++ # presentlang can be used as a fallback for messages ++ # which are not translated in the desiredlang catalog). ++ case "$desiredlang" in ++ "$presentlang"*) useit=yes;; ++ esac ++ done ++ if test $useit = yes; then ++ INST_LINGUAS="$INST_LINGUAS $presentlang" ++ fi ++ done ++ fi ++ CATALOGS= ++ if test -n "$INST_LINGUAS"; then ++ for lang in $INST_LINGUAS; do ++ CATALOGS="$CATALOGS $lang.gmo" ++ done ++ fi ++ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" ++ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" ++ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do ++ if test -f "$f"; then ++ case "$f" in ++ *.orig | *.bak | *~) ;; ++ *) cat "$f" >> "$ac_dir/Makefile" ;; ++ esac ++ fi ++ done ++ fi ++ ;; ++ esac ++ done ;; ++ "default":C) ++case "$srcdir" in ++ .) srcdirpre= ;; ++ *) srcdirpre='$(srcdir)/' ;; ++esac ++POFILES= ++GMOFILES= ++for lang in dummy $OBSOLETE_ALL_LINGUAS; do ++ if test $lang != dummy; then ++ POFILES="$POFILES $srcdirpre$lang.po" ++ GMOFILES="$GMOFILES $srcdirpre$lang.gmo" ++ fi ++done ++sed -e '/^SRC-POTFILES =/r po/SRC-POTFILES' \ ++ -e '/^BLD-POTFILES =/r po/BLD-POTFILES' \ ++ -e "s,@POFILES@,$POFILES," \ ++ -e "s,@GMOFILES@,$GMOFILES," \ ++ po/Makefile.in > po/Makefile ;; ++ ++ esac ++done # for ac_tag ++ ++ ++as_fn_exit 0 ++_ACEOF ++ac_clean_files=$ac_clean_files_save ++ ++test $ac_write_fail = 0 || ++ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 ++ ++ ++# configure is writing to config.log, and then calls config.status. ++# config.status does its own redirection, appending to config.log. ++# Unfortunately, on DOS this fails, as config.log is still kept open ++# by configure, so config.status won't be able to write to it; its ++# output is simply discarded. So we exec the FD to /dev/null, ++# effectively closing config.log, so it can be properly (re)opened and ++# appended to by config.status. When coming back to configure, we ++# need to make the FD available again. ++if test "$no_create" != yes; then ++ ac_cs_success=: ++ ac_config_status_args= ++ test "$silent" = yes && ++ ac_config_status_args="$ac_config_status_args --quiet" ++ exec 5>/dev/null ++ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false ++ exec 5>>config.log ++ # Use ||, not &&, to avoid exiting from the if with $? = 1, which ++ # would make configure fail if this is the last instruction. ++ $ac_cs_success || as_fn_exit 1 ++fi ++if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 ++$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} ++fi ++ ++ ++ ++touch config.status.tmp ++if touch --reference=config.status config.status.tmp > /dev/null 2>&1; then ++ sed '/as_fn_exit 0/i \ ++sed -e \"s/^\t\\\(\\\$(AM_V_CCLD)\\\)/\t+ \\\1/\" Makefile > Makefile.tmp \ ++touch --reference=Makefile Makefile.tmp \ ++mv Makefile.tmp Makefile \ ++' config.status > config.status.tmp ++ touch --reference=config.status config.status.tmp ++ mv config.status.tmp config.status ++ chmod +x config.status ++ sed -e "s/^\t\(\$(AM_V_CCLD)\)/\t+ \1/" Makefile > Makefile.tmp ++ touch --reference=Makefile Makefile.tmp ++ mv Makefile.tmp Makefile ++else ++ rm -f config.status.tmp ++fi +diff -rupN binutils.orig/ld/configure.rej binutils-2.41/ld/configure.rej +--- binutils.orig/ld/configure.rej 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/configure.rej 2023-10-19 12:11:56.516949626 +0100 +@@ -0,0 +1,34 @@ ++--- ld/configure +++++ ld/configure ++@@ -1536,9 +1538,13 @@ Optional Features: ++ enable DT_TEXTREL check in ELF linker ++ --enable-separate-code enable -z separate-code in ELF linker by default ++ --enable-warn-execstack enable warnings when creating an executable stack +++ --enable-error-execstack +++ turn executable stack warnings into errors ++ --enable-warn-rwx-segments ++ enable warnings when creating segments with RWX ++ permissions +++ --enable-error-rwx-segments +++ turn executable segment warnings into errors ++ --enable-default-execstack ++ create an executable stack if an input file is ++ missing a .note.GNU-stack section ++@@ -11657,7 +11663,7 @@ else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<_LT_EOF ++-#line 11658 "configure" +++#line 11664 "configure" ++ #include "confdefs.h" ++ ++ #if HAVE_DLFCN_H ++@@ -11763,7 +11769,7 @@ else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<_LT_EOF ++-#line 11764 "configure" +++#line 11770 "configure" ++ #include "confdefs.h" ++ ++ #if HAVE_DLFCN_H +diff -rupN binutils.orig/ld/emultempl/elf.em binutils-2.41/ld/emultempl/elf.em +--- binutils.orig/ld/emultempl/elf.em 2023-10-19 12:11:47.286940542 +0100 ++++ binutils-2.41/ld/emultempl/elf.em 2023-10-19 12:11:56.516949626 +0100 +@@ -95,6 +95,8 @@ fragment < MEM1 ++ mem2 : @{ *(.data.*); @} > MEM2 ++ mem3 : @{ *(.data.*); @} > MEM3 ++ @} ++ ++ with input sections: ++ .data.1: size 8 ++ .data.2: size 0x10 ++ .data.3: size 4 ++ ++ results in .data.1 affected to mem1, and .data.2 and .data.3 ++ affected to mem2, even though .data.3 would fit in mem3. ++@end smallexample ++ ++This option is incompatible with INSERT statements because it changes ++the way input sections are mapped to output sections. ++ ++@kindex --enable-non-contiguous-regions-warnings ++@item --enable-non-contiguous-regions-warnings ++This option enables warnings when ++@code{--enable-non-contiguous-regions} allows possibly unexpected ++matches in sections mapping, potentially leading to silently ++discarding a section instead of failing because it does not fit any ++output region. ++ ++@cindex entry point, from command line ++@kindex -e @var{entry} ++@kindex --entry=@var{entry} ++@item -e @var{entry} ++@itemx --entry=@var{entry} ++Use @var{entry} as the explicit symbol for beginning execution of your ++program, rather than the default entry point. If there is no symbol ++named @var{entry}, the linker will try to parse @var{entry} as a number, ++and use that as the entry address (the number will be interpreted in ++base 10; you may use a leading @samp{0x} for base 16, or a leading ++@samp{0} for base 8). @xref{Entry Point}, for a discussion of defaults ++and other ways of specifying the entry point. ++ ++@kindex --exclude-libs ++@item --exclude-libs @var{lib},@var{lib},... ++Specifies a list of archive libraries from which symbols should not be automatically ++exported. The library names may be delimited by commas or colons. Specifying ++@code{--exclude-libs ALL} excludes symbols in all archive libraries from ++automatic export. This option is available only for the i386 PE targeted ++port of the linker and for ELF targeted ports. For i386 PE, symbols ++explicitly listed in a .def file are still exported, regardless of this ++option. For ELF targeted ports, symbols affected by this option will ++be treated as hidden. ++ ++@kindex --exclude-modules-for-implib ++@item --exclude-modules-for-implib @var{module},@var{module},... ++Specifies a list of object files or archive members, from which symbols ++should not be automatically exported, but which should be copied wholesale ++into the import library being generated during the link. The module names ++may be delimited by commas or colons, and must match exactly the filenames ++used by @command{ld} to open the files; for archive members, this is simply ++the member name, but for object files the name listed must include and ++match precisely any path used to specify the input file on the linker's ++command-line. This option is available only for the i386 PE targeted port ++of the linker. Symbols explicitly listed in a .def file are still exported, ++regardless of this option. ++ ++@cindex dynamic symbol table ++@kindex -E ++@kindex --export-dynamic ++@kindex --no-export-dynamic ++@item -E ++@itemx --export-dynamic ++@itemx --no-export-dynamic ++When creating a dynamically linked executable, using the @option{-E} ++option or the @option{--export-dynamic} option causes the linker to add ++all symbols to the dynamic symbol table. The dynamic symbol table is the ++set of symbols which are visible from dynamic objects at run time. ++ ++If you do not use either of these options (or use the ++@option{--no-export-dynamic} option to restore the default behavior), the ++dynamic symbol table will normally contain only those symbols which are ++referenced by some dynamic object mentioned in the link. ++ ++If you use @code{dlopen} to load a dynamic object which needs to refer ++back to the symbols defined by the program, rather than some other ++dynamic object, then you will probably need to use this option when ++linking the program itself. ++ ++You can also use the dynamic list to control what symbols should ++be added to the dynamic symbol table if the output format supports it. ++See the description of @samp{--dynamic-list}. ++ ++Note that this option is specific to ELF targeted ports. PE targets ++support a similar function to export all symbols from a DLL or EXE; see ++the description of @samp{--export-all-symbols} below. ++ ++@kindex --export-dynamic-symbol=@var{glob} ++@cindex export dynamic symbol ++@item --export-dynamic-symbol=@var{glob} ++When creating a dynamically linked executable, symbols matching ++@var{glob} will be added to the dynamic symbol table. When creating a ++shared library, references to symbols matching @var{glob} will not be ++bound to the definitions within the shared library. This option is a ++no-op when creating a shared library and @samp{-Bsymbolic} or ++@samp{--dynamic-list} are not specified. This option is only meaningful ++on ELF platforms which support shared libraries. ++ ++@kindex --export-dynamic-symbol-list=@var{file} ++@cindex export dynamic symbol list ++@item --export-dynamic-symbol-list=@var{file} ++Specify a @samp{--export-dynamic-symbol} for each pattern in the file. ++The format of the file is the same as the version node without ++scope and node name. See @ref{VERSION} for more information. ++ ++@ifclear SingleFormat ++@cindex big-endian objects ++@cindex endianness ++@kindex -EB ++@item -EB ++Link big-endian objects. This affects the default output format. ++ ++@cindex little-endian objects ++@kindex -EL ++@item -EL ++Link little-endian objects. This affects the default output format. ++@end ifclear ++ ++@kindex -f @var{name} ++@kindex --auxiliary=@var{name} ++@item -f @var{name} ++@itemx --auxiliary=@var{name} ++When creating an ELF shared object, set the internal DT_AUXILIARY field ++to the specified name. This tells the dynamic linker that the symbol ++table of the shared object should be used as an auxiliary filter on the ++symbol table of the shared object @var{name}. ++ ++If you later link a program against this filter object, then, when you ++run the program, the dynamic linker will see the DT_AUXILIARY field. If ++the dynamic linker resolves any symbols from the filter object, it will ++first check whether there is a definition in the shared object ++@var{name}. If there is one, it will be used instead of the definition ++in the filter object. The shared object @var{name} need not exist. ++Thus the shared object @var{name} may be used to provide an alternative ++implementation of certain functions, perhaps for debugging or for ++machine-specific performance. ++ ++This option may be specified more than once. The DT_AUXILIARY entries ++will be created in the order in which they appear on the command line. ++ ++@kindex -F @var{name} ++@kindex --filter=@var{name} ++@item -F @var{name} ++@itemx --filter=@var{name} ++When creating an ELF shared object, set the internal DT_FILTER field to ++the specified name. This tells the dynamic linker that the symbol table ++of the shared object which is being created should be used as a filter ++on the symbol table of the shared object @var{name}. ++ ++If you later link a program against this filter object, then, when you ++run the program, the dynamic linker will see the DT_FILTER field. The ++dynamic linker will resolve symbols according to the symbol table of the ++filter object as usual, but it will actually link to the definitions ++found in the shared object @var{name}. Thus the filter object can be ++used to select a subset of the symbols provided by the object ++@var{name}. ++ ++Some older linkers used the @option{-F} option throughout a compilation ++toolchain for specifying object-file format for both input and output ++object files. ++@ifclear SingleFormat ++The @sc{gnu} linker uses other mechanisms for this purpose: the ++@option{-b}, @option{--format}, @option{--oformat} options, the ++@code{TARGET} command in linker scripts, and the @code{GNUTARGET} ++environment variable. ++@end ifclear ++The @sc{gnu} linker will ignore the @option{-F} option when not ++creating an ELF shared object. ++ ++@cindex finalization function ++@kindex -fini=@var{name} ++@item -fini=@var{name} ++When creating an ELF executable or shared object, call NAME when the ++executable or shared object is unloaded, by setting DT_FINI to the ++address of the function. By default, the linker uses @code{_fini} as ++the function to call. ++ ++@kindex -g ++@item -g ++Ignored. Provided for compatibility with other tools. ++ ++@kindex -G @var{value} ++@kindex --gpsize=@var{value} ++@cindex object size ++@item -G @var{value} ++@itemx --gpsize=@var{value} ++Set the maximum size of objects to be optimized using the GP register to ++@var{size}. This is only meaningful for object file formats such as ++MIPS ELF that support putting large and small objects into different ++sections. This is ignored for other object file formats. ++ ++@cindex runtime library name ++@kindex -h @var{name} ++@kindex -soname=@var{name} ++@item -h @var{name} ++@itemx -soname=@var{name} ++When creating an ELF shared object, set the internal DT_SONAME field to ++the specified name. When an executable is linked with a shared object ++which has a DT_SONAME field, then when the executable is run the dynamic ++linker will attempt to load the shared object specified by the DT_SONAME ++field rather than using the file name given to the linker. ++ ++@kindex -i ++@cindex incremental link ++@item -i ++Perform an incremental link (same as option @samp{-r}). ++ ++@cindex initialization function ++@kindex -init=@var{name} ++@item -init=@var{name} ++When creating an ELF executable or shared object, call NAME when the ++executable or shared object is loaded, by setting DT_INIT to the address ++of the function. By default, the linker uses @code{_init} as the ++function to call. ++ ++@cindex archive files, from cmd line ++@kindex -l @var{namespec} ++@kindex --library=@var{namespec} ++@item -l @var{namespec} ++@itemx --library=@var{namespec} ++Add the archive or object file specified by @var{namespec} to the ++list of files to link. This option may be used any number of times. ++If @var{namespec} is of the form @file{:@var{filename}}, @command{ld} ++will search the library path for a file called @var{filename}, otherwise it ++will search the library path for a file called @file{lib@var{namespec}.a}. ++ ++On systems which support shared libraries, @command{ld} may also search for ++files other than @file{lib@var{namespec}.a}. Specifically, on ELF ++and SunOS systems, @command{ld} will search a directory for a library ++called @file{lib@var{namespec}.so} before searching for one called ++@file{lib@var{namespec}.a}. (By convention, a @code{.so} extension ++indicates a shared library.) Note that this behavior does not apply ++to @file{:@var{filename}}, which always specifies a file called ++@var{filename}. ++ ++The linker will search an archive only once, at the location where it is ++specified on the command line. If the archive defines a symbol which ++was undefined in some object which appeared before the archive on the ++command line, the linker will include the appropriate file(s) from the ++archive. However, an undefined symbol in an object appearing later on ++the command line will not cause the linker to search the archive again. ++ ++See the @option{-(} option for a way to force the linker to search ++archives multiple times. ++ ++You may list the same archive multiple times on the command line. ++ ++@ifset GENERIC ++This type of archive searching is standard for Unix linkers. However, ++if you are using @command{ld} on AIX, note that it is different from the ++behaviour of the AIX linker. ++@end ifset ++ ++@cindex search directory, from cmd line ++@kindex -L @var{dir} ++@kindex --library-path=@var{dir} ++@item -L @var{searchdir} ++@itemx --library-path=@var{searchdir} ++Add path @var{searchdir} to the list of paths that @command{ld} will search ++for archive libraries and @command{ld} control scripts. You may use this ++option any number of times. The directories are searched in the order ++in which they are specified on the command line. Directories specified ++on the command line are searched before the default directories. All ++@option{-L} options apply to all @option{-l} options, regardless of the ++order in which the options appear. @option{-L} options do not affect ++how @command{ld} searches for a linker script unless @option{-T} ++option is specified. ++ ++If @var{searchdir} begins with @code{=} or @code{$SYSROOT}, then this ++prefix will be replaced by the @dfn{sysroot prefix}, controlled by the ++@samp{--sysroot} option, or specified when the linker is configured. ++ ++@ifset UsesEnvVars ++The default set of paths searched (without being specified with ++@samp{-L}) depends on which emulation mode @command{ld} is using, and in ++some cases also on how it was configured. @xref{Environment}. ++@end ifset ++ ++The paths can also be specified in a link script with the ++@code{SEARCH_DIR} command. Directories specified this way are searched ++at the point in which the linker script appears in the command line. ++ ++@cindex emulation ++@kindex -m @var{emulation} ++@item -m @var{emulation} ++Emulate the @var{emulation} linker. You can list the available ++emulations with the @samp{--verbose} or @samp{-V} options. ++ ++If the @samp{-m} option is not used, the emulation is taken from the ++@code{LDEMULATION} environment variable, if that is defined. ++ ++Otherwise, the default emulation depends upon how the linker was ++configured. ++ ++@cindex remapping inputs ++@kindex --remap-inputs=@file{pattern}=@file{filename} ++@kindex --remap-inputs-file=@file{file} ++@item --remap-inputs=@file{pattern}=@file{filename} ++@itemx --remap-inputs-file=@file{file} ++These options allow the names of input files to be changed before the ++linker attempts to open them. The option ++@option{--remap-inputs=foo.o=bar.o} will cause any attempt to load a ++file called @file{foo.o} to instead try to load a file called ++@file{bar.o}. Wildcard patterns are permitted in the first filename, ++so @option{--remap-inputs=foo*.o=bar.o} will rename any input file that ++matches @file{foo*.o} to @file{bar.o}. ++ ++An alternative form of the option ++@option{--remap-inputs-file=filename} allows the remappings to be read ++from a file. Each line in the file can contain a single remapping. ++Blank lines are ignored. Anything from a hash character (@samp{#}) to ++the end of a line is considered to be a comment and is also ignored. ++The mapping pattern can be separated from the filename by whitespace ++or an equals (@samp{=}) character. ++ ++The options can be specified multiple times. Their contents ++accumulate. The remappings will be processed in the order in which ++they occur on the command line, and if they come from a file, in the ++order in which they occur in the file. If a match is made, no further ++checking for that filename will be performed. ++ ++If the replacement filename is @file{/dev/null} or just @file{NUL} ++then the remapping will actually cause the input file to be ignored. ++This can be a convenient way to experiment with removing input files ++from a complicated build environment. ++ ++Note that this option is position dependent and only affects filenames ++that come after it on the command line. Thus: ++ ++@smallexample ++ ld foo.o --remap-inputs=foo.o=bar.o ++@end smallexample ++ ++Will have no effect, whereas: ++ ++@smallexample ++ ld --remap-inputs=foo.o=bar.o foo.o ++@end smallexample ++ ++Will rename the input file @file{foo.o} to @file{bar.o}. ++ ++Note - these options also affect files referenced by @emph{INPUT} ++statements in linker scripts. But since linker scripts are processed ++after the entire command line is read, the position of the remap ++options on the command line is not significant. ++ ++If the @option{verbose} option is enabled then any mappings that match ++will be reported, although again the @option{verbose} option needs to ++be enabled on the command line @emph{before} the remaped filenames ++appear. ++ ++If the @option{-Map} or @option{--print-map} options are enabled then ++the remapping list will be included in the map output. ++ ++@cindex link map ++@kindex -M ++@kindex --print-map ++@item -M ++@itemx --print-map ++Print a link map to the standard output. A link map provides ++information about the link, including the following: ++ ++@itemize @bullet ++@item ++Where object files are mapped into memory. ++@item ++How common symbols are allocated. ++@item ++All archive members included in the link, with a mention of the symbol ++which caused the archive member to be brought in. ++@item ++The values assigned to symbols. ++ ++Note - symbols whose values are computed by an expression which ++involves a reference to a previous value of the same symbol may not ++have correct result displayed in the link map. This is because the ++linker discards intermediate results and only retains the final value ++of an expression. Under such circumstances the linker will display ++the final value enclosed by square brackets. Thus for example a ++linker script containing: ++ ++@smallexample ++ foo = 1 ++ foo = foo * 4 ++ foo = foo + 8 ++@end smallexample ++ ++will produce the following output in the link map if the @option{-M} ++option is used: ++ ++@smallexample ++ 0x00000001 foo = 0x1 ++ [0x0000000c] foo = (foo * 0x4) ++ [0x0000000c] foo = (foo + 0x8) ++@end smallexample ++ ++See @ref{Expressions} for more information about expressions in linker ++scripts. ++ ++@item ++How GNU properties are merged. ++ ++When the linker merges input .note.gnu.property sections into one output ++.note.gnu.property section, some properties are removed or updated. ++These actions are reported in the link map. For example: ++ ++@smallexample ++Removed property 0xc0000002 to merge foo.o (0x1) and bar.o (not found) ++@end smallexample ++ ++This indicates that property 0xc0000002 is removed from output when ++merging properties in @file{foo.o}, whose property 0xc0000002 value ++is 0x1, and @file{bar.o}, which doesn't have property 0xc0000002. ++ ++@smallexample ++Updated property 0xc0010001 (0x1) to merge foo.o (0x1) and bar.o (0x1) ++@end smallexample ++ ++This indicates that property 0xc0010001 value is updated to 0x1 in output ++when merging properties in @file{foo.o}, whose 0xc0010001 property value ++is 0x1, and @file{bar.o}, whose 0xc0010001 property value is 0x1. ++@end itemize ++ ++@cindex link map discarded ++@kindex --print-map-discarded ++@kindex --no-print-map-discarded ++@item --print-map-discarded ++@itemx --no-print-map-discarded ++Print (or do not print) the list of discarded and garbage collected sections ++in the link map. Enabled by default. ++ ++@kindex --print-map-locals ++@kindex --no-print-map-locals ++@item --print-map-locals ++@itemx --no-print-map-locals ++Print (or do not print) local symbols in the link map. Local symbols ++will have the text @samp{(local)} printed before their name, and will ++be listed after all of the global symbols in a given section. ++Temporary local symbols (typically those that start with @samp{.L}) ++will not be included in the output. Disabled by default. ++ ++@kindex -n ++@cindex read-only text ++@cindex NMAGIC ++@kindex --nmagic ++@item -n ++@itemx --nmagic ++Turn off page alignment of sections, and disable linking against shared ++libraries. If the output format supports Unix style magic numbers, ++mark the output as @code{NMAGIC}. ++ ++@kindex -N ++@kindex --omagic ++@cindex read/write from cmd line ++@cindex OMAGIC ++@item -N ++@itemx --omagic ++Set the text and data sections to be readable and writable. Also, do ++not page-align the data segment, and disable linking against shared ++libraries. If the output format supports Unix style magic numbers, ++mark the output as @code{OMAGIC}. Note: Although a writable text section ++is allowed for PE-COFF targets, it does not conform to the format ++specification published by Microsoft. ++ ++@kindex --no-omagic ++@cindex OMAGIC ++@item --no-omagic ++This option negates most of the effects of the @option{-N} option. It ++sets the text section to be read-only, and forces the data segment to ++be page-aligned. Note - this option does not enable linking against ++shared libraries. Use @option{-Bdynamic} for this. ++ ++@kindex -o @var{output} ++@kindex --output=@var{output} ++@cindex naming the output file ++@item -o @var{output} ++@itemx --output=@var{output} ++Use @var{output} as the name for the program produced by @command{ld}; if this ++option is not specified, the name @file{a.out} is used by default. The ++script command @code{OUTPUT} can also specify the output file name. ++ ++@kindex --dependency-file=@var{depfile} ++@cindex dependency file ++@item --dependency-file=@var{depfile} ++Write a @dfn{dependency file} to @var{depfile}. This file contains a rule ++suitable for @code{make} describing the output file and all the input files ++that were read to produce it. The output is similar to the compiler's ++output with @samp{-M -MP} (@pxref{Preprocessor Options,, Options ++Controlling the Preprocessor, gcc.info, Using the GNU Compiler ++Collection}). Note that there is no option like the compiler's @samp{-MM}, ++to exclude ``system files'' (which is not a well-specified concept in the ++linker, unlike ``system headers'' in the compiler). So the output from ++@samp{--dependency-file} is always specific to the exact state of the ++installation where it was produced, and should not be copied into ++distributed makefiles without careful editing. ++ ++@kindex -O @var{level} ++@cindex generating optimized output ++@item -O @var{level} ++If @var{level} is a numeric values greater than zero @command{ld} optimizes ++the output. This might take significantly longer and therefore probably ++should only be enabled for the final binary. At the moment this ++option only affects ELF shared library generation. Future releases of ++the linker may make more use of this option. Also currently there is ++no difference in the linker's behaviour for different non-zero values ++of this option. Again this may change with future releases. ++ ++@kindex -plugin @var{name} ++@item -plugin @var{name} ++Involve a plugin in the linking process. The @var{name} parameter is ++the absolute filename of the plugin. Usually this parameter is ++automatically added by the complier, when using link time ++optimization, but users can also add their own plugins if they so ++wish. ++ ++Note that the location of the compiler originated plugins is different ++from the place where the @command{ar}, @command{nm} and ++@command{ranlib} programs search for their plugins. In order for ++those commands to make use of a compiler based plugin it must first be ++copied into the @file{$@{libdir@}/bfd-plugins} directory. All gcc ++based linker plugins are backward compatible, so it is sufficient to ++just copy in the newest one. ++ ++@kindex --push-state ++@cindex push state governing input file handling ++@item --push-state ++The @option{--push-state} allows one to preserve the current state of the ++flags which govern the input file handling so that they can all be ++restored with one corresponding @option{--pop-state} option. ++ ++The option which are covered are: @option{-Bdynamic}, @option{-Bstatic}, ++@option{-dn}, @option{-dy}, @option{-call_shared}, @option{-non_shared}, ++@option{-static}, @option{-N}, @option{-n}, @option{--whole-archive}, ++@option{--no-whole-archive}, @option{-r}, @option{-Ur}, ++@option{--copy-dt-needed-entries}, @option{--no-copy-dt-needed-entries}, ++@option{--as-needed}, @option{--no-as-needed}, and @option{-a}. ++ ++One target for this option are specifications for @file{pkg-config}. When ++used with the @option{--libs} option all possibly needed libraries are ++listed and then possibly linked with all the time. It is better to return ++something as follows: ++ ++@smallexample ++-Wl,--push-state,--as-needed -libone -libtwo -Wl,--pop-state ++@end smallexample ++ ++@kindex --pop-state ++@cindex pop state governing input file handling ++@item --pop-state ++Undoes the effect of --push-state, restores the previous values of the ++flags governing input file handling. ++ ++@kindex -q ++@kindex --emit-relocs ++@cindex retain relocations in final executable ++@item -q ++@itemx --emit-relocs ++Leave relocation sections and contents in fully linked executables. ++Post link analysis and optimization tools may need this information in ++order to perform correct modifications of executables. This results ++in larger executables. ++ ++This option is currently only supported on ELF platforms. ++ ++@kindex --force-dynamic ++@cindex forcing the creation of dynamic sections ++@item --force-dynamic ++Force the output file to have dynamic sections. This option is specific ++to VxWorks targets. ++ ++@cindex partial link ++@cindex relocatable output ++@kindex -r ++@kindex --relocatable ++@item -r ++@itemx --relocatable ++Generate relocatable output---i.e., generate an output file that can in ++turn serve as input to @command{ld}. This is often called @dfn{partial ++linking}. As a side effect, in environments that support standard Unix ++magic numbers, this option also sets the output file's magic number to ++@code{OMAGIC}. ++@c ; see @option{-N}. ++If this option is not specified, an absolute file is produced. When ++linking C++ programs, this option @emph{will not} resolve references to ++constructors; to do that, use @samp{-Ur}. ++ ++When an input file does not have the same format as the output file, ++partial linking is only supported if that input file does not contain any ++relocations. Different output formats can have further restrictions; for ++example some @code{a.out}-based formats do not support partial linking ++with input files in other formats at all. ++ ++This option does the same thing as @samp{-i}. ++ ++@kindex -R @var{file} ++@kindex --just-symbols=@var{file} ++@cindex symbol-only input ++@item -R @var{filename} ++@itemx --just-symbols=@var{filename} ++Read symbol names and their addresses from @var{filename}, but do not ++relocate it or include it in the output. This allows your output file ++to refer symbolically to absolute locations of memory defined in other ++programs. You may use this option more than once. ++ ++For compatibility with other ELF linkers, if the @option{-R} option is ++followed by a directory name, rather than a file name, it is treated as ++the @option{-rpath} option. ++ ++@kindex -s ++@kindex --strip-all ++@cindex strip all symbols ++@item -s ++@itemx --strip-all ++Omit all symbol information from the output file. ++ ++@kindex -S ++@kindex --strip-debug ++@cindex strip debugger symbols ++@item -S ++@itemx --strip-debug ++Omit debugger symbol information (but not all symbols) from the output file. ++ ++@kindex --strip-discarded ++@kindex --no-strip-discarded ++@item --strip-discarded ++@itemx --no-strip-discarded ++Omit (or do not omit) global symbols defined in discarded sections. ++Enabled by default. ++ ++@kindex -t ++@kindex --trace ++@cindex input files, displaying ++@item -t ++@itemx --trace ++Print the names of the input files as @command{ld} processes them. If ++@samp{-t} is given twice then members within archives are also printed. ++@samp{-t} output is useful to generate a list of all the object files ++and scripts involved in linking, for example, when packaging files for ++a linker bug report. ++ ++@kindex -T @var{script} ++@kindex --script=@var{script} ++@cindex script files ++@item -T @var{scriptfile} ++@itemx --script=@var{scriptfile} ++Use @var{scriptfile} as the linker script. This script replaces ++@command{ld}'s default linker script (rather than adding to it), ++unless the script contains @code{INSERT}, so ++@var{commandfile} must specify everything necessary to describe the ++output file. @xref{Scripts}. If @var{scriptfile} does not exist in ++the current directory, @code{ld} looks for it in the directories ++specified by any preceding @samp{-L} options. Multiple @samp{-T} ++options accumulate. ++ ++@kindex -dT @var{script} ++@kindex --default-script=@var{script} ++@cindex script files ++@item -dT @var{scriptfile} ++@itemx --default-script=@var{scriptfile} ++Use @var{scriptfile} as the default linker script. @xref{Scripts}. ++ ++This option is similar to the @option{--script} option except that ++processing of the script is delayed until after the rest of the ++command line has been processed. This allows options placed after the ++@option{--default-script} option on the command line to affect the ++behaviour of the linker script, which can be important when the linker ++command line cannot be directly controlled by the user. (eg because ++the command line is being constructed by another tool, such as ++@samp{gcc}). ++ ++@kindex -u @var{symbol} ++@kindex --undefined=@var{symbol} ++@cindex undefined symbol ++@item -u @var{symbol} ++@itemx --undefined=@var{symbol} ++Force @var{symbol} to be entered in the output file as an undefined ++symbol. Doing this may, for example, trigger linking of additional ++modules from standard libraries. @samp{-u} may be repeated with ++different option arguments to enter additional undefined symbols. This ++option is equivalent to the @code{EXTERN} linker script command. ++ ++If this option is being used to force additional modules to be pulled ++into the link, and if it is an error for the symbol to remain ++undefined, then the option @option{--require-defined} should be used ++instead. ++ ++@kindex --require-defined=@var{symbol} ++@cindex symbols, require defined ++@cindex defined symbol ++@item --require-defined=@var{symbol} ++Require that @var{symbol} is defined in the output file. This option ++is the same as option @option{--undefined} except that if @var{symbol} ++is not defined in the output file then the linker will issue an error ++and exit. The same effect can be achieved in a linker script by using ++@code{EXTERN}, @code{ASSERT} and @code{DEFINED} together. This option ++can be used multiple times to require additional symbols. ++ ++@kindex -Ur ++@cindex constructors ++@item -Ur ++ ++For programs that do not use constructors or destructors, or for ELF ++based systems this option is equivalent to @option{-r}: it generates ++relocatable output---i.e., an output file that can in turn serve as ++input to @command{ld}. For other binaries however the @option{-Ur} ++option is similar to @option{-r} but it also resolves references to ++constructors and destructors. ++ ++For those systems where @option{-r} and @option{-Ur} behave ++differently, it does not work to use @option{-Ur} on files that were ++themselves linked with @option{-Ur}; once the constructor table has ++been built, it cannot be added to. Use @option{-Ur} only for the last ++partial link, and @option{-r} for the others. ++ ++@kindex --orphan-handling=@var{MODE} ++@cindex orphan sections ++@cindex sections, orphan ++@item --orphan-handling=@var{MODE} ++Control how orphan sections are handled. An orphan section is one not ++specifically mentioned in a linker script. @xref{Orphan Sections}. ++ ++@var{MODE} can have any of the following values: ++ ++@table @code ++@item place ++Orphan sections are placed into a suitable output section following ++the strategy described in @ref{Orphan Sections}. The option ++@samp{--unique} also affects how sections are placed. ++ ++@item discard ++All orphan sections are discarded, by placing them in the ++@samp{/DISCARD/} section (@pxref{Output Section Discarding}). ++ ++@item warn ++The linker will place the orphan section as for @code{place} and also ++issue a warning. ++ ++@item error ++The linker will exit with an error if any orphan section is found. ++@end table ++ ++The default if @samp{--orphan-handling} is not given is @code{place}. ++ ++@kindex --unique[=@var{SECTION}] ++@item --unique[=@var{SECTION}] ++Creates a separate output section for every input section matching ++@var{SECTION}, or if the optional wildcard @var{SECTION} argument is ++missing, for every orphan input section. An orphan section is one not ++specifically mentioned in a linker script. You may use this option ++multiple times on the command line; It prevents the normal merging of ++input sections with the same name, overriding output section assignments ++in a linker script. ++ ++@kindex -v ++@kindex -V ++@kindex --version ++@cindex version ++@item -v ++@itemx --version ++@itemx -V ++Display the version number for @command{ld}. The @option{-V} option also ++lists the supported emulations. See also the description of the ++@option{--enable-linker-version} in @ref{Options,,Command-line Options} ++which can be used to insert the linker version string into a binary. ++ ++@kindex -x ++@kindex --discard-all ++@cindex deleting local symbols ++@item -x ++@itemx --discard-all ++Delete all local symbols. ++ ++@kindex -X ++@kindex --discard-locals ++@cindex local symbols, deleting ++@item -X ++@itemx --discard-locals ++Delete all temporary local symbols. (These symbols start with ++system-specific local label prefixes, typically @samp{.L} for ELF systems ++or @samp{L} for traditional a.out systems.) ++ ++@kindex -y @var{symbol} ++@kindex --trace-symbol=@var{symbol} ++@cindex symbol tracing ++@item -y @var{symbol} ++@itemx --trace-symbol=@var{symbol} ++Print the name of each linked file in which @var{symbol} appears. This ++option may be given any number of times. On many systems it is necessary ++to prepend an underscore. ++ ++This option is useful when you have an undefined symbol in your link but ++don't know where the reference is coming from. ++ ++@kindex -Y @var{path} ++@item -Y @var{path} ++Add @var{path} to the default library search path. This option exists ++for Solaris compatibility. ++ ++@kindex -z @var{keyword} ++@item -z @var{keyword} ++The recognized keywords are: ++@table @samp ++ ++@item call-nop=prefix-addr ++@itemx call-nop=suffix-nop ++@itemx call-nop=prefix-@var{byte} ++@itemx call-nop=suffix-@var{byte} ++Specify the 1-byte @code{NOP} padding when transforming indirect call ++to a locally defined function, foo, via its GOT slot. ++@option{call-nop=prefix-addr} generates @code{0x67 call foo}. ++@option{call-nop=suffix-nop} generates @code{call foo 0x90}. ++@option{call-nop=prefix-@var{byte}} generates @code{@var{byte} call foo}. ++@option{call-nop=suffix-@var{byte}} generates @code{call foo @var{byte}}. ++Supported for i386 and x86_64. ++ ++@item cet-report=none ++@itemx cet-report=warning ++@itemx cet-report=error ++Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_IBT and ++GNU_PROPERTY_X86_FEATURE_1_SHSTK properties in input .note.gnu.property ++section. @option{cet-report=none}, which is the default, will make the ++linker not report missing properties in input files. ++@option{cet-report=warning} will make the linker issue a warning for ++missing properties in input files. @option{cet-report=error} will make ++the linker issue an error for missing properties in input files. ++Note that @option{ibt} will turn off the missing ++GNU_PROPERTY_X86_FEATURE_1_IBT property report and @option{shstk} will ++turn off the missing GNU_PROPERTY_X86_FEATURE_1_SHSTK property report. ++Supported for Linux/i386 and Linux/x86_64. ++ ++@item combreloc ++@itemx nocombreloc ++Combine multiple dynamic relocation sections and sort to improve ++dynamic symbol lookup caching. Do not do this if @samp{nocombreloc}. ++ ++@item common ++@itemx nocommon ++Generate common symbols with STT_COMMON type during a relocatable ++link. Use STT_OBJECT type if @samp{nocommon}. ++ ++@item common-page-size=@var{value} ++Set the page size most commonly used to @var{value}. Memory image ++layout will be optimized to minimize memory pages if the system is ++using pages of this size. ++ ++@item defs ++Report unresolved symbol references from regular object files. This ++is done even if the linker is creating a non-symbolic shared library. ++This option is the inverse of @samp{-z undefs}. ++ ++@item dynamic-undefined-weak ++@itemx nodynamic-undefined-weak ++Make undefined weak symbols dynamic when building a dynamic object, ++if they are referenced from a regular object file and not forced local ++by symbol visibility or versioning. Do not make them dynamic if ++@samp{nodynamic-undefined-weak}. If neither option is given, a target ++may default to either option being in force, or make some other ++selection of undefined weak symbols dynamic. Not all targets support ++these options. ++ ++@item execstack ++Marks the object as requiring executable stack. ++ ++@item global ++This option is only meaningful when building a shared object. It makes ++the symbols defined by this shared object available for symbol resolution ++of subsequently loaded libraries. ++ ++@item globalaudit ++This option is only meaningful when building a dynamic executable. ++This option marks the executable as requiring global auditing by ++setting the @code{DF_1_GLOBAUDIT} bit in the @code{DT_FLAGS_1} dynamic ++tag. Global auditing requires that any auditing library defined via ++the @option{--depaudit} or @option{-P} command-line options be run for ++all dynamic objects loaded by the application. ++ ++@item ibtplt ++Generate Intel Indirect Branch Tracking (IBT) enabled PLT entries. ++Supported for Linux/i386 and Linux/x86_64. ++ ++@item ibt ++Generate GNU_PROPERTY_X86_FEATURE_1_IBT in .note.gnu.property section ++to indicate compatibility with IBT. This also implies @option{ibtplt}. ++Supported for Linux/i386 and Linux/x86_64. ++ ++@item indirect-extern-access ++@itemx noindirect-extern-access ++Generate GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS in ++.note.gnu.property section to indicate that object file requires ++canonical function pointers and cannot be used with copy relocation. ++This option also implies @option{noextern-protected-data} and ++@option{nocopyreloc}. Supported for i386 and x86-64. ++ ++@option{noindirect-extern-access} removes ++GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS from .note.gnu.property ++section. ++ ++@item initfirst ++This option is only meaningful when building a shared object. ++It marks the object so that its runtime initialization will occur ++before the runtime initialization of any other objects brought into ++the process at the same time. Similarly the runtime finalization of ++the object will occur after the runtime finalization of any other ++objects. ++ ++@item interpose ++Specify that the dynamic loader should modify its symbol search order ++so that symbols in this shared library interpose all other shared ++libraries not so marked. ++ ++@item unique ++@itemx nounique ++When generating a shared library or other dynamically loadable ELF ++object mark it as one that should (by default) only ever be loaded once, ++and only in the main namespace (when using @code{dlmopen}). This is ++primarily used to mark fundamental libraries such as libc, libpthread et ++al which do not usually function correctly unless they are the sole instances ++of themselves. This behaviour can be overridden by the @code{dlmopen} caller ++and does not apply to certain loading mechanisms (such as audit libraries). ++ ++@item lam-u48 ++Generate GNU_PROPERTY_X86_FEATURE_1_LAM_U48 in .note.gnu.property section ++to indicate compatibility with Intel LAM_U48. Supported for Linux/x86_64. ++ ++@item lam-u57 ++Generate GNU_PROPERTY_X86_FEATURE_1_LAM_U57 in .note.gnu.property section ++to indicate compatibility with Intel LAM_U57. Supported for Linux/x86_64. ++ ++@item lam-u48-report=none ++@itemx lam-u48-report=warning ++@itemx lam-u48-report=error ++Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_LAM_U48 ++property in input .note.gnu.property section. ++@option{lam-u48-report=none}, which is the default, will make the ++linker not report missing properties in input files. ++@option{lam-u48-report=warning} will make the linker issue a warning for ++missing properties in input files. @option{lam-u48-report=error} will ++make the linker issue an error for missing properties in input files. ++Supported for Linux/x86_64. ++ ++@item lam-u57-report=none ++@itemx lam-u57-report=warning ++@itemx lam-u57-report=error ++Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_LAM_U57 ++property in input .note.gnu.property section. ++@option{lam-u57-report=none}, which is the default, will make the ++linker not report missing properties in input files. ++@option{lam-u57-report=warning} will make the linker issue a warning for ++missing properties in input files. @option{lam-u57-report=error} will ++make the linker issue an error for missing properties in input files. ++Supported for Linux/x86_64. ++ ++@item lam-report=none ++@itemx lam-report=warning ++@itemx lam-report=error ++Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_LAM_U48 and ++GNU_PROPERTY_X86_FEATURE_1_LAM_U57 properties in input .note.gnu.property ++section. @option{lam-report=none}, which is the default, will make the ++linker not report missing properties in input files. ++@option{lam-report=warning} will make the linker issue a warning for ++missing properties in input files. @option{lam-report=error} will make ++the linker issue an error for missing properties in input files. ++Supported for Linux/x86_64. ++ ++@item lazy ++When generating an executable or shared library, mark it to tell the ++dynamic linker to defer function call resolution to the point when ++the function is called (lazy binding), rather than at load time. ++Lazy binding is the default. ++ ++@item loadfltr ++Specify that the object's filters be processed immediately at runtime. ++ ++@item max-page-size=@var{value} ++Set the maximum memory page size supported to @var{value}. ++ ++@item muldefs ++Allow multiple definitions. ++ ++@item nocopyreloc ++Disable linker generated .dynbss variables used in place of variables ++defined in shared libraries. May result in dynamic text relocations. ++ ++@item nodefaultlib ++Specify that the dynamic loader search for dependencies of this object ++should ignore any default library search paths. ++ ++@item nodelete ++Specify that the object shouldn't be unloaded at runtime. ++ ++@item nodlopen ++Specify that the object is not available to @code{dlopen}. ++ ++@item nodump ++Specify that the object can not be dumped by @code{dldump}. ++ ++@item noexecstack ++Marks the object as not requiring executable stack. ++ ++@item noextern-protected-data ++Don't treat protected data symbols as external when building a shared ++library. This option overrides the linker backend default. It can be ++used to work around incorrect relocations against protected data symbols ++generated by compiler. Updates on protected data symbols by another ++module aren't visible to the resulting shared library. Supported for ++i386 and x86-64. ++ ++@item noreloc-overflow ++Disable relocation overflow check. This can be used to disable ++relocation overflow check if there will be no dynamic relocation ++overflow at run-time. Supported for x86_64. ++ ++@item now ++When generating an executable or shared library, mark it to tell the ++dynamic linker to resolve all symbols when the program is started, or ++when the shared library is loaded by dlopen, instead of deferring ++function call resolution to the point when the function is first ++called. ++ ++@item origin ++Specify that the object requires @samp{$ORIGIN} handling in paths. ++ ++@item pack-relative-relocs ++@itemx nopack-relative-relocs ++Generate compact relative relocation in position-independent executable ++and shared library. It adds @code{DT_RELR}, @code{DT_RELRSZ} and ++@code{DT_RELRENT} entries to the dynamic section. It is ignored when ++building position-dependent executable and relocatable output. ++@option{nopack-relative-relocs} is the default, which disables compact ++relative relocation. When linked against the GNU C Library, a ++GLIBC_ABI_DT_RELR symbol version dependency on the shared C Library is ++added to the output. Supported for i386 and x86-64. ++ ++@item relro ++@itemx norelro ++Create an ELF @code{PT_GNU_RELRO} segment header in the object. This ++specifies a memory segment that should be made read-only after ++relocation, if supported. Specifying @samp{common-page-size} smaller ++than the system page size will render this protection ineffective. ++Don't create an ELF @code{PT_GNU_RELRO} segment if @samp{norelro}. ++ ++@item report-relative-reloc ++Report dynamic relative relocations generated by linker. Supported for ++Linux/i386 and Linux/x86_64. ++ ++@item sectionheader ++@itemx nosectionheader ++Generate section header. Don't generate section header if ++@samp{nosectionheader} is used. @option{sectionheader} is the default. ++ ++@item separate-code ++@itemx noseparate-code ++Create separate code @code{PT_LOAD} segment header in the object. This ++specifies a memory segment that should contain only instructions and must ++be in wholly disjoint pages from any other data. Don't create separate ++code @code{PT_LOAD} segment if @samp{noseparate-code} is used. ++ ++@item shstk ++Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK in .note.gnu.property section ++to indicate compatibility with Intel Shadow Stack. Supported for ++Linux/i386 and Linux/x86_64. ++ ++@item stack-size=@var{value} ++Specify a stack size for an ELF @code{PT_GNU_STACK} segment. ++Specifying zero will override any default non-zero sized ++@code{PT_GNU_STACK} segment creation. ++ ++@item start-stop-gc ++@itemx nostart-stop-gc ++@cindex start-stop-gc ++When @samp{--gc-sections} is in effect, a reference from a retained ++section to @code{__start_SECNAME} or @code{__stop_SECNAME} causes all ++input sections named @code{SECNAME} to also be retained, if ++@code{SECNAME} is representable as a C identifier and either ++@code{__start_SECNAME} or @code{__stop_SECNAME} is synthesized by the ++linker. @samp{-z start-stop-gc} disables this effect, allowing ++sections to be garbage collected as if the special synthesized symbols ++were not defined. @samp{-z start-stop-gc} has no effect on a ++definition of @code{__start_SECNAME} or @code{__stop_SECNAME} in an ++object file or linker script. Such a definition will prevent the ++linker providing a synthesized @code{__start_SECNAME} or ++@code{__stop_SECNAME} respectively, and therefore the special ++treatment by garbage collection for those references. ++ ++@item start-stop-visibility=@var{value} ++@cindex visibility ++@cindex ELF symbol visibility ++Specify the ELF symbol visibility for synthesized ++@code{__start_SECNAME} and @code{__stop_SECNAME} symbols (@pxref{Input ++Section Example}). @var{value} must be exactly @samp{default}, ++@samp{internal}, @samp{hidden}, or @samp{protected}. If no @samp{-z ++start-stop-visibility} option is given, @samp{protected} is used for ++compatibility with historical practice. However, it's highly ++recommended to use @samp{-z start-stop-visibility=hidden} in new ++programs and shared libraries so that these symbols are not exported ++between shared objects, which is not usually what's intended. ++ ++@item text ++@itemx notext ++@itemx textoff ++Report an error if DT_TEXTREL is set, i.e., if the position-independent ++or shared object has dynamic relocations in read-only sections. Don't ++report an error if @samp{notext} or @samp{textoff}. ++ ++@item undefs ++Do not report unresolved symbol references from regular object files, ++either when creating an executable, or when creating a shared library. ++This option is the inverse of @samp{-z defs}. ++ ++@item unique-symbol ++@itemx nounique-symbol ++Avoid duplicated local symbol names in the symbol string table. Append ++".@code{number}" to duplicated local symbol names if @samp{unique-symbol} ++is used. @option{nounique-symbol} is the default. ++ ++@item x86-64-baseline ++@item x86-64-v2 ++@item x86-64-v3 ++@itemx x86-64-v4 ++Specify the x86-64 ISA level needed in .note.gnu.property section. ++@option{x86-64-baseline} generates @code{GNU_PROPERTY_X86_ISA_1_BASELINE}. ++@option{x86-64-v2} generates @code{GNU_PROPERTY_X86_ISA_1_V2}. ++@option{x86-64-v3} generates @code{GNU_PROPERTY_X86_ISA_1_V3}. ++@option{x86-64-v4} generates @code{GNU_PROPERTY_X86_ISA_1_V4}. ++Supported for Linux/i386 and Linux/x86_64. ++ ++@end table ++ ++Other keywords are ignored for Solaris compatibility. ++ ++@kindex -( ++@cindex groups of archives ++@item -( @var{archives} -) ++@itemx --start-group @var{archives} --end-group ++The @var{archives} should be a list of archive files. They may be ++either explicit file names, or @samp{-l} options. ++ ++The specified archives are searched repeatedly until no new undefined ++references are created. Normally, an archive is searched only once in ++the order that it is specified on the command line. If a symbol in that ++archive is needed to resolve an undefined symbol referred to by an ++object in an archive that appears later on the command line, the linker ++would not be able to resolve that reference. By grouping the archives, ++they will all be searched repeatedly until all possible references are ++resolved. ++ ++Using this option has a significant performance cost. It is best to use ++it only when there are unavoidable circular references between two or ++more archives. ++ ++@kindex --accept-unknown-input-arch ++@kindex --no-accept-unknown-input-arch ++@item --accept-unknown-input-arch ++@itemx --no-accept-unknown-input-arch ++Tells the linker to accept input files whose architecture cannot be ++recognised. The assumption is that the user knows what they are doing ++and deliberately wants to link in these unknown input files. This was ++the default behaviour of the linker, before release 2.14. The default ++behaviour from release 2.14 onwards is to reject such input files, and ++so the @samp{--accept-unknown-input-arch} option has been added to ++restore the old behaviour. ++ ++@kindex --as-needed ++@kindex --no-as-needed ++@item --as-needed ++@itemx --no-as-needed ++This option affects ELF DT_NEEDED tags for dynamic libraries mentioned ++on the command line after the @option{--as-needed} option. Normally ++the linker will add a DT_NEEDED tag for each dynamic library mentioned ++on the command line, regardless of whether the library is actually ++needed or not. @option{--as-needed} causes a DT_NEEDED tag to only be ++emitted for a library that @emph{at that point in the link} satisfies a ++non-weak undefined symbol reference from a regular object file or, if ++the library is not found in the DT_NEEDED lists of other needed libraries, a ++non-weak undefined symbol reference from another needed dynamic library. ++Object files or libraries appearing on the command line @emph{after} ++the library in question do not affect whether the library is seen as ++needed. This is similar to the rules for extraction of object files ++from archives. @option{--no-as-needed} restores the default behaviour. ++ ++Note: On Linux based systems the @option{--as-needed} option also has ++an affect on the behaviour of the @option{--rpath} and ++@option{--rpath-link} options. See the description of ++@option{--rpath-link} for more details. ++ ++@kindex --add-needed ++@kindex --no-add-needed ++@item --add-needed ++@itemx --no-add-needed ++These two options have been deprecated because of the similarity of ++their names to the @option{--as-needed} and @option{--no-as-needed} ++options. They have been replaced by @option{--copy-dt-needed-entries} ++and @option{--no-copy-dt-needed-entries}. ++ ++@kindex -assert @var{keyword} ++@item -assert @var{keyword} ++This option is ignored for SunOS compatibility. ++ ++@kindex -Bdynamic ++@kindex -dy ++@kindex -call_shared ++@item -Bdynamic ++@itemx -dy ++@itemx -call_shared ++Link against dynamic libraries. This is only meaningful on platforms ++for which shared libraries are supported. This option is normally the ++default on such platforms. The different variants of this option are ++for compatibility with various systems. You may use this option ++multiple times on the command line: it affects library searching for ++@option{-l} options which follow it. ++ ++@kindex -Bgroup ++@item -Bgroup ++Set the @code{DF_1_GROUP} flag in the @code{DT_FLAGS_1} entry in the dynamic ++section. This causes the runtime linker to handle lookups in this ++object and its dependencies to be performed only inside the group. ++@option{--unresolved-symbols=report-all} is implied. This option is ++only meaningful on ELF platforms which support shared libraries. ++ ++@kindex -Bstatic ++@kindex -dn ++@kindex -non_shared ++@kindex -static ++@item -Bstatic ++@itemx -dn ++@itemx -non_shared ++@itemx -static ++Do not link against shared libraries. This is only meaningful on ++platforms for which shared libraries are supported. The different ++variants of this option are for compatibility with various systems. You ++may use this option multiple times on the command line: it affects ++library searching for @option{-l} options which follow it. This ++option also implies @option{--unresolved-symbols=report-all}. This ++option can be used with @option{-shared}. Doing so means that a ++shared library is being created but that all of the library's external ++references must be resolved by pulling in entries from static ++libraries. ++ ++@kindex -Bsymbolic ++@item -Bsymbolic ++When creating a shared library, bind references to global symbols to the ++definition within the shared library, if any. Normally, it is possible ++for a program linked against a shared library to override the definition ++within the shared library. This option is only meaningful on ELF ++platforms which support shared libraries. ++ ++@kindex -Bsymbolic-functions ++@item -Bsymbolic-functions ++When creating a shared library, bind references to global function ++symbols to the definition within the shared library, if any. ++This option is only meaningful on ELF platforms which support shared ++libraries. ++ ++@kindex -Bno-symbolic ++@item -Bno-symbolic ++This option can cancel previously specified @samp{-Bsymbolic} and ++@samp{-Bsymbolic-functions}. ++ ++@kindex --dynamic-list=@var{dynamic-list-file} ++@item --dynamic-list=@var{dynamic-list-file} ++Specify the name of a dynamic list file to the linker. This is ++typically used when creating shared libraries to specify a list of ++global symbols whose references shouldn't be bound to the definition ++within the shared library, or creating dynamically linked executables ++to specify a list of symbols which should be added to the symbol table ++in the executable. This option is only meaningful on ELF platforms ++which support shared libraries. ++ ++The format of the dynamic list is the same as the version node without ++scope and node name. See @ref{VERSION} for more information. ++ ++@kindex --dynamic-list-data ++@item --dynamic-list-data ++Include all global data symbols to the dynamic list. ++ ++@kindex --dynamic-list-cpp-new ++@item --dynamic-list-cpp-new ++Provide the builtin dynamic list for C++ operator new and delete. It ++is mainly useful for building shared libstdc++. ++ ++@kindex --dynamic-list-cpp-typeinfo ++@item --dynamic-list-cpp-typeinfo ++Provide the builtin dynamic list for C++ runtime type identification. ++ ++@kindex --check-sections ++@kindex --no-check-sections ++@item --check-sections ++@itemx --no-check-sections ++Asks the linker @emph{not} to check section addresses after they have ++been assigned to see if there are any overlaps. Normally the linker will ++perform this check, and if it finds any overlaps it will produce ++suitable error messages. The linker does know about, and does make ++allowances for sections in overlays. The default behaviour can be ++restored by using the command-line switch @option{--check-sections}. ++Section overlap is not usually checked for relocatable links. You can ++force checking in that case by using the @option{--check-sections} ++option. ++ ++@kindex --copy-dt-needed-entries ++@kindex --no-copy-dt-needed-entries ++@item --copy-dt-needed-entries ++@itemx --no-copy-dt-needed-entries ++This option affects the treatment of dynamic libraries referred to ++by DT_NEEDED tags @emph{inside} ELF dynamic libraries mentioned on the ++command line. Normally the linker won't add a DT_NEEDED tag to the ++output binary for each library mentioned in a DT_NEEDED tag in an ++input dynamic library. With @option{--copy-dt-needed-entries} ++specified on the command line however any dynamic libraries that ++follow it will have their DT_NEEDED entries added. The default ++behaviour can be restored with @option{--no-copy-dt-needed-entries}. ++ ++This option also has an effect on the resolution of symbols in dynamic ++libraries. With @option{--copy-dt-needed-entries} dynamic libraries ++mentioned on the command line will be recursively searched, following ++their DT_NEEDED tags to other libraries, in order to resolve symbols ++required by the output binary. With the default setting however ++the searching of dynamic libraries that follow it will stop with the ++dynamic library itself. No DT_NEEDED links will be traversed to resolve ++symbols. ++ ++@cindex cross reference table ++@kindex --cref ++@item --cref ++Output a cross reference table. If a linker map file is being ++generated, the cross reference table is printed to the map file. ++Otherwise, it is printed on the standard output. ++ ++The format of the table is intentionally simple, so that it may be ++easily processed by a script if necessary. The symbols are printed out, ++sorted by name. For each symbol, a list of file names is given. If the ++symbol is defined, the first file listed is the location of the ++definition. If the symbol is defined as a common value then any files ++where this happens appear next. Finally any files that reference the ++symbol are listed. ++ ++@cindex ctf variables ++@kindex --ctf-variables ++@kindex --no-ctf-variables ++@item --ctf-variables ++@item --no-ctf-variables ++The CTF debuginfo format supports a section which encodes the names and ++types of variables found in the program which do not appear in any symbol ++table. These variables clearly cannot be looked up by address by ++conventional debuggers, so the space used for their types and names is ++usually wasted: the types are usually small but the names are often not. ++@option{--ctf-variables} causes the generation of such a section. ++The default behaviour can be restored with @option{--no-ctf-variables}. ++ ++@cindex ctf type sharing ++@kindex --ctf-share-types ++@item --ctf-share-types=@var{method} ++Adjust the method used to share types between translation units in CTF. ++ ++@table @samp ++@item share-unconflicted ++Put all types that do not have ambiguous definitions into the shared dictionary, ++where debuggers can easily access them, even if they only occur in one ++translation unit. This is the default. ++ ++@item share-duplicated ++Put only types that occur in multiple translation units into the shared ++dictionary: types with only one definition go into per-translation-unit ++dictionaries. Types with ambiguous definitions in multiple translation units ++always go into per-translation-unit dictionaries. This tends to make the CTF ++larger, but may reduce the amount of CTF in the shared dictionary. For very ++large projects this may speed up opening the CTF and save memory in the CTF ++consumer at runtime. ++@end table ++ ++@cindex common allocation ++@kindex --no-define-common ++@item --no-define-common ++This option inhibits the assignment of addresses to common symbols. ++The script command @code{INHIBIT_COMMON_ALLOCATION} has the same effect. ++@xref{Miscellaneous Commands}. ++ ++The @samp{--no-define-common} option allows decoupling ++the decision to assign addresses to Common symbols from the choice ++of the output file type; otherwise a non-Relocatable output type ++forces assigning addresses to Common symbols. ++Using @samp{--no-define-common} allows Common symbols that are referenced ++from a shared library to be assigned addresses only in the main program. ++This eliminates the unused duplicate space in the shared library, ++and also prevents any possible confusion over resolving to the wrong ++duplicate when there are many dynamic modules with specialized search ++paths for runtime symbol resolution. ++ ++@cindex group allocation in linker script ++@cindex section groups ++@cindex COMDAT ++@kindex --force-group-allocation ++@item --force-group-allocation ++This option causes the linker to place section group members like ++normal input sections, and to delete the section groups. This is the ++default behaviour for a final link but this option can be used to ++change the behaviour of a relocatable link (@samp{-r}). The script ++command @code{FORCE_GROUP_ALLOCATION} has the same ++effect. @xref{Miscellaneous Commands}. ++ ++@cindex symbols, from command line ++@kindex --defsym=@var{symbol}=@var{exp} ++@item --defsym=@var{symbol}=@var{expression} ++Create a global symbol in the output file, containing the absolute ++address given by @var{expression}. You may use this option as many ++times as necessary to define multiple symbols in the command line. A ++limited form of arithmetic is supported for the @var{expression} in this ++context: you may give a hexadecimal constant or the name of an existing ++symbol, or use @code{+} and @code{-} to add or subtract hexadecimal ++constants or symbols. If you need more elaborate expressions, consider ++using the linker command language from a script (@pxref{Assignments}). ++@emph{Note:} there should be no white space between @var{symbol}, the ++equals sign (``@key{=}''), and @var{expression}. ++ ++The linker processes @samp{--defsym} arguments and @samp{-T} arguments ++in order, placing @samp{--defsym} before @samp{-T} will define the ++symbol before the linker script from @samp{-T} is processed, while ++placing @samp{--defsym} after @samp{-T} will define the symbol after ++the linker script has been processed. This difference has ++consequences for expressions within the linker script that use the ++@samp{--defsym} symbols, which order is correct will depend on what ++you are trying to achieve. ++ ++@cindex demangling, from command line ++@kindex --demangle[=@var{style}] ++@kindex --no-demangle ++@item --demangle[=@var{style}] ++@itemx --no-demangle ++These options control whether to demangle symbol names in error messages ++and other output. When the linker is told to demangle, it tries to ++present symbol names in a readable fashion: it strips leading ++underscores if they are used by the object file format, and converts C++ ++mangled symbol names into user readable names. Different compilers have ++different mangling styles. The optional demangling style argument can be used ++to choose an appropriate demangling style for your compiler. The linker will ++demangle by default unless the environment variable @samp{COLLECT_NO_DEMANGLE} ++is set. These options may be used to override the default. ++ ++@cindex dynamic linker, from command line ++@kindex -I@var{file} ++@kindex --dynamic-linker=@var{file} ++@item -I@var{file} ++@itemx --dynamic-linker=@var{file} ++Set the name of the dynamic linker. This is only meaningful when ++generating dynamically linked ELF executables. The default dynamic ++linker is normally correct; don't use this unless you know what you are ++doing. ++ ++@kindex --no-dynamic-linker ++@item --no-dynamic-linker ++When producing an executable file, omit the request for a dynamic ++linker to be used at load-time. This is only meaningful for ELF ++executables that contain dynamic relocations, and usually requires ++entry point code that is capable of processing these relocations. ++ ++@kindex --embedded-relocs ++@item --embedded-relocs ++This option is similar to the @option{--emit-relocs} option except ++that the relocs are stored in a target-specific section. This option ++is only supported by the @samp{BFIN}, @samp{CR16} and @emph{M68K} ++targets. ++ ++@kindex --disable-multiple-abs-defs ++@item --disable-multiple-abs-defs ++Do not allow multiple definitions with symbols included ++in filename invoked by -R or --just-symbols ++ ++@kindex --fatal-warnings ++@kindex --no-fatal-warnings ++@item --fatal-warnings ++@itemx --no-fatal-warnings ++Treat all warnings as errors. The default behaviour can be restored ++with the option @option{--no-fatal-warnings}. ++ ++@kindex -w ++@kindex --no-warnings ++@item -w ++@itemx --no-warnings ++Do not display any warning or error messages. This overrides ++@option{--fatal-warnings} if it has been enabled. This option can be ++used when it is known that the output binary will not work, but there ++is still a need to create it. ++ ++@kindex --force-exe-suffix ++@item --force-exe-suffix ++Make sure that an output file has a .exe suffix. ++ ++If a successfully built fully linked output file does not have a ++@code{.exe} or @code{.dll} suffix, this option forces the linker to copy ++the output file to one of the same name with a @code{.exe} suffix. This ++option is useful when using unmodified Unix makefiles on a Microsoft ++Windows host, since some versions of Windows won't run an image unless ++it ends in a @code{.exe} suffix. ++ ++@kindex --gc-sections ++@kindex --no-gc-sections ++@cindex garbage collection ++@item --gc-sections ++@itemx --no-gc-sections ++Enable garbage collection of unused input sections. It is ignored on ++targets that do not support this option. The default behaviour (of not ++performing this garbage collection) can be restored by specifying ++@samp{--no-gc-sections} on the command line. Note that garbage ++collection for COFF and PE format targets is supported, but the ++implementation is currently considered to be experimental. ++ ++@samp{--gc-sections} decides which input sections are used by ++examining symbols and relocations. The section containing the entry ++symbol and all sections containing symbols undefined on the ++command-line will be kept, as will sections containing symbols ++referenced by dynamic objects. Note that when building shared ++libraries, the linker must assume that any visible symbol is ++referenced. Once this initial set of sections has been determined, ++the linker recursively marks as used any section referenced by their ++relocations. See @samp{--entry}, @samp{--undefined}, and ++@samp{--gc-keep-exported}. ++ ++This option can be set when doing a partial link (enabled with option ++@samp{-r}). In this case the root of symbols kept must be explicitly ++specified either by one of the options @samp{--entry}, ++@samp{--undefined}, or @samp{--gc-keep-exported} or by a @code{ENTRY} ++command in the linker script. ++ ++As a GNU extension, ELF input sections marked with the ++@code{SHF_GNU_RETAIN} flag will not be garbage collected. ++ ++@kindex --print-gc-sections ++@kindex --no-print-gc-sections ++@cindex garbage collection ++@item --print-gc-sections ++@itemx --no-print-gc-sections ++List all sections removed by garbage collection. The listing is ++printed on stderr. This option is only effective if garbage ++collection has been enabled via the @samp{--gc-sections}) option. The ++default behaviour (of not listing the sections that are removed) can ++be restored by specifying @samp{--no-print-gc-sections} on the command ++line. ++ ++@kindex --gc-keep-exported ++@cindex garbage collection ++@item --gc-keep-exported ++When @samp{--gc-sections} is enabled, this option prevents garbage ++collection of unused input sections that contain global symbols having ++default or protected visibility. This option is intended to be used for ++executables where unreferenced sections would otherwise be garbage ++collected regardless of the external visibility of contained symbols. ++Note that this option has no effect when linking shared objects since ++it is already the default behaviour. This option is only supported for ++ELF format targets. ++ ++@kindex --print-output-format ++@cindex output format ++@item --print-output-format ++Print the name of the default output format (perhaps influenced by ++other command-line options). This is the string that would appear ++in an @code{OUTPUT_FORMAT} linker script command (@pxref{File Commands}). ++ ++@kindex --print-memory-usage ++@cindex memory usage ++@item --print-memory-usage ++Print used size, total size and used size of memory regions created with ++the @ref{MEMORY} command. This is useful on embedded targets to have a ++quick view of amount of free memory. The format of the output has one ++headline and one line per region. It is both human readable and easily ++parsable by tools. Here is an example of an output: ++ ++@smallexample ++Memory region Used Size Region Size %age Used ++ ROM: 256 KB 1 MB 25.00% ++ RAM: 32 B 2 GB 0.00% ++@end smallexample ++ ++@cindex help ++@cindex usage ++@kindex --help ++@item --help ++Print a summary of the command-line options on the standard output and exit. ++ ++@kindex --target-help ++@item --target-help ++Print a summary of all target-specific options on the standard output and exit. ++ ++@kindex -Map=@var{mapfile} ++@item -Map=@var{mapfile} ++Print a link map to the file @var{mapfile}. See the description of the ++@option{-M} option, above. If @var{mapfile} is just the character ++@code{-} then the map will be written to stdout. ++ ++Specifying a directory as @var{mapfile} causes the linker map to be ++written as a file inside the directory. Normally name of the file ++inside the directory is computed as the basename of the @var{output} ++file with @code{.map} appended. If however the special character ++@code{%} is used then this will be replaced by the full path of the ++output file. Additionally if there are any characters after the ++@var{%} symbol then @code{.map} will no longer be appended. ++ ++@smallexample ++ -o foo.exe -Map=bar [Creates ./bar] ++ -o ../dir/foo.exe -Map=bar [Creates ./bar] ++ -o foo.exe -Map=../dir [Creates ../dir/foo.exe.map] ++ -o ../dir2/foo.exe -Map=../dir [Creates ../dir/foo.exe.map] ++ -o foo.exe -Map=% [Creates ./foo.exe.map] ++ -o ../dir/foo.exe -Map=% [Creates ../dir/foo.exe.map] ++ -o foo.exe -Map=%.bar [Creates ./foo.exe.bar] ++ -o ../dir/foo.exe -Map=%.bar [Creates ../dir/foo.exe.bar] ++ -o ../dir2/foo.exe -Map=../dir/% [Creates ../dir/../dir2/foo.exe.map] ++ -o ../dir2/foo.exe -Map=../dir/%.bar [Creates ../dir/../dir2/foo.exe.bar] ++@end smallexample ++ ++It is an error to specify more than one @code{%} character. ++ ++If the map file already exists then it will be overwritten by this ++operation. ++ ++@cindex memory usage ++@kindex --no-keep-memory ++@item --no-keep-memory ++@command{ld} normally optimizes for speed over memory usage by caching the ++symbol tables of input files in memory. This option tells @command{ld} to ++instead optimize for memory usage, by rereading the symbol tables as ++necessary. This may be required if @command{ld} runs out of memory space ++while linking a large executable. ++ ++@kindex --no-undefined ++@kindex -z defs ++@kindex -z undefs ++@item --no-undefined ++@itemx -z defs ++Report unresolved symbol references from regular object files. This ++is done even if the linker is creating a non-symbolic shared library. ++The switch @option{--[no-]allow-shlib-undefined} controls the ++behaviour for reporting unresolved references found in shared ++libraries being linked in. ++ ++The effects of this option can be reverted by using @code{-z undefs}. ++ ++@kindex --allow-multiple-definition ++@kindex -z muldefs ++@item --allow-multiple-definition ++@itemx -z muldefs ++Normally when a symbol is defined multiple times, the linker will ++report a fatal error. These options allow multiple definitions and the ++first definition will be used. ++ ++@kindex --allow-shlib-undefined ++@kindex --no-allow-shlib-undefined ++@item --allow-shlib-undefined ++@itemx --no-allow-shlib-undefined ++Allows or disallows undefined symbols in shared libraries. ++This switch is similar to @option{--no-undefined} except that it ++determines the behaviour when the undefined symbols are in a ++shared library rather than a regular object file. It does not affect ++how undefined symbols in regular object files are handled. ++ ++The default behaviour is to report errors for any undefined symbols ++referenced in shared libraries if the linker is being used to create ++an executable, but to allow them if the linker is being used to create ++a shared library. ++ ++The reasons for allowing undefined symbol references in shared ++libraries specified at link time are that: ++ ++@itemize @bullet ++@item ++A shared library specified at link time may not be the same as the one ++that is available at load time, so the symbol might actually be ++resolvable at load time. ++@item ++There are some operating systems, eg BeOS and HPPA, where undefined ++symbols in shared libraries are normal. ++ ++The BeOS kernel for example patches shared libraries at load time to ++select whichever function is most appropriate for the current ++architecture. This is used, for example, to dynamically select an ++appropriate memset function. ++@end itemize ++ ++@kindex --error-handling-script=@var{scriptname} ++@item --error-handling-script=@var{scriptname} ++If this option is provided then the linker will invoke ++@var{scriptname} whenever an error is encountered. Currently however ++only two kinds of error are supported: missing symbols and missing ++libraries. Two arguments will be passed to script: the keyword ++``undefined-symbol'' or `missing-lib'' and the @var{name} of the ++undefined symbol or missing library. The intention is that the script ++will provide suggestions to the user as to where the symbol or library ++might be found. After the script has finished then the normal linker ++error message will be displayed. ++ ++The availability of this option is controlled by a configure time ++switch, so it may not be present in specific implementations. ++ ++@kindex --no-undefined-version ++@item --no-undefined-version ++Normally when a symbol has an undefined version, the linker will ignore ++it. This option disallows symbols with undefined version and a fatal error ++will be issued instead. ++ ++@kindex --default-symver ++@item --default-symver ++Create and use a default symbol version (the soname) for unversioned ++exported symbols. ++ ++@kindex --default-imported-symver ++@item --default-imported-symver ++Create and use a default symbol version (the soname) for unversioned ++imported symbols. ++ ++@kindex --no-warn-mismatch ++@item --no-warn-mismatch ++Normally @command{ld} will give an error if you try to link together input ++files that are mismatched for some reason, perhaps because they have ++been compiled for different processors or for different endiannesses. ++This option tells @command{ld} that it should silently permit such possible ++errors. This option should only be used with care, in cases when you ++have taken some special action that ensures that the linker errors are ++inappropriate. ++ ++@kindex --no-warn-search-mismatch ++@item --no-warn-search-mismatch ++Normally @command{ld} will give a warning if it finds an incompatible ++library during a library search. This option silences the warning. ++ ++@kindex --no-whole-archive ++@item --no-whole-archive ++Turn off the effect of the @option{--whole-archive} option for subsequent ++archive files. ++ ++@cindex output file after errors ++@kindex --noinhibit-exec ++@item --noinhibit-exec ++Retain the executable output file whenever it is still usable. ++Normally, the linker will not produce an output file if it encounters ++errors during the link process; it exits without writing an output file ++when it issues any error whatsoever. ++ ++@kindex -nostdlib ++@item -nostdlib ++Only search library directories explicitly specified on the ++command line. Library directories specified in linker scripts ++(including linker scripts specified on the command line) are ignored. ++ ++@ifclear SingleFormat ++@kindex --oformat=@var{output-format} ++@item --oformat=@var{output-format} ++@command{ld} may be configured to support more than one kind of object ++file. If your @command{ld} is configured this way, you can use the ++@samp{--oformat} option to specify the binary format for the output ++object file. Even when @command{ld} is configured to support alternative ++object formats, you don't usually need to specify this, as @command{ld} ++should be configured to produce as a default output format the most ++usual format on each machine. @var{output-format} is a text string, the ++name of a particular format supported by the BFD libraries. (You can ++list the available binary formats with @samp{objdump -i}.) The script ++command @code{OUTPUT_FORMAT} can also specify the output format, but ++this option overrides it. @xref{BFD}. ++@end ifclear ++ ++@kindex --out-implib ++@item --out-implib @var{file} ++Create an import library in @var{file} corresponding to the executable ++the linker is generating (eg. a DLL or ELF program). This import ++library (which should be called @code{*.dll.a} or @code{*.a} for DLLs) ++may be used to link clients against the generated executable; this ++behaviour makes it possible to skip a separate import library creation ++step (eg. @code{dlltool} for DLLs). This option is only available for ++the i386 PE and ELF targetted ports of the linker. ++ ++@kindex -pie ++@kindex --pic-executable ++@item -pie ++@itemx --pic-executable ++@cindex position independent executables ++Create a position independent executable. This is currently only supported on ++ELF platforms. Position independent executables are similar to shared ++libraries in that they are relocated by the dynamic linker to the virtual ++address the OS chooses for them (which can vary between invocations). Like ++normal dynamically linked executables they can be executed and symbols ++defined in the executable cannot be overridden by shared libraries. ++ ++@kindex -no-pie ++@item -no-pie ++@cindex position dependent executables ++Create a position dependent executable. This is the default. ++ ++@kindex -qmagic ++@item -qmagic ++This option is ignored for Linux compatibility. ++ ++@kindex -Qy ++@item -Qy ++This option is ignored for SVR4 compatibility. ++ ++@kindex --relax ++@cindex synthesizing linker ++@cindex relaxing addressing modes ++@cindex --no-relax ++@item --relax ++@itemx --no-relax ++An option with machine dependent effects. ++@ifset GENERIC ++This option is only supported on a few targets. ++@end ifset ++@ifset H8300 ++@xref{H8/300,,@command{ld} and the H8/300}. ++@end ifset ++@ifset XTENSA ++@xref{Xtensa,, @command{ld} and Xtensa Processors}. ++@end ifset ++@ifset M68HC11 ++@xref{M68HC11/68HC12,,@command{ld} and the 68HC11 and 68HC12}. ++@end ifset ++@ifset NIOSII ++@xref{Nios II,,@command{ld} and the Altera Nios II}. ++@end ifset ++@ifset POWERPC ++@xref{PowerPC ELF32,,@command{ld} and PowerPC 32-bit ELF Support}. ++@end ifset ++ ++On some platforms the @option{--relax} option performs target specific, ++global optimizations that become possible when the linker resolves ++addressing in the program, such as relaxing address modes, ++synthesizing new instructions, selecting shorter version of current ++instructions, and combining constant values. ++ ++On some platforms these link time global optimizations may make symbolic ++debugging of the resulting executable impossible. ++@ifset GENERIC ++This is known to be the case for the Matsushita MN10200 and MN10300 ++family of processors. ++@end ifset ++ ++On platforms where the feature is supported, the option ++@option{--no-relax} will disable it. ++ ++On platforms where the feature is not supported, both @option{--relax} ++and @option{--no-relax} are accepted, but ignored. ++ ++@cindex retaining specified symbols ++@cindex stripping all but some symbols ++@cindex symbols, retaining selectively ++@kindex --retain-symbols-file=@var{filename} ++@item --retain-symbols-file=@var{filename} ++Retain @emph{only} the symbols listed in the file @var{filename}, ++discarding all others. @var{filename} is simply a flat file, with one ++symbol name per line. This option is especially useful in environments ++@ifset GENERIC ++(such as VxWorks) ++@end ifset ++where a large global symbol table is accumulated gradually, to conserve ++run-time memory. ++ ++@samp{--retain-symbols-file} does @emph{not} discard undefined symbols, ++or symbols needed for relocations. ++ ++You may only specify @samp{--retain-symbols-file} once in the command ++line. It overrides @samp{-s} and @samp{-S}. ++ ++@ifset GENERIC ++@item -rpath=@var{dir} ++@cindex runtime library search path ++@kindex -rpath=@var{dir} ++Add a directory to the runtime library search path. This is used when ++linking an ELF executable with shared objects. All @option{-rpath} ++arguments are concatenated and passed to the runtime linker, which uses ++them to locate shared objects at runtime. ++ ++The @option{-rpath} option is also used when locating shared objects which ++are needed by shared objects explicitly included in the link; see the ++description of the @option{-rpath-link} option. Searching @option{-rpath} ++in this way is only supported by native linkers and cross linkers which ++have been configured with the @option{--with-sysroot} option. ++ ++If @option{-rpath} is not used when linking an ELF executable, the ++contents of the environment variable @code{LD_RUN_PATH} will be used if it ++is defined. ++ ++The @option{-rpath} option may also be used on SunOS. By default, on ++SunOS, the linker will form a runtime search path out of all the ++@option{-L} options it is given. If a @option{-rpath} option is used, the ++runtime search path will be formed exclusively using the @option{-rpath} ++options, ignoring the @option{-L} options. This can be useful when using ++gcc, which adds many @option{-L} options which may be on NFS mounted ++file systems. ++ ++For compatibility with other ELF linkers, if the @option{-R} option is ++followed by a directory name, rather than a file name, it is treated as ++the @option{-rpath} option. ++@end ifset ++ ++@ifset GENERIC ++@cindex link-time runtime library search path ++@kindex -rpath-link=@var{dir} ++@item -rpath-link=@var{dir} ++When using ELF or SunOS, one shared library may require another. This ++happens when an @code{ld -shared} link includes a shared library as one ++of the input files. ++ ++When the linker encounters such a dependency when doing a non-shared, ++non-relocatable link, it will automatically try to locate the required ++shared library and include it in the link, if it is not included ++explicitly. In such a case, the @option{-rpath-link} option ++specifies the first set of directories to search. The ++@option{-rpath-link} option may specify a sequence of directory names ++either by specifying a list of names separated by colons, or by ++appearing multiple times. ++ ++The tokens @var{$ORIGIN} and @var{$LIB} can appear in these search ++directories. They will be replaced by the full path to the directory ++containing the program or shared object in the case of @var{$ORIGIN} ++and either @samp{lib} - for 32-bit binaries - or @samp{lib64} - for ++64-bit binaries - in the case of @var{$LIB}. ++ ++The alternative form of these tokens - @var{$@{ORIGIN@}} and ++@var{$@{LIB@}} can also be used. The token @var{$PLATFORM} is not ++supported. ++ ++This option should be used with caution as it overrides the search path ++that may have been hard compiled into a shared library. In such a case it ++is possible to use unintentionally a different search path than the ++runtime linker would do. ++ ++The linker uses the following search paths to locate required shared ++libraries: ++ ++@enumerate ++@item ++Any directories specified by @option{-rpath-link} options. ++@item ++Any directories specified by @option{-rpath} options. The difference ++between @option{-rpath} and @option{-rpath-link} is that directories ++specified by @option{-rpath} options are included in the executable and ++used at runtime, whereas the @option{-rpath-link} option is only effective ++at link time. Searching @option{-rpath} in this way is only supported ++by native linkers and cross linkers which have been configured with ++the @option{--with-sysroot} option. ++@item ++On an ELF system, for native linkers, if the @option{-rpath} and ++@option{-rpath-link} options were not used, search the contents of the ++environment variable @code{LD_RUN_PATH}. ++@item ++On SunOS, if the @option{-rpath} option was not used, search any ++directories specified using @option{-L} options. ++@item ++For a native linker, search the contents of the environment ++variable @code{LD_LIBRARY_PATH}. ++@item ++For a native ELF linker, the directories in @code{DT_RUNPATH} or ++@code{DT_RPATH} of a shared library are searched for shared ++libraries needed by it. The @code{DT_RPATH} entries are ignored if ++@code{DT_RUNPATH} entries exist. ++@item ++For a linker for a Linux system, if the file @file{/etc/ld.so.conf} ++exists, the list of directories found in that file. Note: the path ++to this file is prefixed with the @code{sysroot} value, if that is ++defined, and then any @code{prefix} string if the linker was ++configured with the @command{--prefix=} option. ++@item ++For a native linker on a FreeBSD system, any directories specified by ++the @code{_PATH_ELF_HINTS} macro defined in the @file{elf-hints.h} ++header file. ++@item ++Any directories specified by a @code{SEARCH_DIR} command in a ++linker script given on the command line, including scripts specified ++by @option{-T} (but not @option{-dT}). ++@item ++The default directories, normally @file{/lib} and @file{/usr/lib}. ++@item ++Any directories specified by a plugin LDPT_SET_EXTRA_LIBRARY_PATH. ++@item ++Any directories specified by a @code{SEARCH_DIR} command in a default ++linker script. ++@end enumerate ++ ++Note however on Linux based systems there is an additional caveat: If ++the @option{--as-needed} option is active @emph{and} a shared library ++is located which would normally satisfy the search @emph{and} this ++library does not have DT_NEEDED tag for @file{libc.so} ++@emph{and} there is a shared library later on in the set of search ++directories which also satisfies the search @emph{and} ++this second shared library does have a DT_NEEDED tag for ++@file{libc.so} @emph{then} the second library will be selected instead ++of the first. ++ ++If the required shared library is not found, the linker will issue a ++warning and continue with the link. ++ ++@end ifset ++ ++@kindex -shared ++@kindex -Bshareable ++@item -shared ++@itemx -Bshareable ++@cindex shared libraries ++Create a shared library. This is currently only supported on ELF, XCOFF ++and SunOS platforms. On SunOS, the linker will automatically create a ++shared library if the @option{-e} option is not used and there are ++undefined symbols in the link. ++ ++@kindex --sort-common ++@item --sort-common ++@itemx --sort-common=ascending ++@itemx --sort-common=descending ++This option tells @command{ld} to sort the common symbols by alignment in ++ascending or descending order when it places them in the appropriate output ++sections. The symbol alignments considered are sixteen-byte or larger, ++eight-byte, four-byte, two-byte, and one-byte. This is to prevent gaps ++between symbols due to alignment constraints. If no sorting order is ++specified, then descending order is assumed. ++ ++@kindex --sort-section=name ++@item --sort-section=name ++This option will apply @code{SORT_BY_NAME} to all wildcard section ++patterns in the linker script. ++ ++@kindex --sort-section=alignment ++@item --sort-section=alignment ++This option will apply @code{SORT_BY_ALIGNMENT} to all wildcard section ++patterns in the linker script. ++ ++@kindex --spare-dynamic-tags ++@item --spare-dynamic-tags=@var{count} ++This option specifies the number of empty slots to leave in the ++.dynamic section of ELF shared objects. Empty slots may be needed by ++post processing tools, such as the prelinker. The default is 5. ++ ++@kindex --split-by-file ++@item --split-by-file[=@var{size}] ++Similar to @option{--split-by-reloc} but creates a new output section for ++each input file when @var{size} is reached. @var{size} defaults to a ++size of 1 if not given. ++ ++@kindex --split-by-reloc ++@item --split-by-reloc[=@var{count}] ++Tries to creates extra sections in the output file so that no single ++output section in the file contains more than @var{count} relocations. ++This is useful when generating huge relocatable files for downloading into ++certain real time kernels with the COFF object file format; since COFF ++cannot represent more than 65535 relocations in a single section. Note ++that this will fail to work with object file formats which do not ++support arbitrary sections. The linker will not split up individual ++input sections for redistribution, so if a single input section contains ++more than @var{count} relocations one output section will contain that ++many relocations. @var{count} defaults to a value of 32768. ++ ++@kindex --stats ++@item --stats ++Compute and display statistics about the operation of the linker, such ++as execution time and memory usage. ++ ++@kindex --sysroot=@var{directory} ++@item --sysroot=@var{directory} ++Use @var{directory} as the location of the sysroot, overriding the ++configure-time default. This option is only supported by linkers ++that were configured using @option{--with-sysroot}. ++ ++@kindex --task-link ++@item --task-link ++This is used by COFF/PE based targets to create a task-linked object ++file where all of the global symbols have been converted to statics. ++ ++@kindex --traditional-format ++@cindex traditional format ++@item --traditional-format ++For some targets, the output of @command{ld} is different in some ways from ++the output of some existing linker. This switch requests @command{ld} to ++use the traditional format instead. ++ ++@cindex dbx ++For example, on SunOS, @command{ld} combines duplicate entries in the ++symbol string table. This can reduce the size of an output file with ++full debugging information by over 30 percent. Unfortunately, the SunOS ++@code{dbx} program can not read the resulting program (@code{gdb} has no ++trouble). The @samp{--traditional-format} switch tells @command{ld} to not ++combine duplicate entries. ++ ++@kindex --section-start=@var{sectionname}=@var{org} ++@item --section-start=@var{sectionname}=@var{org} ++Locate a section in the output file at the absolute ++address given by @var{org}. You may use this option as many ++times as necessary to locate multiple sections in the command ++line. ++@var{org} must be a single hexadecimal integer; ++for compatibility with other linkers, you may omit the leading ++@samp{0x} usually associated with hexadecimal values. @emph{Note:} there ++should be no white space between @var{sectionname}, the equals ++sign (``@key{=}''), and @var{org}. ++ ++@kindex -Tbss=@var{org} ++@kindex -Tdata=@var{org} ++@kindex -Ttext=@var{org} ++@cindex segment origins, cmd line ++@item -Tbss=@var{org} ++@itemx -Tdata=@var{org} ++@itemx -Ttext=@var{org} ++Same as @option{--section-start}, with @code{.bss}, @code{.data} or ++@code{.text} as the @var{sectionname}. ++ ++@kindex -Ttext-segment=@var{org} ++@item -Ttext-segment=@var{org} ++@cindex text segment origin, cmd line ++When creating an ELF executable, it will set the address of the first ++byte of the text segment. ++ ++@kindex -Trodata-segment=@var{org} ++@item -Trodata-segment=@var{org} ++@cindex rodata segment origin, cmd line ++When creating an ELF executable or shared object for a target where ++the read-only data is in its own segment separate from the executable ++text, it will set the address of the first byte of the read-only data segment. ++ ++@kindex -Tldata-segment=@var{org} ++@item -Tldata-segment=@var{org} ++@cindex ldata segment origin, cmd line ++When creating an ELF executable or shared object for x86-64 medium memory ++model, it will set the address of the first byte of the ldata segment. ++ ++@kindex --unresolved-symbols ++@item --unresolved-symbols=@var{method} ++Determine how to handle unresolved symbols. There are four possible ++values for @samp{method}: ++ ++@table @samp ++@item ignore-all ++Do not report any unresolved symbols. ++ ++@item report-all ++Report all unresolved symbols. This is the default. ++ ++@item ignore-in-object-files ++Report unresolved symbols that are contained in shared libraries, but ++ignore them if they come from regular object files. ++ ++@item ignore-in-shared-libs ++Report unresolved symbols that come from regular object files, but ++ignore them if they come from shared libraries. This can be useful ++when creating a dynamic binary and it is known that all the shared ++libraries that it should be referencing are included on the linker's ++command line. ++@end table ++ ++The behaviour for shared libraries on their own can also be controlled ++by the @option{--[no-]allow-shlib-undefined} option. ++ ++Normally the linker will generate an error message for each reported ++unresolved symbol but the option @option{--warn-unresolved-symbols} ++can change this to a warning. ++ ++@kindex --verbose[=@var{NUMBER}] ++@cindex verbose[=@var{NUMBER}] ++@item --dll-verbose ++@itemx --verbose[=@var{NUMBER}] ++Display the version number for @command{ld} and list the linker emulations ++supported. Display which input files can and cannot be opened. Display ++the linker script being used by the linker. If the optional @var{NUMBER} ++argument > 1, plugin symbol status will also be displayed. ++ ++@kindex --version-script=@var{version-scriptfile} ++@cindex version script, symbol versions ++@item --version-script=@var{version-scriptfile} ++Specify the name of a version script to the linker. This is typically ++used when creating shared libraries to specify additional information ++about the version hierarchy for the library being created. This option ++is only fully supported on ELF platforms which support shared libraries; ++see @ref{VERSION}. It is partially supported on PE platforms, which can ++use version scripts to filter symbol visibility in auto-export mode: any ++symbols marked @samp{local} in the version script will not be exported. ++@xref{WIN32}. ++ ++@kindex --warn-common ++@cindex warnings, on combining symbols ++@cindex combining symbols, warnings on ++@item --warn-common ++Warn when a common symbol is combined with another common symbol or with ++a symbol definition. Unix linkers allow this somewhat sloppy practice, ++but linkers on some other operating systems do not. This option allows ++you to find potential problems from combining global symbols. ++Unfortunately, some C libraries use this practice, so you may get some ++warnings about symbols in the libraries as well as in your programs. ++ ++There are three kinds of global symbols, illustrated here by C examples: ++ ++@table @samp ++@item int i = 1; ++A definition, which goes in the initialized data section of the output ++file. ++ ++@item extern int i; ++An undefined reference, which does not allocate space. ++There must be either a definition or a common symbol for the ++variable somewhere. ++ ++@item int i; ++A common symbol. If there are only (one or more) common symbols for a ++variable, it goes in the uninitialized data area of the output file. ++The linker merges multiple common symbols for the same variable into a ++single symbol. If they are of different sizes, it picks the largest ++size. The linker turns a common symbol into a declaration, if there is ++a definition of the same variable. ++@end table ++ ++The @samp{--warn-common} option can produce five kinds of warnings. ++Each warning consists of a pair of lines: the first describes the symbol ++just encountered, and the second describes the previous symbol ++encountered with the same name. One or both of the two symbols will be ++a common symbol. ++ ++@enumerate ++@item ++Turning a common symbol into a reference, because there is already a ++definition for the symbol. ++@smallexample ++@var{file}(@var{section}): warning: common of `@var{symbol}' ++ overridden by definition ++@var{file}(@var{section}): warning: defined here ++@end smallexample ++ ++@item ++Turning a common symbol into a reference, because a later definition for ++the symbol is encountered. This is the same as the previous case, ++except that the symbols are encountered in a different order. ++@smallexample ++@var{file}(@var{section}): warning: definition of `@var{symbol}' ++ overriding common ++@var{file}(@var{section}): warning: common is here ++@end smallexample ++ ++@item ++Merging a common symbol with a previous same-sized common symbol. ++@smallexample ++@var{file}(@var{section}): warning: multiple common ++ of `@var{symbol}' ++@var{file}(@var{section}): warning: previous common is here ++@end smallexample ++ ++@item ++Merging a common symbol with a previous larger common symbol. ++@smallexample ++@var{file}(@var{section}): warning: common of `@var{symbol}' ++ overridden by larger common ++@var{file}(@var{section}): warning: larger common is here ++@end smallexample ++ ++@item ++Merging a common symbol with a previous smaller common symbol. This is ++the same as the previous case, except that the symbols are ++encountered in a different order. ++@smallexample ++@var{file}(@var{section}): warning: common of `@var{symbol}' ++ overriding smaller common ++@var{file}(@var{section}): warning: smaller common is here ++@end smallexample ++@end enumerate ++ ++@kindex --warn-constructors ++@item --warn-constructors ++Warn if any global constructors are used. This is only useful for a few ++object file formats. For formats like COFF or ELF, the linker can not ++detect the use of global constructors. ++ ++@kindex --warn-execstack ++@cindex warnings, on executable stack ++@cindex executable stack, warnings on ++@item --warn-execstack ++@itemx --no-warn-execstack ++On ELF platforms this option controls how the linker generates warning ++messages when it creates an output file with an executable stack. By ++default the linker will not warn if the @command{-z execstack} command ++line option has been used, but this behaviour can be overridden by the ++@option{--warn-execstack} option. ++ ++On the other hand the linker will normally warn if the stack is made ++executable because one or more of the input files need an execuable ++stack and neither of the @command{-z execstack} or @command{-z ++noexecstack} command line options have been specified. This warning ++can be disabled via the @command{--no-warn-execstack} option. ++ ++Note: ELF format input files specify that they need an executable ++stack by having a @var{.note.GNU-stack} section with the executable ++bit set in its section flags. They can specify that they do not need ++an executable stack by having that section, but without the executable ++flag bit set. If an input file does not have a @var{.note.GNU-stack} ++section present then the default behaviour is target specific. For ++some targets, then absence of such a section implies that an ++executable stack @emph{is} required. This is often a problem for hand ++crafted assembler files. ++ ++@kindex --warn-multiple-gp ++@item --warn-multiple-gp ++Warn if multiple global pointer values are required in the output file. ++This is only meaningful for certain processors, such as the Alpha. ++Specifically, some processors put large-valued constants in a special ++section. A special register (the global pointer) points into the middle ++of this section, so that constants can be loaded efficiently via a ++base-register relative addressing mode. Since the offset in ++base-register relative mode is fixed and relatively small (e.g., 16 ++bits), this limits the maximum size of the constant pool. Thus, in ++large programs, it is often necessary to use multiple global pointer ++values in order to be able to address all possible constants. This ++option causes a warning to be issued whenever this case occurs. ++ ++@kindex --warn-once ++@cindex warnings, on undefined symbols ++@cindex undefined symbols, warnings on ++@item --warn-once ++Only warn once for each undefined symbol, rather than once per module ++which refers to it. ++ ++@kindex --warn-rwx-segments ++@cindex warnings, on writeable and exectuable segments ++@cindex executable segments, warnings on ++@item --warn-rwx-segments ++@itemx --no-warn-rwx-segments ++Warn if the linker creates a loadable, non-zero sized segment that has ++all three of the read, write and execute permission flags set. Such a ++segment represents a potential security vulnerability. In addition ++warnings will be generated if a thread local storage segment is ++created with the execute permission flag set, regardless of whether or ++not it has the read and/or write flags set. ++ ++These warnings are enabled by default. They can be disabled via the ++@option{--no-warn-rwx-segments} option and re-enabled via the ++@option{--warn-rwx-segments} option. ++ ++@kindex --warn-section-align ++@cindex warnings, on section alignment ++@cindex section alignment, warnings on ++@item --warn-section-align ++Warn if the address of an output section is changed because of ++alignment. Typically, the alignment will be set by an input section. ++The address will only be changed if it not explicitly specified; that ++is, if the @code{SECTIONS} command does not specify a start address for ++the section (@pxref{SECTIONS}). ++ ++@kindex --warn-textrel ++@item --warn-textrel ++Warn if the linker adds DT_TEXTREL to a position-independent executable ++or shared object. ++ ++@kindex --warn-alternate-em ++@item --warn-alternate-em ++Warn if an object has alternate ELF machine code. ++ ++@kindex --warn-unresolved-symbols ++@item --warn-unresolved-symbols ++If the linker is going to report an unresolved symbol (see the option ++@option{--unresolved-symbols}) it will normally generate an error. ++This option makes it generate a warning instead. ++ ++@kindex --error-unresolved-symbols ++@item --error-unresolved-symbols ++This restores the linker's default behaviour of generating errors when ++it is reporting unresolved symbols. ++ ++@kindex --whole-archive ++@cindex including an entire archive ++@item --whole-archive ++For each archive mentioned on the command line after the ++@option{--whole-archive} option, include every object file in the archive ++in the link, rather than searching the archive for the required object ++files. This is normally used to turn an archive file into a shared ++library, forcing every object to be included in the resulting shared ++library. This option may be used more than once. ++ ++Two notes when using this option from gcc: First, gcc doesn't know ++about this option, so you have to use @option{-Wl,-whole-archive}. ++Second, don't forget to use @option{-Wl,-no-whole-archive} after your ++list of archives, because gcc will add its own list of archives to ++your link and you may not want this flag to affect those as well. ++ ++@kindex --wrap=@var{symbol} ++@item --wrap=@var{symbol} ++Use a wrapper function for @var{symbol}. Any undefined reference to ++@var{symbol} will be resolved to @code{__wrap_@var{symbol}}. Any ++undefined reference to @code{__real_@var{symbol}} will be resolved to ++@var{symbol}. ++ ++This can be used to provide a wrapper for a system function. The ++wrapper function should be called @code{__wrap_@var{symbol}}. If it ++wishes to call the system function, it should call ++@code{__real_@var{symbol}}. ++ ++Here is a trivial example: ++ ++@smallexample ++void * ++__wrap_malloc (size_t c) ++@{ ++ printf ("malloc called with %zu\n", c); ++ return __real_malloc (c); ++@} ++@end smallexample ++ ++If you link other code with this file using @option{--wrap malloc}, then ++all calls to @code{malloc} will call the function @code{__wrap_malloc} ++instead. The call to @code{__real_malloc} in @code{__wrap_malloc} will ++call the real @code{malloc} function. ++ ++You may wish to provide a @code{__real_malloc} function as well, so that ++links without the @option{--wrap} option will succeed. If you do this, ++you should not put the definition of @code{__real_malloc} in the same ++file as @code{__wrap_malloc}; if you do, the assembler may resolve the ++call before the linker has a chance to wrap it to @code{malloc}. ++ ++Only undefined references are replaced by the linker. So, translation unit ++internal references to @var{symbol} are not resolved to ++@code{__wrap_@var{symbol}}. In the next example, the call to @code{f} in ++@code{g} is not resolved to @code{__wrap_f}. ++ ++@smallexample ++int ++f (void) ++@{ ++ return 123; ++@} ++ ++int ++g (void) ++@{ ++ return f(); ++@} ++@end smallexample ++ ++@kindex --eh-frame-hdr ++@kindex --no-eh-frame-hdr ++@item --eh-frame-hdr ++@itemx --no-eh-frame-hdr ++Request (@option{--eh-frame-hdr}) or suppress ++(@option{--no-eh-frame-hdr}) the creation of @code{.eh_frame_hdr} ++section and ELF @code{PT_GNU_EH_FRAME} segment header. ++ ++@kindex --ld-generated-unwind-info ++@item --no-ld-generated-unwind-info ++Request creation of @code{.eh_frame} unwind info for linker ++generated code sections like PLT. This option is on by default ++if linker generated unwind info is supported. This option also ++controls the generation of @code{.sframe} stack trace info for linker ++generated code sections like PLT. ++ ++@kindex --enable-new-dtags ++@kindex --disable-new-dtags ++@item --enable-new-dtags ++@itemx --disable-new-dtags ++This linker can create the new dynamic tags in ELF. But the older ELF ++systems may not understand them. If you specify ++@option{--enable-new-dtags}, the new dynamic tags will be created as needed ++and older dynamic tags will be omitted. ++If you specify @option{--disable-new-dtags}, no new dynamic tags will be ++created. By default, the new dynamic tags are created. Note that ++those options are only available for ELF systems. ++ ++@kindex --hash-size=@var{number} ++@item --hash-size=@var{number} ++Set the default size of the linker's hash tables to a prime number ++close to @var{number}. Increasing this value can reduce the length of ++time it takes the linker to perform its tasks, at the expense of ++increasing the linker's memory requirements. Similarly reducing this ++value can reduce the memory requirements at the expense of speed. ++ ++@kindex --hash-style=@var{style} ++@item --hash-style=@var{style} ++Set the type of linker's hash table(s). @var{style} can be either ++@code{sysv} for classic ELF @code{.hash} section, @code{gnu} for ++new style GNU @code{.gnu.hash} section or @code{both} for both ++the classic ELF @code{.hash} and new style GNU @code{.gnu.hash} ++hash tables. The default depends upon how the linker was configured, ++but for most Linux based systems it will be @code{both}. ++ ++@kindex --compress-debug-sections=none ++@kindex --compress-debug-sections=zlib ++@kindex --compress-debug-sections=zlib-gnu ++@kindex --compress-debug-sections=zlib-gabi ++@kindex --compress-debug-sections=zstd ++@item --compress-debug-sections=none ++@itemx --compress-debug-sections=zlib ++@itemx --compress-debug-sections=zlib-gnu ++@itemx --compress-debug-sections=zlib-gabi ++@itemx --compress-debug-sections=zstd ++On ELF platforms, these options control how DWARF debug sections are ++compressed using zlib. ++ ++@option{--compress-debug-sections=none} doesn't compress DWARF debug ++sections. @option{--compress-debug-sections=zlib-gnu} compresses ++DWARF debug sections and renames them to begin with @samp{.zdebug} ++instead of @samp{.debug}. @option{--compress-debug-sections=zlib-gabi} ++also compresses DWARF debug sections, but rather than renaming them it ++sets the SHF_COMPRESSED flag in the sections' headers. ++ ++The @option{--compress-debug-sections=zlib} option is an alias for ++@option{--compress-debug-sections=zlib-gabi}. ++ ++@option{--compress-debug-sections=zstd} compresses DWARF debug sections using ++zstd. ++ ++Note that this option overrides any compression in input debug ++sections, so if a binary is linked with @option{--compress-debug-sections=none} ++for example, then any compressed debug sections in input files will be ++uncompressed before they are copied into the output binary. ++ ++The default compression behaviour varies depending upon the target ++involved and the configure options used to build the toolchain. The ++default can be determined by examining the output from the linker's ++@option{--help} option. ++ ++@kindex --reduce-memory-overheads ++@item --reduce-memory-overheads ++This option reduces memory requirements at ld runtime, at the expense of ++linking speed. This was introduced to select the old O(n^2) algorithm ++for link map file generation, rather than the new O(n) algorithm which uses ++about 40% more memory for symbol storage. ++ ++Another effect of the switch is to set the default hash table size to ++1021, which again saves memory at the cost of lengthening the linker's ++run time. This is not done however if the @option{--hash-size} switch ++has been used. ++ ++The @option{--reduce-memory-overheads} switch may be also be used to ++enable other tradeoffs in future versions of the linker. ++ ++@kindex --max-cache-size=@var{size} ++@item --max-cache-size=@var{size} ++@command{ld} normally caches the relocation information and symbol tables ++of input files in memory with the unlimited size. This option sets the ++maximum cache size to @var{size}. ++ ++@kindex --build-id ++@kindex --build-id=@var{style} ++@item --build-id ++@itemx --build-id=@var{style} ++Request the creation of a @code{.note.gnu.build-id} ELF note section ++or a @code{.buildid} COFF section. The contents of the note are ++unique bits identifying this linked file. @var{style} can be ++@code{uuid} to use 128 random bits, @code{sha1} to use a 160-bit ++@sc{SHA1} hash on the normative parts of the output contents, ++@code{md5} to use a 128-bit @sc{MD5} hash on the normative parts of ++the output contents, or @code{0x@var{hexstring}} to use a chosen bit ++string specified as an even number of hexadecimal digits (@code{-} and ++@code{:} characters between digit pairs are ignored). If @var{style} ++is omitted, @code{sha1} is used. ++ ++The @code{md5} and @code{sha1} styles produces an identifier ++that is always the same in an identical output file, but will be ++unique among all nonidentical output files. It is not intended ++to be compared as a checksum for the file's contents. A linked ++file may be changed later by other tools, but the build ID bit ++string identifying the original linked file does not change. ++ ++Passing @code{none} for @var{style} disables the setting from any ++@code{--build-id} options earlier on the command line. ++ ++@kindex --package-metadata=@var{JSON} ++@item --package-metadata=@var{JSON} ++Request the creation of a @code{.note.package} ELF note section. The ++contents of the note are in JSON format, as per the package metadata ++specification. For more information see: ++https://systemd.io/ELF_PACKAGE_METADATA/ ++If the JSON argument is missing/empty then this will disable the ++creation of the metadata note, if one had been enabled by an earlier ++occurrence of the --package-metdata option. ++If the linker has been built with libjansson, then the JSON string ++will be validated. ++@end table ++ ++@c man end ++ ++@subsection Options Specific to i386 PE Targets ++ ++@c man begin OPTIONS ++ ++The i386 PE linker supports the @option{-shared} option, which causes ++the output to be a dynamically linked library (DLL) instead of a ++normal executable. You should name the output @code{*.dll} when you ++use this option. In addition, the linker fully supports the standard ++@code{*.def} files, which may be specified on the linker command line ++like an object file (in fact, it should precede archives it exports ++symbols from, to ensure that they get linked in, just like a normal ++object file). ++ ++In addition to the options common to all targets, the i386 PE linker ++support additional command-line options that are specific to the i386 ++PE target. Options that take values may be separated from their ++values by either a space or an equals sign. ++ ++@table @gcctabopt ++ ++@kindex --add-stdcall-alias ++@item --add-stdcall-alias ++If given, symbols with a stdcall suffix (@@@var{nn}) will be exported ++as-is and also with the suffix stripped. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --base-file ++@item --base-file @var{file} ++Use @var{file} as the name of a file in which to save the base ++addresses of all the relocations needed for generating DLLs with ++@file{dlltool}. ++[This is an i386 PE specific option] ++ ++@kindex --dll ++@item --dll ++Create a DLL instead of a regular executable. You may also use ++@option{-shared} or specify a @code{LIBRARY} in a given @code{.def} ++file. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --enable-long-section-names ++@kindex --disable-long-section-names ++@item --enable-long-section-names ++@itemx --disable-long-section-names ++The PE variants of the COFF object format add an extension that permits ++the use of section names longer than eight characters, the normal limit ++for COFF. By default, these names are only allowed in object files, as ++fully-linked executable images do not carry the COFF string table required ++to support the longer names. As a GNU extension, it is possible to ++allow their use in executable images as well, or to (probably pointlessly!) ++disallow it in object files, by using these two options. Executable images ++generated with these long section names are slightly non-standard, carrying ++as they do a string table, and may generate confusing output when examined ++with non-GNU PE-aware tools, such as file viewers and dumpers. However, ++GDB relies on the use of PE long section names to find Dwarf-2 debug ++information sections in an executable image at runtime, and so if neither ++option is specified on the command-line, @command{ld} will enable long ++section names, overriding the default and technically correct behaviour, ++when it finds the presence of debug information while linking an executable ++image and not stripping symbols. ++[This option is valid for all PE targeted ports of the linker] ++ ++@kindex --enable-stdcall-fixup ++@kindex --disable-stdcall-fixup ++@item --enable-stdcall-fixup ++@itemx --disable-stdcall-fixup ++If the link finds a symbol that it cannot resolve, it will attempt to ++do ``fuzzy linking'' by looking for another defined symbol that differs ++only in the format of the symbol name (cdecl vs stdcall) and will ++resolve that symbol by linking to the match. For example, the ++undefined symbol @code{_foo} might be linked to the function ++@code{_foo@@12}, or the undefined symbol @code{_bar@@16} might be linked ++to the function @code{_bar}. When the linker does this, it prints a ++warning, since it normally should have failed to link, but sometimes ++import libraries generated from third-party dlls may need this feature ++to be usable. If you specify @option{--enable-stdcall-fixup}, this ++feature is fully enabled and warnings are not printed. If you specify ++@option{--disable-stdcall-fixup}, this feature is disabled and such ++mismatches are considered to be errors. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --leading-underscore ++@kindex --no-leading-underscore ++@item --leading-underscore ++@itemx --no-leading-underscore ++For most targets default symbol-prefix is an underscore and is defined ++in target's description. By this option it is possible to ++disable/enable the default underscore symbol-prefix. ++ ++@cindex DLLs, creating ++@kindex --export-all-symbols ++@item --export-all-symbols ++If given, all global symbols in the objects used to build a DLL will ++be exported by the DLL. Note that this is the default if there ++otherwise wouldn't be any exported symbols. When symbols are ++explicitly exported via DEF files or implicitly exported via function ++attributes, the default is to not export anything else unless this ++option is given. Note that the symbols @code{DllMain@@12}, ++@code{DllEntryPoint@@0}, @code{DllMainCRTStartup@@12}, and ++@code{impure_ptr} will not be automatically ++exported. Also, symbols imported from other DLLs will not be ++re-exported, nor will symbols specifying the DLL's internal layout ++such as those beginning with @code{_head_} or ending with ++@code{_iname}. In addition, no symbols from @code{libgcc}, ++@code{libstd++}, @code{libmingw32}, or @code{crtX.o} will be exported. ++Symbols whose names begin with @code{__rtti_} or @code{__builtin_} will ++not be exported, to help with C++ DLLs. Finally, there is an ++extensive list of cygwin-private symbols that are not exported ++(obviously, this applies on when building DLLs for cygwin targets). ++These cygwin-excludes are: @code{_cygwin_dll_entry@@12}, ++@code{_cygwin_crt0_common@@8}, @code{_cygwin_noncygwin_dll_entry@@12}, ++@code{_fmode}, @code{_impure_ptr}, @code{cygwin_attach_dll}, ++@code{cygwin_premain0}, @code{cygwin_premain1}, @code{cygwin_premain2}, ++@code{cygwin_premain3}, and @code{environ}. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --exclude-symbols ++@item --exclude-symbols @var{symbol},@var{symbol},... ++Specifies a list of symbols which should not be automatically ++exported. The symbol names may be delimited by commas or colons. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --exclude-all-symbols ++@item --exclude-all-symbols ++Specifies no symbols should be automatically exported. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --file-alignment ++@item --file-alignment ++Specify the file alignment. Sections in the file will always begin at ++file offsets which are multiples of this number. This defaults to ++512. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex heap size ++@kindex --heap ++@item --heap @var{reserve} ++@itemx --heap @var{reserve},@var{commit} ++Specify the number of bytes of memory to reserve (and optionally commit) ++to be used as heap for this program. The default is 1MB reserved, 4K ++committed. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex image base ++@kindex --image-base ++@item --image-base @var{value} ++Use @var{value} as the base address of your program or dll. This is ++the lowest memory location that will be used when your program or dll ++is loaded. To reduce the need to relocate and improve performance of ++your dlls, each should have a unique base address and not overlap any ++other dlls. The default is 0x400000 for executables, and 0x10000000 ++for dlls. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --kill-at ++@item --kill-at ++If given, the stdcall suffixes (@@@var{nn}) will be stripped from ++symbols before they are exported. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --large-address-aware ++@item --large-address-aware ++If given, the appropriate bit in the ``Characteristics'' field of the COFF ++header is set to indicate that this executable supports virtual addresses ++greater than 2 gigabytes. This should be used in conjunction with the /3GB ++or /USERVA=@var{value} megabytes switch in the ``[operating systems]'' ++section of the BOOT.INI. Otherwise, this bit has no effect. ++[This option is specific to PE targeted ports of the linker] ++ ++@kindex --disable-large-address-aware ++@item --disable-large-address-aware ++Reverts the effect of a previous @samp{--large-address-aware} option. ++This is useful if @samp{--large-address-aware} is always set by the compiler ++driver (e.g. Cygwin gcc) and the executable does not support virtual ++addresses greater than 2 gigabytes. ++[This option is specific to PE targeted ports of the linker] ++ ++@kindex --major-image-version ++@item --major-image-version @var{value} ++Sets the major number of the ``image version''. Defaults to 1. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --major-os-version ++@item --major-os-version @var{value} ++Sets the major number of the ``os version''. Defaults to 4. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --major-subsystem-version ++@item --major-subsystem-version @var{value} ++Sets the major number of the ``subsystem version''. Defaults to 4. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --minor-image-version ++@item --minor-image-version @var{value} ++Sets the minor number of the ``image version''. Defaults to 0. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --minor-os-version ++@item --minor-os-version @var{value} ++Sets the minor number of the ``os version''. Defaults to 0. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --minor-subsystem-version ++@item --minor-subsystem-version @var{value} ++Sets the minor number of the ``subsystem version''. Defaults to 0. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex DEF files, creating ++@cindex DLLs, creating ++@kindex --output-def ++@item --output-def @var{file} ++The linker will create the file @var{file} which will contain a DEF ++file corresponding to the DLL the linker is generating. This DEF file ++(which should be called @code{*.def}) may be used to create an import ++library with @code{dlltool} or may be used as a reference to ++automatically or implicitly exported symbols. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex DLLs, creating ++@kindex --enable-auto-image-base ++@item --enable-auto-image-base ++@itemx --enable-auto-image-base=@var{value} ++Automatically choose the image base for DLLs, optionally starting with base ++@var{value}, unless one is specified using the @code{--image-base} argument. ++By using a hash generated from the dllname to create unique image bases ++for each DLL, in-memory collisions and relocations which can delay program ++execution are avoided. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --disable-auto-image-base ++@item --disable-auto-image-base ++Do not automatically generate a unique image base. If there is no ++user-specified image base (@code{--image-base}) then use the platform ++default. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex DLLs, linking to ++@kindex --dll-search-prefix ++@item --dll-search-prefix @var{string} ++When linking dynamically to a dll without an import library, ++search for @code{.dll} in preference to ++@code{lib.dll}. This behaviour allows easy distinction ++between DLLs built for the various "subplatforms": native, cygwin, ++uwin, pw, etc. For instance, cygwin DLLs typically use ++@code{--dll-search-prefix=cyg}. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --enable-auto-import ++@item --enable-auto-import ++Do sophisticated linking of @code{_symbol} to @code{__imp__symbol} for ++DATA imports from DLLs, thus making it possible to bypass the dllimport ++mechanism on the user side and to reference unmangled symbol names. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++The following remarks pertain to the original implementation of the ++feature and are obsolete nowadays for Cygwin and MinGW targets. ++ ++Note: Use of the 'auto-import' extension will cause the text section ++of the image file to be made writable. This does not conform to the ++PE-COFF format specification published by Microsoft. ++ ++Note - use of the 'auto-import' extension will also cause read only ++data which would normally be placed into the .rdata section to be ++placed into the .data section instead. This is in order to work ++around a problem with consts that is described here: ++http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html ++ ++Using 'auto-import' generally will 'just work' -- but sometimes you may ++see this message: ++ ++"variable '' can't be auto-imported. Please read the ++documentation for ld's @code{--enable-auto-import} for details." ++ ++This message occurs when some (sub)expression accesses an address ++ultimately given by the sum of two constants (Win32 import tables only ++allow one). Instances where this may occur include accesses to member ++fields of struct variables imported from a DLL, as well as using a ++constant index into an array variable imported from a DLL. Any ++multiword variable (arrays, structs, long long, etc) may trigger ++this error condition. However, regardless of the exact data type ++of the offending exported variable, ld will always detect it, issue ++the warning, and exit. ++ ++There are several ways to address this difficulty, regardless of the ++data type of the exported variable: ++ ++One way is to use --enable-runtime-pseudo-reloc switch. This leaves the task ++of adjusting references in your client code for runtime environment, so ++this method works only when runtime environment supports this feature. ++ ++A second solution is to force one of the 'constants' to be a variable -- ++that is, unknown and un-optimizable at compile time. For arrays, ++there are two possibilities: a) make the indexee (the array's address) ++a variable, or b) make the 'constant' index a variable. Thus: ++ ++@example ++extern type extern_array[]; ++extern_array[1] --> ++ @{ volatile type *t=extern_array; t[1] @} ++@end example ++ ++or ++ ++@example ++extern type extern_array[]; ++extern_array[1] --> ++ @{ volatile int t=1; extern_array[t] @} ++@end example ++ ++For structs (and most other multiword data types) the only option ++is to make the struct itself (or the long long, or the ...) variable: ++ ++@example ++extern struct s extern_struct; ++extern_struct.field --> ++ @{ volatile struct s *t=&extern_struct; t->field @} ++@end example ++ ++or ++ ++@example ++extern long long extern_ll; ++extern_ll --> ++ @{ volatile long long * local_ll=&extern_ll; *local_ll @} ++@end example ++ ++A third method of dealing with this difficulty is to abandon ++'auto-import' for the offending symbol and mark it with ++@code{__declspec(dllimport)}. However, in practice that ++requires using compile-time #defines to indicate whether you are ++building a DLL, building client code that will link to the DLL, or ++merely building/linking to a static library. In making the choice ++between the various methods of resolving the 'direct address with ++constant offset' problem, you should consider typical real-world usage: ++ ++Original: ++@example ++--foo.h ++extern int arr[]; ++--foo.c ++#include "foo.h" ++void main(int argc, char **argv)@{ ++ printf("%d\n",arr[1]); ++@} ++@end example ++ ++Solution 1: ++@example ++--foo.h ++extern int arr[]; ++--foo.c ++#include "foo.h" ++void main(int argc, char **argv)@{ ++ /* This workaround is for win32 and cygwin; do not "optimize" */ ++ volatile int *parr = arr; ++ printf("%d\n",parr[1]); ++@} ++@end example ++ ++Solution 2: ++@example ++--foo.h ++/* Note: auto-export is assumed (no __declspec(dllexport)) */ ++#if (defined(_WIN32) || defined(__CYGWIN__)) && \ ++ !(defined(FOO_BUILD_DLL) || defined(FOO_STATIC)) ++#define FOO_IMPORT __declspec(dllimport) ++#else ++#define FOO_IMPORT ++#endif ++extern FOO_IMPORT int arr[]; ++--foo.c ++#include "foo.h" ++void main(int argc, char **argv)@{ ++ printf("%d\n",arr[1]); ++@} ++@end example ++ ++A fourth way to avoid this problem is to re-code your ++library to use a functional interface rather than a data interface ++for the offending variables (e.g. set_foo() and get_foo() accessor ++functions). ++ ++@kindex --disable-auto-import ++@item --disable-auto-import ++Do not attempt to do sophisticated linking of @code{_symbol} to ++@code{__imp__symbol} for DATA imports from DLLs. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --enable-runtime-pseudo-reloc ++@item --enable-runtime-pseudo-reloc ++If your code contains expressions described in --enable-auto-import section, ++that is, DATA imports from DLL with non-zero offset, this switch will create ++a vector of 'runtime pseudo relocations' which can be used by runtime ++environment to adjust references to such data in your client code. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --disable-runtime-pseudo-reloc ++@item --disable-runtime-pseudo-reloc ++Do not create pseudo relocations for non-zero offset DATA imports from DLLs. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --enable-extra-pe-debug ++@item --enable-extra-pe-debug ++Show additional debug info related to auto-import symbol thunking. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --section-alignment ++@item --section-alignment ++Sets the section alignment. Sections in memory will always begin at ++addresses which are a multiple of this number. Defaults to 0x1000. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex stack size ++@kindex --stack ++@item --stack @var{reserve} ++@itemx --stack @var{reserve},@var{commit} ++Specify the number of bytes of memory to reserve (and optionally commit) ++to be used as stack for this program. The default is 2MB reserved, 4K ++committed. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --subsystem ++@item --subsystem @var{which} ++@itemx --subsystem @var{which}:@var{major} ++@itemx --subsystem @var{which}:@var{major}.@var{minor} ++Specifies the subsystem under which your program will execute. The ++legal values for @var{which} are @code{native}, @code{windows}, ++@code{console}, @code{posix}, and @code{xbox}. You may optionally set ++the subsystem version also. Numeric values are also accepted for ++@var{which}. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++The following options set flags in the @code{DllCharacteristics} field ++of the PE file header: ++[These options are specific to PE targeted ports of the linker] ++ ++@kindex --high-entropy-va ++@item --high-entropy-va ++@itemx --disable-high-entropy-va ++Image is compatible with 64-bit address space layout randomization ++(ASLR). This option is enabled by default for 64-bit PE images. ++ ++This option also implies @option{--dynamicbase} and ++@option{--enable-reloc-section}. ++ ++@kindex --dynamicbase ++@item --dynamicbase ++@itemx --disable-dynamicbase ++The image base address may be relocated using address space layout ++randomization (ASLR). This feature was introduced with MS Windows ++Vista for i386 PE targets. This option is enabled by default but ++can be disabled via the @option{--disable-dynamicbase} option. ++This option also implies @option{--enable-reloc-section}. ++ ++@kindex --forceinteg ++@item --forceinteg ++@itemx --disable-forceinteg ++Code integrity checks are enforced. This option is disabled by ++default. ++ ++@kindex --nxcompat ++@item --nxcompat ++@item --disable-nxcompat ++The image is compatible with the Data Execution Prevention. ++This feature was introduced with MS Windows XP SP2 for i386 PE ++targets. The option is enabled by default. ++ ++@kindex --no-isolation ++@item --no-isolation ++@itemx --disable-no-isolation ++Although the image understands isolation, do not isolate the image. ++This option is disabled by default. ++ ++@kindex --no-seh ++@item --no-seh ++@itemx --disable-no-seh ++The image does not use SEH. No SE handler may be called from ++this image. This option is disabled by default. ++ ++@kindex --no-bind ++@item --no-bind ++@itemx --disable-no-bind ++Do not bind this image. This option is disabled by default. ++ ++@kindex --wdmdriver ++@item --wdmdriver ++@itemx --disable-wdmdriver ++The driver uses the MS Windows Driver Model. This option is disabled ++by default. ++ ++@kindex --tsaware ++@item --tsaware ++@itemx --disable-tsaware ++The image is Terminal Server aware. This option is disabled by ++default. ++ ++@kindex --insert-timestamp ++@item --insert-timestamp ++@itemx --no-insert-timestamp ++Insert a real timestamp into the image. This is the default behaviour ++as it matches legacy code and it means that the image will work with ++other, proprietary tools. The problem with this default is that it ++will result in slightly different images being produced each time the ++same sources are linked. The option @option{--no-insert-timestamp} ++can be used to insert a zero value for the timestamp, this ensuring ++that binaries produced from identical sources will compare ++identically. ++ ++@kindex --enable-reloc-section ++@item --enable-reloc-section ++@itemx --disable-reloc-section ++Create the base relocation table, which is necessary if the image ++is loaded at a different image base than specified in the PE header. ++This option is enabled by default. ++@end table ++ ++@c man end ++ ++@ifset C6X ++@subsection Options specific to C6X uClinux targets ++ ++@c man begin OPTIONS ++ ++The C6X uClinux target uses a binary format called DSBT to support shared ++libraries. Each shared library in the system needs to have a unique index; ++all executables use an index of 0. ++ ++@table @gcctabopt ++ ++@kindex --dsbt-size ++@item --dsbt-size @var{size} ++This option sets the number of entries in the DSBT of the current executable ++or shared library to @var{size}. The default is to create a table with 64 ++entries. ++ ++@kindex --dsbt-index ++@item --dsbt-index @var{index} ++This option sets the DSBT index of the current executable or shared library ++to @var{index}. The default is 0, which is appropriate for generating ++executables. If a shared library is generated with a DSBT index of 0, the ++@code{R_C6000_DSBT_INDEX} relocs are copied into the output file. ++ ++@kindex --no-merge-exidx-entries ++The @samp{--no-merge-exidx-entries} switch disables the merging of adjacent ++exidx entries in frame unwind info. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset CSKY ++@subsection Options specific to C-SKY targets ++ ++@c man begin OPTIONS ++ ++@table @gcctabopt ++ ++@kindex --branch-stub on C-SKY ++@item --branch-stub ++This option enables linker branch relaxation by inserting branch stub ++sections when needed to extend the range of branches. This option is ++usually not required since C-SKY supports branch and call instructions that ++can access the full memory range and branch relaxation is normally handled by ++the compiler or assembler. ++ ++@kindex --stub-group-size on C-SKY ++@item --stub-group-size=@var{N} ++This option allows finer control of linker branch stub creation. ++It sets the maximum size of a group of input sections that can ++be handled by one stub section. A negative value of @var{N} locates ++stub sections after their branches, while a positive value allows stub ++sections to appear either before or after the branches. Values of ++@samp{1} or @samp{-1} indicate that the ++linker should choose suitable defaults. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset M68HC11 ++@subsection Options specific to Motorola 68HC11 and 68HC12 targets ++ ++@c man begin OPTIONS ++ ++The 68HC11 and 68HC12 linkers support specific options to control the ++memory bank switching mapping and trampoline code generation. ++ ++@table @gcctabopt ++ ++@kindex --no-trampoline ++@item --no-trampoline ++This option disables the generation of trampoline. By default a trampoline ++is generated for each far function which is called using a @code{jsr} ++instruction (this happens when a pointer to a far function is taken). ++ ++@kindex --bank-window ++@item --bank-window @var{name} ++This option indicates to the linker the name of the memory region in ++the @samp{MEMORY} specification that describes the memory bank window. ++The definition of such region is then used by the linker to compute ++paging and addresses within the memory window. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset M68K ++@subsection Options specific to Motorola 68K target ++ ++@c man begin OPTIONS ++ ++The following options are supported to control handling of GOT generation ++when linking for 68K targets. ++ ++@table @gcctabopt ++ ++@kindex --got ++@item --got=@var{type} ++This option tells the linker which GOT generation scheme to use. ++@var{type} should be one of @samp{single}, @samp{negative}, ++@samp{multigot} or @samp{target}. For more information refer to the ++Info entry for @file{ld}. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset MIPS ++@subsection Options specific to MIPS targets ++ ++@c man begin OPTIONS ++ ++The following options are supported to control microMIPS instruction ++generation and branch relocation checks for ISA mode transitions when ++linking for MIPS targets. ++ ++@table @gcctabopt ++ ++@kindex --insn32 ++@item --insn32 ++@kindex --no-insn32 ++@itemx --no-insn32 ++These options control the choice of microMIPS instructions used in code ++generated by the linker, such as that in the PLT or lazy binding stubs, ++or in relaxation. If @samp{--insn32} is used, then the linker only uses ++32-bit instruction encodings. By default or if @samp{--no-insn32} is ++used, all instruction encodings are used, including 16-bit ones where ++possible. ++ ++@kindex --ignore-branch-isa ++@item --ignore-branch-isa ++@kindex --no-ignore-branch-isa ++@itemx --no-ignore-branch-isa ++These options control branch relocation checks for invalid ISA mode ++transitions. If @samp{--ignore-branch-isa} is used, then the linker ++accepts any branch relocations and any ISA mode transition required ++is lost in relocation calculation, except for some cases of @code{BAL} ++instructions which meet relaxation conditions and are converted to ++equivalent @code{JALX} instructions as the associated relocation is ++calculated. By default or if @samp{--no-ignore-branch-isa} is used ++a check is made causing the loss of an ISA mode transition to produce ++an error. ++ ++@kindex --compact-branches ++@item --compact-branches ++@kindex --no-compact-branches ++@itemx --no-compact-branches ++These options control the generation of compact instructions by the linker ++in the PLT entries for MIPS R6. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++ ++@ifset PDP11 ++@subsection Options specific to PDP11 targets ++ ++@c man begin OPTIONS ++ ++For the pdp11-aout target, three variants of the output format can be ++produced as selected by the following options. The default variant ++for pdp11-aout is the @samp{--omagic} option, whereas for other ++targets @samp{--nmagic} is the default. The @samp{--imagic} option is ++defined only for the pdp11-aout target, while the others are described ++here as they apply to the pdp11-aout target. ++ ++@table @gcctabopt ++ ++@kindex -N ++@item -N ++@kindex --omagic ++@itemx --omagic ++ ++Mark the output as @code{OMAGIC} (0407) in the @file{a.out} header to ++indicate that the text segment is not to be write-protected and ++shared. Since the text and data sections are both readable and ++writable, the data section is allocated immediately contiguous after ++the text segment. This is the oldest format for PDP11 executable ++programs and is the default for @command{ld} on PDP11 Unix systems ++from the beginning through 2.11BSD. ++ ++@kindex -n ++@item -n ++@kindex --nmagic ++@itemx --nmagic ++ ++Mark the output as @code{NMAGIC} (0410) in the @file{a.out} header to ++indicate that when the output file is executed, the text portion will ++be read-only and shareable among all processes executing the same ++file. This involves moving the data areas up to the first possible 8K ++byte page boundary following the end of the text. This option creates ++a @emph{pure executable} format. ++ ++@kindex -z ++@item -z ++@kindex --imagic ++@itemx --imagic ++ ++Mark the output as @code{IMAGIC} (0411) in the @file{a.out} header to ++indicate that when the output file is executed, the program text and ++data areas will be loaded into separate address spaces using the split ++instruction and data space feature of the memory management unit in ++larger models of the PDP11. This doubles the address space available ++to the program. The text segment is again pure, write-protected, and ++shareable. The only difference in the output format between this ++option and the others, besides the magic number, is that both the text ++and data sections start at location 0. The @samp{-z} option selected ++this format in 2.11BSD. This option creates a @emph{separate ++executable} format. ++ ++@kindex --no-omagic ++@item --no-omagic ++ ++Equivalent to @samp{--nmagic} for pdp11-aout. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset UsesEnvVars ++@node Environment ++@section Environment Variables ++ ++@c man begin ENVIRONMENT ++ ++You can change the behaviour of @command{ld} with the environment variables ++@ifclear SingleFormat ++@code{GNUTARGET}, ++@end ifclear ++@code{LDEMULATION} and @code{COLLECT_NO_DEMANGLE}. ++ ++@ifclear SingleFormat ++@kindex GNUTARGET ++@cindex default input format ++@code{GNUTARGET} determines the input-file object format if you don't ++use @samp{-b} (or its synonym @samp{--format}). Its value should be one ++of the BFD names for an input format (@pxref{BFD}). If there is no ++@code{GNUTARGET} in the environment, @command{ld} uses the natural format ++of the target. If @code{GNUTARGET} is set to @code{default} then BFD ++attempts to discover the input format by examining binary input files; ++this method often succeeds, but there are potential ambiguities, since ++there is no method of ensuring that the magic number used to specify ++object-file formats is unique. However, the configuration procedure for ++BFD on each system places the conventional format for that system first ++in the search-list, so ambiguities are resolved in favor of convention. ++@end ifclear ++ ++@kindex LDEMULATION ++@cindex default emulation ++@cindex emulation, default ++@code{LDEMULATION} determines the default emulation if you don't use the ++@samp{-m} option. The emulation can affect various aspects of linker ++behaviour, particularly the default linker script. You can list the ++available emulations with the @samp{--verbose} or @samp{-V} options. If ++the @samp{-m} option is not used, and the @code{LDEMULATION} environment ++variable is not defined, the default emulation depends upon how the ++linker was configured. ++ ++@kindex COLLECT_NO_DEMANGLE ++@cindex demangling, default ++Normally, the linker will default to demangling symbols. However, if ++@code{COLLECT_NO_DEMANGLE} is set in the environment, then it will ++default to not demangling symbols. This environment variable is used in ++a similar fashion by the @code{gcc} linker wrapper program. The default ++may be overridden by the @samp{--demangle} and @samp{--no-demangle} ++options. ++ ++@c man end ++@end ifset ++ ++@node Scripts ++@chapter Linker Scripts ++ ++@cindex scripts ++@cindex linker scripts ++@cindex command files ++Every link is controlled by a @dfn{linker script}. This script is ++written in the linker command language. ++ ++The main purpose of the linker script is to describe how the sections in ++the input files should be mapped into the output file, and to control ++the memory layout of the output file. Most linker scripts do nothing ++more than this. However, when necessary, the linker script can also ++direct the linker to perform many other operations, using the commands ++described below. ++ ++The linker always uses a linker script. If you do not supply one ++yourself, the linker will use a default script that is compiled into the ++linker executable. You can use the @samp{--verbose} command-line option ++to display the default linker script. Certain command-line options, ++such as @samp{-r} or @samp{-N}, will affect the default linker script. ++ ++You may supply your own linker script by using the @samp{-T} command ++line option. When you do this, your linker script will replace the ++default linker script. ++ ++You may also use linker scripts implicitly by naming them as input files ++to the linker, as though they were files to be linked. @xref{Implicit ++Linker Scripts}. ++ ++@menu ++* Basic Script Concepts:: Basic Linker Script Concepts ++* Script Format:: Linker Script Format ++* Simple Example:: Simple Linker Script Example ++* Simple Commands:: Simple Linker Script Commands ++* Assignments:: Assigning Values to Symbols ++* SECTIONS:: SECTIONS Command ++* MEMORY:: MEMORY Command ++* PHDRS:: PHDRS Command ++* VERSION:: VERSION Command ++* Expressions:: Expressions in Linker Scripts ++* Implicit Linker Scripts:: Implicit Linker Scripts ++@end menu ++ ++@node Basic Script Concepts ++@section Basic Linker Script Concepts ++@cindex linker script concepts ++We need to define some basic concepts and vocabulary in order to ++describe the linker script language. ++ ++The linker combines input files into a single output file. The output ++file and each input file are in a special data format known as an ++@dfn{object file format}. Each file is called an @dfn{object file}. ++The output file is often called an @dfn{executable}, but for our ++purposes we will also call it an object file. Each object file has, ++among other things, a list of @dfn{sections}. We sometimes refer to a ++section in an input file as an @dfn{input section}; similarly, a section ++in the output file is an @dfn{output section}. ++ ++Each section in an object file has a name and a size. Most sections ++also have an associated block of data, known as the @dfn{section ++contents}. A section may be marked as @dfn{loadable}, which means that ++the contents should be loaded into memory when the output file is run. ++A section with no contents may be @dfn{allocatable}, which means that an ++area in memory should be set aside, but nothing in particular should be ++loaded there (in some cases this memory must be zeroed out). A section ++which is neither loadable nor allocatable typically contains some sort ++of debugging information. ++ ++Every loadable or allocatable output section has two addresses. The ++first is the @dfn{VMA}, or virtual memory address. This is the address ++the section will have when the output file is run. The second is the ++@dfn{LMA}, or load memory address. This is the address at which the ++section will be loaded. In most cases the two addresses will be the ++same. An example of when they might be different is when a data section ++is loaded into ROM, and then copied into RAM when the program starts up ++(this technique is often used to initialize global variables in a ROM ++based system). In this case the ROM address would be the LMA, and the ++RAM address would be the VMA. ++ ++You can see the sections in an object file by using the @code{objdump} ++program with the @samp{-h} option. ++ ++Every object file also has a list of @dfn{symbols}, known as the ++@dfn{symbol table}. A symbol may be defined or undefined. Each symbol ++has a name, and each defined symbol has an address, among other ++information. If you compile a C or C++ program into an object file, you ++will get a defined symbol for every defined function and global or ++static variable. Every undefined function or global variable which is ++referenced in the input file will become an undefined symbol. ++ ++You can see the symbols in an object file by using the @code{nm} ++program, or by using the @code{objdump} program with the @samp{-t} ++option. ++ ++@node Script Format ++@section Linker Script Format ++@cindex linker script format ++Linker scripts are text files. ++ ++You write a linker script as a series of commands. Each command is ++either a keyword, possibly followed by arguments, or an assignment to a ++symbol. You may separate commands using semicolons. Whitespace is ++generally ignored. ++ ++Strings such as file or format names can normally be entered directly. ++If the file name contains a character such as a comma which would ++otherwise serve to separate file names, you may put the file name in ++double quotes. There is no way to use a double quote character in a ++file name. ++ ++You may include comments in linker scripts just as in C, delimited by ++@samp{/*} and @samp{*/}. As in C, comments are syntactically equivalent ++to whitespace. ++ ++@node Simple Example ++@section Simple Linker Script Example ++@cindex linker script example ++@cindex example of linker script ++Many linker scripts are fairly simple. ++ ++The simplest possible linker script has just one command: ++@samp{SECTIONS}. You use the @samp{SECTIONS} command to describe the ++memory layout of the output file. ++ ++The @samp{SECTIONS} command is a powerful command. Here we will ++describe a simple use of it. Let's assume your program consists only of ++code, initialized data, and uninitialized data. These will be in the ++@samp{.text}, @samp{.data}, and @samp{.bss} sections, respectively. ++Let's assume further that these are the only sections which appear in ++your input files. ++ ++For this example, let's say that the code should be loaded at address ++0x10000, and that the data should start at address 0x8000000. Here is a ++linker script which will do that: ++@smallexample ++SECTIONS ++@{ ++ . = 0x10000; ++ .text : @{ *(.text) @} ++ . = 0x8000000; ++ .data : @{ *(.data) @} ++ .bss : @{ *(.bss) @} ++@} ++@end smallexample ++ ++You write the @samp{SECTIONS} command as the keyword @samp{SECTIONS}, ++followed by a series of symbol assignments and output section ++descriptions enclosed in curly braces. ++ ++The first line inside the @samp{SECTIONS} command of the above example ++sets the value of the special symbol @samp{.}, which is the location ++counter. If you do not specify the address of an output section in some ++other way (other ways are described later), the address is set from the ++current value of the location counter. The location counter is then ++incremented by the size of the output section. At the start of the ++@samp{SECTIONS} command, the location counter has the value @samp{0}. ++ ++The second line defines an output section, @samp{.text}. The colon is ++required syntax which may be ignored for now. Within the curly braces ++after the output section name, you list the names of the input sections ++which should be placed into this output section. The @samp{*} is a ++wildcard which matches any file name. The expression @samp{*(.text)} ++means all @samp{.text} input sections in all input files. ++ ++Since the location counter is @samp{0x10000} when the output section ++@samp{.text} is defined, the linker will set the address of the ++@samp{.text} section in the output file to be @samp{0x10000}. ++ ++The remaining lines define the @samp{.data} and @samp{.bss} sections in ++the output file. The linker will place the @samp{.data} output section ++at address @samp{0x8000000}. After the linker places the @samp{.data} ++output section, the value of the location counter will be ++@samp{0x8000000} plus the size of the @samp{.data} output section. The ++effect is that the linker will place the @samp{.bss} output section ++immediately after the @samp{.data} output section in memory. ++ ++The linker will ensure that each output section has the required ++alignment, by increasing the location counter if necessary. In this ++example, the specified addresses for the @samp{.text} and @samp{.data} ++sections will probably satisfy any alignment constraints, but the linker ++may have to create a small gap between the @samp{.data} and @samp{.bss} ++sections. ++ ++That's it! That's a simple and complete linker script. ++ ++@node Simple Commands ++@section Simple Linker Script Commands ++@cindex linker script simple commands ++In this section we describe the simple linker script commands. ++ ++@menu ++* Entry Point:: Setting the entry point ++* File Commands:: Commands dealing with files ++@ifclear SingleFormat ++* Format Commands:: Commands dealing with object file formats ++@end ifclear ++ ++* REGION_ALIAS:: Assign alias names to memory regions ++* Miscellaneous Commands:: Other linker script commands ++@end menu ++ ++@node Entry Point ++@subsection Setting the Entry Point ++@kindex ENTRY(@var{symbol}) ++@cindex start of execution ++@cindex first instruction ++@cindex entry point ++The first instruction to execute in a program is called the @dfn{entry ++point}. You can use the @code{ENTRY} linker script command to set the ++entry point. The argument is a symbol name: ++@smallexample ++ENTRY(@var{symbol}) ++@end smallexample ++ ++There are several ways to set the entry point. The linker will set the ++entry point by trying each of the following methods in order, and ++stopping when one of them succeeds: ++@itemize @bullet ++@item ++the @samp{-e} @var{entry} command-line option; ++@item ++the @code{ENTRY(@var{symbol})} command in a linker script; ++@item ++the value of a target-specific symbol, if it is defined; For many ++targets this is @code{start}, but PE- and BeOS-based systems for example ++check a list of possible entry symbols, matching the first one found. ++@item ++the address of the first byte of the code section, if present and an ++executable is being created - the code section is usually ++@samp{.text}, but can be something else; ++@item ++The address @code{0}. ++@end itemize ++ ++@node File Commands ++@subsection Commands Dealing with Files ++@cindex linker script file commands ++Several linker script commands deal with files. ++ ++@table @code ++@item INCLUDE @var{filename} ++@kindex INCLUDE @var{filename} ++@cindex including a linker script ++Include the linker script @var{filename} at this point. The file will ++be searched for in the current directory, and in any directory specified ++with the @option{-L} option. You can nest calls to @code{INCLUDE} up to ++10 levels deep. ++ ++You can place @code{INCLUDE} directives at the top level, in @code{MEMORY} or ++@code{SECTIONS} commands, or in output section descriptions. ++ ++@item INPUT(@var{file}, @var{file}, @dots{}) ++@itemx INPUT(@var{file} @var{file} @dots{}) ++@kindex INPUT(@var{files}) ++@cindex input files in linker scripts ++@cindex input object files in linker scripts ++@cindex linker script input object files ++The @code{INPUT} command directs the linker to include the named files ++in the link, as though they were named on the command line. ++ ++For example, if you always want to include @file{subr.o} any time you do ++a link, but you can't be bothered to put it on every link command line, ++then you can put @samp{INPUT (subr.o)} in your linker script. ++ ++In fact, if you like, you can list all of your input files in the linker ++script, and then invoke the linker with nothing but a @samp{-T} option. ++ ++In case a @dfn{sysroot prefix} is configured, and the filename starts ++with the @samp{/} character, and the script being processed was ++located inside the @dfn{sysroot prefix}, the filename will be looked ++for in the @dfn{sysroot prefix}. The @dfn{sysroot prefix} can also be forced by specifying ++@code{=} as the first character in the filename path, or prefixing the ++filename path with @code{$SYSROOT}. See also the description of ++@samp{-L} in @ref{Options,,Command-line Options}. ++ ++If a @dfn{sysroot prefix} is not used then the linker will try to open ++the file in the directory containing the linker script. If it is not ++found the linker will then search the current directory. If it is still ++not found the linker will search through the archive library search ++path. ++ ++If you use @samp{INPUT (-l@var{file})}, @command{ld} will transform the ++name to @code{lib@var{file}.a}, as with the command-line argument ++@samp{-l}. ++ ++When you use the @code{INPUT} command in an implicit linker script, the ++files will be included in the link at the point at which the linker ++script file is included. This can affect archive searching. ++ ++@item GROUP(@var{file}, @var{file}, @dots{}) ++@itemx GROUP(@var{file} @var{file} @dots{}) ++@kindex GROUP(@var{files}) ++@cindex grouping input files ++The @code{GROUP} command is like @code{INPUT}, except that the named ++files should all be archives, and they are searched repeatedly until no ++new undefined references are created. See the description of @samp{-(} ++in @ref{Options,,Command-line Options}. ++ ++@item AS_NEEDED(@var{file}, @var{file}, @dots{}) ++@itemx AS_NEEDED(@var{file} @var{file} @dots{}) ++@kindex AS_NEEDED(@var{files}) ++This construct can appear only inside of the @code{INPUT} or @code{GROUP} ++commands, among other filenames. The files listed will be handled ++as if they appear directly in the @code{INPUT} or @code{GROUP} commands, ++with the exception of ELF shared libraries, that will be added only ++when they are actually needed. This construct essentially enables ++@option{--as-needed} option for all the files listed inside of it ++and restores previous @option{--as-needed} resp. @option{--no-as-needed} ++setting afterwards. ++ ++@item OUTPUT(@var{filename}) ++@kindex OUTPUT(@var{filename}) ++@cindex output file name in linker script ++The @code{OUTPUT} command names the output file. Using ++@code{OUTPUT(@var{filename})} in the linker script is exactly like using ++@samp{-o @var{filename}} on the command line (@pxref{Options,,Command ++Line Options}). If both are used, the command-line option takes ++precedence. ++ ++You can use the @code{OUTPUT} command to define a default name for the ++output file other than the usual default of @file{a.out}. ++ ++@item SEARCH_DIR(@var{path}) ++@kindex SEARCH_DIR(@var{path}) ++@cindex library search path in linker script ++@cindex archive search path in linker script ++@cindex search path in linker script ++The @code{SEARCH_DIR} command adds @var{path} to the list of paths where ++@command{ld} looks for archive libraries. Using ++@code{SEARCH_DIR(@var{path})} is exactly like using @samp{-L @var{path}} ++on the command line (@pxref{Options,,Command-line Options}). If both ++are used, then the linker will search both paths. Paths specified using ++the command-line option are searched first. ++ ++@item STARTUP(@var{filename}) ++@kindex STARTUP(@var{filename}) ++@cindex first input file ++The @code{STARTUP} command is just like the @code{INPUT} command, except ++that @var{filename} will become the first input file to be linked, as ++though it were specified first on the command line. This may be useful ++when using a system in which the entry point is always the start of the ++first file. ++@end table ++ ++@ifclear SingleFormat ++@node Format Commands ++@subsection Commands Dealing with Object File Formats ++A couple of linker script commands deal with object file formats. ++ ++@table @code ++@item OUTPUT_FORMAT(@var{bfdname}) ++@itemx OUTPUT_FORMAT(@var{default}, @var{big}, @var{little}) ++@kindex OUTPUT_FORMAT(@var{bfdname}) ++@cindex output file format in linker script ++The @code{OUTPUT_FORMAT} command names the BFD format to use for the ++output file (@pxref{BFD}). Using @code{OUTPUT_FORMAT(@var{bfdname})} is ++exactly like using @samp{--oformat @var{bfdname}} on the command line ++(@pxref{Options,,Command-line Options}). If both are used, the command ++line option takes precedence. ++ ++You can use @code{OUTPUT_FORMAT} with three arguments to use different ++formats based on the @samp{-EB} and @samp{-EL} command-line options. ++This permits the linker script to set the output format based on the ++desired endianness. ++ ++If neither @samp{-EB} nor @samp{-EL} are used, then the output format ++will be the first argument, @var{default}. If @samp{-EB} is used, the ++output format will be the second argument, @var{big}. If @samp{-EL} is ++used, the output format will be the third argument, @var{little}. ++ ++For example, the default linker script for the MIPS ELF target uses this ++command: ++@smallexample ++OUTPUT_FORMAT(elf32-bigmips, elf32-bigmips, elf32-littlemips) ++@end smallexample ++This says that the default format for the output file is ++@samp{elf32-bigmips}, but if the user uses the @samp{-EL} command-line ++option, the output file will be created in the @samp{elf32-littlemips} ++format. ++ ++@item TARGET(@var{bfdname}) ++@kindex TARGET(@var{bfdname}) ++@cindex input file format in linker script ++The @code{TARGET} command names the BFD format to use when reading input ++files. It affects subsequent @code{INPUT} and @code{GROUP} commands. ++This command is like using @samp{-b @var{bfdname}} on the command line ++(@pxref{Options,,Command-line Options}). If the @code{TARGET} command ++is used but @code{OUTPUT_FORMAT} is not, then the last @code{TARGET} ++command is also used to set the format for the output file. @xref{BFD}. ++@end table ++@end ifclear ++ ++@node REGION_ALIAS ++@subsection Assign alias names to memory regions ++@kindex REGION_ALIAS(@var{alias}, @var{region}) ++@cindex region alias ++@cindex region names ++ ++Alias names can be added to existing memory regions created with the ++@ref{MEMORY} command. Each name corresponds to at most one memory region. ++ ++@smallexample ++REGION_ALIAS(@var{alias}, @var{region}) ++@end smallexample ++ ++The @code{REGION_ALIAS} function creates an alias name @var{alias} for the ++memory region @var{region}. This allows a flexible mapping of output sections ++to memory regions. An example follows. ++ ++Suppose we have an application for embedded systems which come with various ++memory storage devices. All have a general purpose, volatile memory @code{RAM} ++that allows code execution or data storage. Some may have a read-only, ++non-volatile memory @code{ROM} that allows code execution and read-only data ++access. The last variant is a read-only, non-volatile memory @code{ROM2} with ++read-only data access and no code execution capability. We have four output ++sections: ++ ++@itemize @bullet ++@item ++@code{.text} program code; ++@item ++@code{.rodata} read-only data; ++@item ++@code{.data} read-write initialized data; ++@item ++@code{.bss} read-write zero initialized data. ++@end itemize ++ ++The goal is to provide a linker command file that contains a system independent ++part defining the output sections and a system dependent part mapping the ++output sections to the memory regions available on the system. Our embedded ++systems come with three different memory setups @code{A}, @code{B} and ++@code{C}: ++@multitable @columnfractions .25 .25 .25 .25 ++@item Section @tab Variant A @tab Variant B @tab Variant C ++@item .text @tab RAM @tab ROM @tab ROM ++@item .rodata @tab RAM @tab ROM @tab ROM2 ++@item .data @tab RAM @tab RAM/ROM @tab RAM/ROM2 ++@item .bss @tab RAM @tab RAM @tab RAM ++@end multitable ++The notation @code{RAM/ROM} or @code{RAM/ROM2} means that this section is ++loaded into region @code{ROM} or @code{ROM2} respectively. Please note that ++the load address of the @code{.data} section starts in all three variants at ++the end of the @code{.rodata} section. ++ ++The base linker script that deals with the output sections follows. It ++includes the system dependent @code{linkcmds.memory} file that describes the ++memory layout: ++@smallexample ++INCLUDE linkcmds.memory ++ ++SECTIONS ++ @{ ++ .text : ++ @{ ++ *(.text) ++ @} > REGION_TEXT ++ .rodata : ++ @{ ++ *(.rodata) ++ rodata_end = .; ++ @} > REGION_RODATA ++ .data : AT (rodata_end) ++ @{ ++ data_start = .; ++ *(.data) ++ @} > REGION_DATA ++ data_size = SIZEOF(.data); ++ data_load_start = LOADADDR(.data); ++ .bss : ++ @{ ++ *(.bss) ++ @} > REGION_BSS ++ @} ++@end smallexample ++ ++Now we need three different @code{linkcmds.memory} files to define memory ++regions and alias names. The content of @code{linkcmds.memory} for the three ++variants @code{A}, @code{B} and @code{C}: ++@table @code ++@item A ++Here everything goes into the @code{RAM}. ++@smallexample ++MEMORY ++ @{ ++ RAM : ORIGIN = 0, LENGTH = 4M ++ @} ++ ++REGION_ALIAS("REGION_TEXT", RAM); ++REGION_ALIAS("REGION_RODATA", RAM); ++REGION_ALIAS("REGION_DATA", RAM); ++REGION_ALIAS("REGION_BSS", RAM); ++@end smallexample ++@item B ++Program code and read-only data go into the @code{ROM}. Read-write data goes ++into the @code{RAM}. An image of the initialized data is loaded into the ++@code{ROM} and will be copied during system start into the @code{RAM}. ++@smallexample ++MEMORY ++ @{ ++ ROM : ORIGIN = 0, LENGTH = 3M ++ RAM : ORIGIN = 0x10000000, LENGTH = 1M ++ @} ++ ++REGION_ALIAS("REGION_TEXT", ROM); ++REGION_ALIAS("REGION_RODATA", ROM); ++REGION_ALIAS("REGION_DATA", RAM); ++REGION_ALIAS("REGION_BSS", RAM); ++@end smallexample ++@item C ++Program code goes into the @code{ROM}. Read-only data goes into the ++@code{ROM2}. Read-write data goes into the @code{RAM}. An image of the ++initialized data is loaded into the @code{ROM2} and will be copied during ++system start into the @code{RAM}. ++@smallexample ++MEMORY ++ @{ ++ ROM : ORIGIN = 0, LENGTH = 2M ++ ROM2 : ORIGIN = 0x10000000, LENGTH = 1M ++ RAM : ORIGIN = 0x20000000, LENGTH = 1M ++ @} ++ ++REGION_ALIAS("REGION_TEXT", ROM); ++REGION_ALIAS("REGION_RODATA", ROM2); ++REGION_ALIAS("REGION_DATA", RAM); ++REGION_ALIAS("REGION_BSS", RAM); ++@end smallexample ++@end table ++ ++It is possible to write a common system initialization routine to copy the ++@code{.data} section from @code{ROM} or @code{ROM2} into the @code{RAM} if ++necessary: ++@smallexample ++#include ++ ++extern char data_start []; ++extern char data_size []; ++extern char data_load_start []; ++ ++void copy_data(void) ++@{ ++ if (data_start != data_load_start) ++ @{ ++ memcpy(data_start, data_load_start, (size_t) data_size); ++ @} ++@} ++@end smallexample ++ ++@node Miscellaneous Commands ++@subsection Other Linker Script Commands ++There are a few other linker scripts commands. ++ ++@table @code ++@item ASSERT(@var{exp}, @var{message}) ++@kindex ASSERT ++@cindex assertion in linker script ++Ensure that @var{exp} is non-zero. If it is zero, then exit the linker ++with an error code, and print @var{message}. ++ ++Note that assertions are checked before the final stages of linking ++take place. This means that expressions involving symbols PROVIDEd ++inside section definitions will fail if the user has not set values ++for those symbols. The only exception to this rule is PROVIDEd ++symbols that just reference dot. Thus an assertion like this: ++ ++@smallexample ++ .stack : ++ @{ ++ PROVIDE (__stack = .); ++ PROVIDE (__stack_size = 0x100); ++ ASSERT ((__stack > (_end + __stack_size)), "Error: No room left for the stack"); ++ @} ++@end smallexample ++ ++will fail if @code{__stack_size} is not defined elsewhere. Symbols ++PROVIDEd outside of section definitions are evaluated earlier, so they ++can be used inside ASSERTions. Thus: ++ ++@smallexample ++ PROVIDE (__stack_size = 0x100); ++ .stack : ++ @{ ++ PROVIDE (__stack = .); ++ ASSERT ((__stack > (_end + __stack_size)), "Error: No room left for the stack"); ++ @} ++@end smallexample ++ ++will work. ++ ++@item EXTERN(@var{symbol} @var{symbol} @dots{}) ++@kindex EXTERN ++@cindex undefined symbol in linker script ++Force @var{symbol} to be entered in the output file as an undefined ++symbol. Doing this may, for example, trigger linking of additional ++modules from standard libraries. You may list several @var{symbol}s for ++each @code{EXTERN}, and you may use @code{EXTERN} multiple times. This ++command has the same effect as the @samp{-u} command-line option. ++ ++@item FORCE_COMMON_ALLOCATION ++@kindex FORCE_COMMON_ALLOCATION ++@cindex common allocation in linker script ++This command has the same effect as the @samp{-d} command-line option: ++to make @command{ld} assign space to common symbols even if a relocatable ++output file is specified (@samp{-r}). ++ ++@item INHIBIT_COMMON_ALLOCATION ++@kindex INHIBIT_COMMON_ALLOCATION ++@cindex common allocation in linker script ++This command has the same effect as the @samp{--no-define-common} ++command-line option: to make @code{ld} omit the assignment of addresses ++to common symbols even for a non-relocatable output file. ++ ++@item FORCE_GROUP_ALLOCATION ++@kindex FORCE_GROUP_ALLOCATION ++@cindex group allocation in linker script ++@cindex section groups ++@cindex COMDAT ++This command has the same effect as the ++@samp{--force-group-allocation} command-line option: to make ++@command{ld} place section group members like normal input sections, ++and to delete the section groups even if a relocatable output file is ++specified (@samp{-r}). ++ ++@item INSERT [ AFTER | BEFORE ] @var{output_section} ++@kindex INSERT ++@cindex insert user script into default script ++This command is typically used in a script specified by @samp{-T} to ++augment the default @code{SECTIONS} with, for example, overlays. It ++inserts all prior linker script statements after (or before) ++@var{output_section}, and also causes @samp{-T} to not override the ++default linker script. The exact insertion point is as for orphan ++sections. @xref{Location Counter}. The insertion happens after the ++linker has mapped input sections to output sections. Prior to the ++insertion, since @samp{-T} scripts are parsed before the default ++linker script, statements in the @samp{-T} script occur before the ++default linker script statements in the internal linker representation ++of the script. In particular, input section assignments will be made ++to @samp{-T} output sections before those in the default script. Here ++is an example of how a @samp{-T} script using @code{INSERT} might look: ++ ++@smallexample ++SECTIONS ++@{ ++ OVERLAY : ++ @{ ++ .ov1 @{ ov1*(.text) @} ++ .ov2 @{ ov2*(.text) @} ++ @} ++@} ++INSERT AFTER .text; ++@end smallexample ++ ++Note that when @samp{-T} is used twice, once to override the default ++script and once to augment that script using @code{INSERT} the order ++of parsing and section assignments apply as for the default script. ++The script with @code{INSERT} should be specified @emph{first} on the ++command line. ++ ++@item NOCROSSREFS(@var{section} @var{section} @dots{}) ++@kindex NOCROSSREFS(@var{sections}) ++@cindex cross references ++This command may be used to tell @command{ld} to issue an error about any ++references among certain output sections. ++ ++In certain types of programs, particularly on embedded systems when ++using overlays, when one section is loaded into memory, another section ++will not be. Any direct references between the two sections would be ++errors. For example, it would be an error if code in one section called ++a function defined in the other section. ++ ++The @code{NOCROSSREFS} command takes a list of output section names. If ++@command{ld} detects any cross references between the sections, it reports ++an error and returns a non-zero exit status. Note that the ++@code{NOCROSSREFS} command uses output section names, not input section ++names. ++ ++@item NOCROSSREFS_TO(@var{tosection} @var{fromsection} @dots{}) ++@kindex NOCROSSREFS_TO(@var{tosection} @var{fromsections}) ++@cindex cross references ++This command may be used to tell @command{ld} to issue an error about any ++references to one section from a list of other sections. ++ ++The @code{NOCROSSREFS} command is useful when ensuring that two or more ++output sections are entirely independent but there are situations where ++a one-way dependency is needed. For example, in a multi-core application ++there may be shared code that can be called from each core but for safety ++must never call back. ++ ++The @code{NOCROSSREFS_TO} command takes a list of output section names. ++The first section can not be referenced from any of the other sections. ++If @command{ld} detects any references to the first section from any of ++the other sections, it reports an error and returns a non-zero exit ++status. Note that the @code{NOCROSSREFS_TO} command uses output section ++names, not input section names. ++ ++@ifclear SingleFormat ++@item OUTPUT_ARCH(@var{bfdarch}) ++@kindex OUTPUT_ARCH(@var{bfdarch}) ++@cindex machine architecture ++@cindex architecture ++Specify a particular output machine architecture. The argument is one ++of the names used by the BFD library (@pxref{BFD}). You can see the ++architecture of an object file by using the @code{objdump} program with ++the @samp{-f} option. ++@end ifclear ++ ++@item LD_FEATURE(@var{string}) ++@kindex LD_FEATURE(@var{string}) ++This command may be used to modify @command{ld} behavior. If ++@var{string} is @code{"SANE_EXPR"} then absolute symbols and numbers ++in a script are simply treated as numbers everywhere. ++@xref{Expression Section}. ++@end table ++ ++@node Assignments ++@section Assigning Values to Symbols ++@cindex assignment in scripts ++@cindex symbol definition, scripts ++@cindex variables, defining ++You may assign a value to a symbol in a linker script. This will define ++the symbol and place it into the symbol table with a global scope. ++ ++@menu ++* Simple Assignments:: Simple Assignments ++* HIDDEN:: HIDDEN ++* PROVIDE:: PROVIDE ++* PROVIDE_HIDDEN:: PROVIDE_HIDDEN ++* Source Code Reference:: How to use a linker script defined symbol in source code ++@end menu ++ ++@node Simple Assignments ++@subsection Simple Assignments ++ ++You may assign to a symbol using any of the C assignment operators: ++ ++@table @code ++@item @var{symbol} = @var{expression} ; ++@itemx @var{symbol} += @var{expression} ; ++@itemx @var{symbol} -= @var{expression} ; ++@itemx @var{symbol} *= @var{expression} ; ++@itemx @var{symbol} /= @var{expression} ; ++@itemx @var{symbol} <<= @var{expression} ; ++@itemx @var{symbol} >>= @var{expression} ; ++@itemx @var{symbol} &= @var{expression} ; ++@itemx @var{symbol} |= @var{expression} ; ++@end table ++ ++The first case will define @var{symbol} to the value of ++@var{expression}. In the other cases, @var{symbol} must already be ++defined, and the value will be adjusted accordingly. ++ ++The special symbol name @samp{.} indicates the location counter. You ++may only use this within a @code{SECTIONS} command. @xref{Location Counter}. ++ ++The semicolon after @var{expression} is required. ++ ++Expressions are defined below; see @ref{Expressions}. ++ ++You may write symbol assignments as commands in their own right, or as ++statements within a @code{SECTIONS} command, or as part of an output ++section description in a @code{SECTIONS} command. ++ ++The section of the symbol will be set from the section of the ++expression; for more information, see @ref{Expression Section}. ++ ++Here is an example showing the three different places that symbol ++assignments may be used: ++ ++@smallexample ++floating_point = 0; ++SECTIONS ++@{ ++ .text : ++ @{ ++ *(.text) ++ _etext = .; ++ @} ++ _bdata = (. + 3) & ~ 3; ++ .data : @{ *(.data) @} ++@} ++@end smallexample ++@noindent ++In this example, the symbol @samp{floating_point} will be defined as ++zero. The symbol @samp{_etext} will be defined as the address following ++the last @samp{.text} input section. The symbol @samp{_bdata} will be ++defined as the address following the @samp{.text} output section aligned ++upward to a 4 byte boundary. ++ ++@node HIDDEN ++@subsection HIDDEN ++@cindex HIDDEN ++For ELF targeted ports, define a symbol that will be hidden and won't be ++exported. The syntax is @code{HIDDEN(@var{symbol} = @var{expression})}. ++ ++Here is the example from @ref{Simple Assignments}, rewritten to use ++@code{HIDDEN}: ++ ++@smallexample ++HIDDEN(floating_point = 0); ++SECTIONS ++@{ ++ .text : ++ @{ ++ *(.text) ++ HIDDEN(_etext = .); ++ @} ++ HIDDEN(_bdata = (. + 3) & ~ 3); ++ .data : @{ *(.data) @} ++@} ++@end smallexample ++@noindent ++In this case none of the three symbols will be visible outside this module. ++ ++@node PROVIDE ++@subsection PROVIDE ++@cindex PROVIDE ++In some cases, it is desirable for a linker script to define a symbol ++only if it is referenced and is not defined by any object included in ++the link. For example, traditional linkers defined the symbol ++@samp{etext}. However, ANSI C requires that the user be able to use ++@samp{etext} as a function name without encountering an error. The ++@code{PROVIDE} keyword may be used to define a symbol, such as ++@samp{etext}, only if it is referenced but not defined. The syntax is ++@code{PROVIDE(@var{symbol} = @var{expression})}. ++ ++Here is an example of using @code{PROVIDE} to define @samp{etext}: ++@smallexample ++SECTIONS ++@{ ++ .text : ++ @{ ++ *(.text) ++ _etext = .; ++ PROVIDE(etext = .); ++ @} ++@} ++@end smallexample ++ ++In this example, if the program defines @samp{_etext} (with a leading ++underscore), the linker will give a multiple definition diagnostic. If, ++on the other hand, the program defines @samp{etext} (with no leading ++underscore), the linker will silently use the definition in the program. ++If the program references @samp{etext} but does not define it, the ++linker will use the definition in the linker script. ++ ++Note - the @code{PROVIDE} directive considers a common symbol to be ++defined, even though such a symbol could be combined with the symbol ++that the @code{PROVIDE} would create. This is particularly important ++when considering constructor and destructor list symbols such as ++@samp{__CTOR_LIST__} as these are often defined as common symbols. ++ ++@node PROVIDE_HIDDEN ++@subsection PROVIDE_HIDDEN ++@cindex PROVIDE_HIDDEN ++Similar to @code{PROVIDE}. For ELF targeted ports, the symbol will be ++hidden and won't be exported. ++ ++@node Source Code Reference ++@subsection Source Code Reference ++ ++Accessing a linker script defined variable from source code is not ++intuitive. In particular a linker script symbol is not equivalent to ++a variable declaration in a high level language, it is instead a ++symbol that does not have a value. ++ ++Before going further, it is important to note that compilers often ++transform names in the source code into different names when they are ++stored in the symbol table. For example, Fortran compilers commonly ++prepend or append an underscore, and C++ performs extensive @samp{name ++mangling}. Therefore there might be a discrepancy between the name ++of a variable as it is used in source code and the name of the same ++variable as it is defined in a linker script. For example in C a ++linker script variable might be referred to as: ++ ++@smallexample ++ extern int foo; ++@end smallexample ++ ++But in the linker script it might be defined as: ++ ++@smallexample ++ _foo = 1000; ++@end smallexample ++ ++In the remaining examples however it is assumed that no name ++transformation has taken place. ++ ++When a symbol is declared in a high level language such as C, two ++things happen. The first is that the compiler reserves enough space ++in the program's memory to hold the @emph{value} of the symbol. The ++second is that the compiler creates an entry in the program's symbol ++table which holds the symbol's @emph{address}. ie the symbol table ++contains the address of the block of memory holding the symbol's ++value. So for example the following C declaration, at file scope: ++ ++@smallexample ++ int foo = 1000; ++@end smallexample ++ ++creates an entry called @samp{foo} in the symbol table. This entry ++holds the address of an @samp{int} sized block of memory where the ++number 1000 is initially stored. ++ ++When a program references a symbol the compiler generates code that ++first accesses the symbol table to find the address of the symbol's ++memory block and then code to read the value from that memory block. ++So: ++ ++@smallexample ++ foo = 1; ++@end smallexample ++ ++looks up the symbol @samp{foo} in the symbol table, gets the address ++associated with this symbol and then writes the value 1 into that ++address. Whereas: ++ ++@smallexample ++ int * a = & foo; ++@end smallexample ++ ++looks up the symbol @samp{foo} in the symbol table, gets its address ++and then copies this address into the block of memory associated with ++the variable @samp{a}. ++ ++Linker scripts symbol declarations, by contrast, create an entry in ++the symbol table but do not assign any memory to them. Thus they are ++an address without a value. So for example the linker script definition: ++ ++@smallexample ++ foo = 1000; ++@end smallexample ++ ++creates an entry in the symbol table called @samp{foo} which holds ++the address of memory location 1000, but nothing special is stored at ++address 1000. This means that you cannot access the @emph{value} of a ++linker script defined symbol - it has no value - all you can do is ++access the @emph{address} of a linker script defined symbol. ++ ++Hence when you are using a linker script defined symbol in source code ++you should always take the address of the symbol, and never attempt to ++use its value. For example suppose you want to copy the contents of a ++section of memory called .ROM into a section called .FLASH and the ++linker script contains these declarations: ++ ++@smallexample ++@group ++ start_of_ROM = .ROM; ++ end_of_ROM = .ROM + sizeof (.ROM); ++ start_of_FLASH = .FLASH; ++@end group ++@end smallexample ++ ++Then the C source code to perform the copy would be: ++ ++@smallexample ++@group ++ extern char start_of_ROM, end_of_ROM, start_of_FLASH; ++ ++ memcpy (& start_of_FLASH, & start_of_ROM, & end_of_ROM - & start_of_ROM); ++@end group ++@end smallexample ++ ++Note the use of the @samp{&} operators. These are correct. ++Alternatively the symbols can be treated as the names of vectors or ++arrays and then the code will again work as expected: ++ ++@smallexample ++@group ++ extern char start_of_ROM[], end_of_ROM[], start_of_FLASH[]; ++ ++ memcpy (start_of_FLASH, start_of_ROM, end_of_ROM - start_of_ROM); ++@end group ++@end smallexample ++ ++Note how using this method does not require the use of @samp{&} ++operators. ++ ++@node SECTIONS ++@section SECTIONS Command ++@kindex SECTIONS ++The @code{SECTIONS} command tells the linker how to map input sections ++into output sections, and how to place the output sections in memory. ++ ++The format of the @code{SECTIONS} command is: ++@smallexample ++SECTIONS ++@{ ++ @var{sections-command} ++ @var{sections-command} ++ @dots{} ++@} ++@end smallexample ++ ++Each @var{sections-command} may of be one of the following: ++ ++@itemize @bullet ++@item ++an @code{ENTRY} command (@pxref{Entry Point,,Entry command}) ++@item ++a symbol assignment (@pxref{Assignments}) ++@item ++an output section description ++@item ++an overlay description ++@end itemize ++ ++The @code{ENTRY} command and symbol assignments are permitted inside the ++@code{SECTIONS} command for convenience in using the location counter in ++those commands. This can also make the linker script easier to ++understand because you can use those commands at meaningful points in ++the layout of the output file. ++ ++Output section descriptions and overlay descriptions are described ++below. ++ ++If you do not use a @code{SECTIONS} command in your linker script, the ++linker will place each input section into an identically named output ++section in the order that the sections are first encountered in the ++input files. If all input sections are present in the first file, for ++example, the order of sections in the output file will match the order ++in the first input file. The first section will be at address zero. ++ ++@menu ++* Output Section Description:: Output section description ++* Output Section Name:: Output section name ++* Output Section Address:: Output section address ++* Input Section:: Input section description ++* Output Section Data:: Output section data ++* Output Section Keywords:: Output section keywords ++* Output Section Discarding:: Output section discarding ++* Output Section Attributes:: Output section attributes ++* Overlay Description:: Overlay description ++@end menu ++ ++@node Output Section Description ++@subsection Output Section Description ++The full description of an output section looks like this: ++@smallexample ++@group ++@var{section} [@var{address}] [(@var{type})] : ++ [AT(@var{lma})] ++ [ALIGN(@var{section_align}) | ALIGN_WITH_INPUT] ++ [SUBALIGN(@var{subsection_align})] ++ [@var{constraint}] ++ @{ ++ @var{output-section-command} ++ @var{output-section-command} ++ @dots{} ++ @} [>@var{region}] [AT>@var{lma_region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}] [,] ++@end group ++@end smallexample ++ ++Most output sections do not use most of the optional section attributes. ++ ++The whitespace around @var{section} is required, so that the section ++name is unambiguous. The colon and the curly braces are also required. ++The comma at the end may be required if a @var{fillexp} is used and ++the next @var{sections-command} looks like a continuation of the expression. ++The line breaks and other white space are optional. ++ ++Each @var{output-section-command} may be one of the following: ++ ++@itemize @bullet ++@item ++a symbol assignment (@pxref{Assignments}) ++@item ++an input section description (@pxref{Input Section}) ++@item ++data values to include directly (@pxref{Output Section Data}) ++@item ++a special output section keyword (@pxref{Output Section Keywords}) ++@end itemize ++ ++@node Output Section Name ++@subsection Output Section Name ++@cindex name, section ++@cindex section name ++The name of the output section is @var{section}. @var{section} must ++meet the constraints of your output format. In formats which only ++support a limited number of sections, such as @code{a.out}, the name ++must be one of the names supported by the format (@code{a.out}, for ++example, allows only @samp{.text}, @samp{.data} or @samp{.bss}). If the ++output format supports any number of sections, but with numbers and not ++names (as is the case for Oasys), the name should be supplied as a ++quoted numeric string. A section name may consist of any sequence of ++characters, but a name which contains any unusual characters such as ++commas must be quoted. ++ ++The output section name @samp{/DISCARD/} is special; @ref{Output Section ++Discarding}. ++ ++@node Output Section Address ++@subsection Output Section Address ++@cindex address, section ++@cindex section address ++The @var{address} is an expression for the VMA (the virtual memory ++address) of the output section. This address is optional, but if it ++is provided then the output address will be set exactly as specified. ++ ++If the output address is not specified then one will be chosen for the ++section, based on the heuristic below. This address will be adjusted ++to fit the alignment requirement of the output section. The ++alignment requirement is the strictest alignment of any input section ++contained within the output section. ++ ++The output section address heuristic is as follows: ++ ++@itemize @bullet ++@item ++If an output memory @var{region} is set for the section then it ++is added to this region and its address will be the next free address ++in that region. ++ ++@item ++If the MEMORY command has been used to create a list of memory ++regions then the first region which has attributes compatible with the ++section is selected to contain it. The section's output address will ++be the next free address in that region; @ref{MEMORY}. ++ ++@item ++If no memory regions were specified, or none match the section then ++the output address will be based on the current value of the location ++counter. ++@end itemize ++ ++@noindent ++For example: ++ ++@smallexample ++.text . : @{ *(.text) @} ++@end smallexample ++ ++@noindent ++and ++ ++@smallexample ++.text : @{ *(.text) @} ++@end smallexample ++ ++@noindent ++are subtly different. The first will set the address of the ++@samp{.text} output section to the current value of the location ++counter. The second will set it to the current value of the location ++counter aligned to the strictest alignment of any of the @samp{.text} ++input sections. ++ ++The @var{address} may be an arbitrary expression; @ref{Expressions}. ++For example, if you want to align the section on a 0x10 byte boundary, ++so that the lowest four bits of the section address are zero, you could ++do something like this: ++@smallexample ++.text ALIGN(0x10) : @{ *(.text) @} ++@end smallexample ++@noindent ++This works because @code{ALIGN} returns the current location counter ++aligned upward to the specified value. ++ ++Specifying @var{address} for a section will change the value of the ++location counter, provided that the section is non-empty. (Empty ++sections are ignored). ++ ++@node Input Section ++@subsection Input Section Description ++@cindex input sections ++@cindex mapping input sections to output sections ++The most common output section command is an input section description. ++ ++The input section description is the most basic linker script operation. ++You use output sections to tell the linker how to lay out your program ++in memory. You use input section descriptions to tell the linker how to ++map the input files into your memory layout. ++ ++@menu ++* Input Section Basics:: Input section basics ++* Input Section Wildcards:: Input section wildcard patterns ++* Input Section Common:: Input section for common symbols ++* Input Section Keep:: Input section and garbage collection ++* Input Section Example:: Input section example ++@end menu ++ ++@node Input Section Basics ++@subsubsection Input Section Basics ++@cindex input section basics ++An input section description consists of a file name optionally followed ++by a list of section names in parentheses. ++ ++The file name and the section name may be wildcard patterns, which we ++describe further below (@pxref{Input Section Wildcards}). ++ ++The most common input section description is to include all input ++sections with a particular name in the output section. For example, to ++include all input @samp{.text} sections, you would write: ++@smallexample ++*(.text) ++@end smallexample ++@noindent ++Here the @samp{*} is a wildcard which matches any file name. To exclude a list ++@cindex EXCLUDE_FILE ++of files from matching the file name wildcard, EXCLUDE_FILE may be used to ++match all files except the ones specified in the EXCLUDE_FILE list. For ++example: ++@smallexample ++EXCLUDE_FILE (*crtend.o *otherfile.o) *(.ctors) ++@end smallexample ++@noindent ++will cause all .ctors sections from all files except @file{crtend.o} ++and @file{otherfile.o} to be included. The EXCLUDE_FILE can also be ++placed inside the section list, for example: ++@smallexample ++*(EXCLUDE_FILE (*crtend.o *otherfile.o) .ctors) ++@end smallexample ++@noindent ++The result of this is identically to the previous example. Supporting ++two syntaxes for EXCLUDE_FILE is useful if the section list contains ++more than one section, as described below. ++ ++There are two ways to include more than one section: ++@smallexample ++*(.text .rdata) ++*(.text) *(.rdata) ++@end smallexample ++@noindent ++The difference between these is the order in which the @samp{.text} and ++@samp{.rdata} input sections will appear in the output section. In the ++first example, they will be intermingled, appearing in the same order as ++they are found in the linker input. In the second example, all ++@samp{.text} input sections will appear first, followed by all ++@samp{.rdata} input sections. ++ ++When using EXCLUDE_FILE with more than one section, if the exclusion ++is within the section list then the exclusion only applies to the ++immediately following section, for example: ++@smallexample ++*(EXCLUDE_FILE (*somefile.o) .text .rdata) ++@end smallexample ++@noindent ++will cause all @samp{.text} sections from all files except ++@file{somefile.o} to be included, while all @samp{.rdata} sections ++from all files, including @file{somefile.o}, will be included. To ++exclude the @samp{.rdata} sections from @file{somefile.o} the example ++could be modified to: ++@smallexample ++*(EXCLUDE_FILE (*somefile.o) .text EXCLUDE_FILE (*somefile.o) .rdata) ++@end smallexample ++@noindent ++Alternatively, placing the EXCLUDE_FILE outside of the section list, ++before the input file selection, will cause the exclusion to apply for ++all sections. Thus the previous example can be rewritten as: ++@smallexample ++EXCLUDE_FILE (*somefile.o) *(.text .rdata) ++@end smallexample ++ ++You can specify a file name to include sections from a particular file. ++You would do this if one or more of your files contain special data that ++needs to be at a particular location in memory. For example: ++@smallexample ++data.o(.data) ++@end smallexample ++ ++To refine the sections that are included based on the section flags ++of an input section, INPUT_SECTION_FLAGS may be used. ++ ++Here is a simple example for using Section header flags for ELF sections: ++ ++@smallexample ++@group ++SECTIONS @{ ++ .text : @{ INPUT_SECTION_FLAGS (SHF_MERGE & SHF_STRINGS) *(.text) @} ++ .text2 : @{ INPUT_SECTION_FLAGS (!SHF_WRITE) *(.text) @} ++@} ++@end group ++@end smallexample ++ ++In this example, the output section @samp{.text} will be comprised of any ++input section matching the name *(.text) whose section header flags ++@code{SHF_MERGE} and @code{SHF_STRINGS} are set. The output section ++@samp{.text2} will be comprised of any input section matching the name *(.text) ++whose section header flag @code{SHF_WRITE} is clear. ++ ++You can also specify files within archives by writing a pattern ++matching the archive, a colon, then the pattern matching the file, ++with no whitespace around the colon. ++ ++@table @samp ++@item archive:file ++matches file within archive ++@item archive: ++matches the whole archive ++@item :file ++matches file but not one in an archive ++@end table ++ ++Either one or both of @samp{archive} and @samp{file} can contain shell ++wildcards. On DOS based file systems, the linker will assume that a ++single letter followed by a colon is a drive specifier, so ++@samp{c:myfile.o} is a simple file specification, not @samp{myfile.o} ++within an archive called @samp{c}. @samp{archive:file} filespecs may ++also be used within an @code{EXCLUDE_FILE} list, but may not appear in ++other linker script contexts. For instance, you cannot extract a file ++from an archive by using @samp{archive:file} in an @code{INPUT} ++command. ++ ++If you use a file name without a list of sections, then all sections in ++the input file will be included in the output section. This is not ++commonly done, but it may by useful on occasion. For example: ++@smallexample ++data.o ++@end smallexample ++ ++When you use a file name which is not an @samp{archive:file} specifier ++and does not contain any wild card ++characters, the linker will first see if you also specified the file ++name on the linker command line or in an @code{INPUT} command. If you ++did not, the linker will attempt to open the file as an input file, as ++though it appeared on the command line. Note that this differs from an ++@code{INPUT} command, because the linker will not search for the file in ++the archive search path. ++ ++@node Input Section Wildcards ++@subsubsection Input Section Wildcard Patterns ++@cindex input section wildcards ++@cindex wildcard file name patterns ++@cindex file name wildcard patterns ++@cindex section name wildcard patterns ++In an input section description, either the file name or the section ++name or both may be wildcard patterns. ++ ++The file name of @samp{*} seen in many examples is a simple wildcard ++pattern for the file name. ++ ++The wildcard patterns are like those used by the Unix shell. ++ ++@table @samp ++@item * ++matches any number of characters ++@item ? ++matches any single character ++@item [@var{chars}] ++matches a single instance of any of the @var{chars}; the @samp{-} ++character may be used to specify a range of characters, as in ++@samp{[a-z]} to match any lower case letter ++@item \ ++quotes the following character ++@end table ++ ++File name wildcard patterns only match files which are explicitly ++specified on the command line or in an @code{INPUT} command. The linker ++does not search directories to expand wildcards. ++ ++If a file name matches more than one wildcard pattern, or if a file name ++appears explicitly and is also matched by a wildcard pattern, the linker ++will use the first match in the linker script. For example, this ++sequence of input section descriptions is probably in error, because the ++@file{data.o} rule will not be used: ++@smallexample ++.data : @{ *(.data) @} ++.data1 : @{ data.o(.data) @} ++@end smallexample ++ ++@cindex SORT_BY_NAME ++Normally, the linker will place files and sections matched by wildcards ++in the order in which they are seen during the link. You can change ++this by using the @code{SORT_BY_NAME} keyword, which appears before a wildcard ++pattern in parentheses (e.g., @code{SORT_BY_NAME(.text*)}). When the ++@code{SORT_BY_NAME} keyword is used, the linker will sort the files or sections ++into ascending order by name before placing them in the output file. ++ ++@cindex SORT_BY_ALIGNMENT ++@code{SORT_BY_ALIGNMENT} is similar to @code{SORT_BY_NAME}. ++@code{SORT_BY_ALIGNMENT} will sort sections into descending order of ++alignment before placing them in the output file. Placing larger ++alignments before smaller alignments can reduce the amount of padding ++needed. ++ ++@cindex SORT_BY_INIT_PRIORITY ++@code{SORT_BY_INIT_PRIORITY} is also similar to @code{SORT_BY_NAME}. ++@code{SORT_BY_INIT_PRIORITY} will sort sections into ascending ++numerical order of the GCC init_priority attribute encoded in the ++section name before placing them in the output file. In ++@code{.init_array.NNNNN} and @code{.fini_array.NNNNN}, @code{NNNNN} is ++the init_priority. In @code{.ctors.NNNNN} and @code{.dtors.NNNNN}, ++@code{NNNNN} is 65535 minus the init_priority. ++ ++@cindex SORT ++@code{SORT} is an alias for @code{SORT_BY_NAME}. ++ ++When there are nested section sorting commands in linker script, there ++can be at most 1 level of nesting for section sorting commands. ++ ++@enumerate ++@item ++@code{SORT_BY_NAME} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)). ++It will sort the input sections by name first, then by alignment if two ++sections have the same name. ++@item ++@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_NAME} (wildcard section pattern)). ++It will sort the input sections by alignment first, then by name if two ++sections have the same alignment. ++@item ++@code{SORT_BY_NAME} (@code{SORT_BY_NAME} (wildcard section pattern)) is ++treated the same as @code{SORT_BY_NAME} (wildcard section pattern). ++@item ++@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)) ++is treated the same as @code{SORT_BY_ALIGNMENT} (wildcard section pattern). ++@item ++All other nested section sorting commands are invalid. ++@end enumerate ++ ++When both command-line section sorting option and linker script ++section sorting command are used, section sorting command always ++takes precedence over the command-line option. ++ ++If the section sorting command in linker script isn't nested, the ++command-line option will make the section sorting command to be ++treated as nested sorting command. ++ ++@enumerate ++@item ++@code{SORT_BY_NAME} (wildcard section pattern ) with ++@option{--sort-sections alignment} is equivalent to ++@code{SORT_BY_NAME} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)). ++@item ++@code{SORT_BY_ALIGNMENT} (wildcard section pattern) with ++@option{--sort-section name} is equivalent to ++@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_NAME} (wildcard section pattern)). ++@end enumerate ++ ++If the section sorting command in linker script is nested, the ++command-line option will be ignored. ++ ++@cindex SORT_NONE ++@code{SORT_NONE} disables section sorting by ignoring the command-line ++section sorting option. ++ ++If you ever get confused about where input sections are going, use the ++@samp{-M} linker option to generate a map file. The map file shows ++precisely how input sections are mapped to output sections. ++ ++This example shows how wildcard patterns might be used to partition ++files. This linker script directs the linker to place all @samp{.text} ++sections in @samp{.text} and all @samp{.bss} sections in @samp{.bss}. ++The linker will place the @samp{.data} section from all files beginning ++with an upper case character in @samp{.DATA}; for all other files, the ++linker will place the @samp{.data} section in @samp{.data}. ++@smallexample ++@group ++SECTIONS @{ ++ .text : @{ *(.text) @} ++ .DATA : @{ [A-Z]*(.data) @} ++ .data : @{ *(.data) @} ++ .bss : @{ *(.bss) @} ++@} ++@end group ++@end smallexample ++ ++@node Input Section Common ++@subsubsection Input Section for Common Symbols ++@cindex common symbol placement ++@cindex uninitialized data placement ++A special notation is needed for common symbols, because in many object ++file formats common symbols do not have a particular input section. The ++linker treats common symbols as though they are in an input section ++named @samp{COMMON}. ++ ++You may use file names with the @samp{COMMON} section just as with any ++other input sections. You can use this to place common symbols from a ++particular input file in one section while common symbols from other ++input files are placed in another section. ++ ++In most cases, common symbols in input files will be placed in the ++@samp{.bss} section in the output file. For example: ++@smallexample ++.bss @{ *(.bss) *(COMMON) @} ++@end smallexample ++ ++@cindex scommon section ++@cindex small common symbols ++Some object file formats have more than one type of common symbol. For ++example, the MIPS ELF object file format distinguishes standard common ++symbols and small common symbols. In this case, the linker will use a ++different special section name for other types of common symbols. In ++the case of MIPS ELF, the linker uses @samp{COMMON} for standard common ++symbols and @samp{.scommon} for small common symbols. This permits you ++to map the different types of common symbols into memory at different ++locations. ++ ++@cindex [COMMON] ++You will sometimes see @samp{[COMMON]} in old linker scripts. This ++notation is now considered obsolete. It is equivalent to ++@samp{*(COMMON)}. ++ ++@node Input Section Keep ++@subsubsection Input Section and Garbage Collection ++@cindex KEEP ++@cindex garbage collection ++When link-time garbage collection is in use (@samp{--gc-sections}), ++it is often useful to mark sections that should not be eliminated. ++This is accomplished by surrounding an input section's wildcard entry ++with @code{KEEP()}, as in @code{KEEP(*(.init))} or ++@code{KEEP(SORT_BY_NAME(*)(.ctors))}. ++ ++@node Input Section Example ++@subsubsection Input Section Example ++The following example is a complete linker script. It tells the linker ++to read all of the sections from file @file{all.o} and place them at the ++start of output section @samp{outputa} which starts at location ++@samp{0x10000}. All of section @samp{.input1} from file @file{foo.o} ++follows immediately, in the same output section. All of section ++@samp{.input2} from @file{foo.o} goes into output section ++@samp{outputb}, followed by section @samp{.input1} from @file{foo1.o}. ++All of the remaining @samp{.input1} and @samp{.input2} sections from any ++files are written to output section @samp{outputc}. ++ ++@smallexample ++@group ++SECTIONS @{ ++ outputa 0x10000 : ++ @{ ++ all.o ++ foo.o (.input1) ++ @} ++@end group ++@group ++ outputb : ++ @{ ++ foo.o (.input2) ++ foo1.o (.input1) ++ @} ++@end group ++@group ++ outputc : ++ @{ ++ *(.input1) ++ *(.input2) ++ @} ++@} ++@end group ++@end smallexample ++ ++If an output section's name is the same as the input section's name ++and is representable as a C identifier, then the linker will ++automatically @pxref{PROVIDE} two symbols: __start_SECNAME and ++__stop_SECNAME, where SECNAME is the name of the section. These ++indicate the start address and end address of the output section ++respectively. Note: most section names are not representable as ++C identifiers because they contain a @samp{.} character. ++ ++@node Output Section Data ++@subsection Output Section Data ++@cindex data ++@cindex section data ++@cindex output section data ++@kindex ASCIZ ``@var{string}'' ++@kindex BYTE(@var{expression}) ++@kindex SHORT(@var{expression}) ++@kindex LONG(@var{expression}) ++@kindex QUAD(@var{expression}) ++@kindex SQUAD(@var{expression}) ++You can include explicit bytes of data in an output section by using ++@code{BYTE}, @code{SHORT}, @code{LONG}, @code{QUAD}, or @code{SQUAD} as ++an output section command. Each keyword is followed by an expression in ++parentheses providing the value to store (@pxref{Expressions}). The ++value of the expression is stored at the current value of the location ++counter. ++ ++The @code{BYTE}, @code{SHORT}, @code{LONG}, and @code{QUAD} commands ++store one, two, four, and eight bytes (respectively). After storing the ++bytes, the location counter is incremented by the number of bytes ++stored. ++ ++For example, this will store the byte 1 followed by the four byte value ++of the symbol @samp{addr}: ++@smallexample ++BYTE(1) ++LONG(addr) ++@end smallexample ++ ++When using a 64 bit host or target, @code{QUAD} and @code{SQUAD} are the ++same; they both store an 8 byte, or 64 bit, value. When both host and ++target are 32 bits, an expression is computed as 32 bits. In this case ++@code{QUAD} stores a 32 bit value zero extended to 64 bits, and ++@code{SQUAD} stores a 32 bit value sign extended to 64 bits. ++ ++If the object file format of the output file has an explicit endianness, ++which is the normal case, the value will be stored in that endianness. ++When the object file format does not have an explicit endianness, as is ++true of, for example, S-records, the value will be stored in the ++endianness of the first input object file. ++ ++You can include a zero-terminated string in an output section by using ++@code{ASCIZ}. The keyword is followed by a string which is stored at ++the current value of the location counter adding a zero byte at the ++end. If the string includes spaces it must be enclosed in double ++quotes. The string may contain '\n', '\r', '\t' and octal numbers. ++Hex numbers are not supported. ++ ++For example, this string of 16 characters will create a 17 byte area ++@smallexample ++ ASCIZ "This is 16 bytes" ++@end smallexample ++ ++Note---these commands only work inside a section description and not ++between them, so the following will produce an error from the linker: ++@smallexample ++SECTIONS @{@ .text : @{@ *(.text) @}@ LONG(1) .data : @{@ *(.data) @}@ @}@ ++@end smallexample ++whereas this will work: ++@smallexample ++SECTIONS @{@ .text : @{@ *(.text) ; LONG(1) @}@ .data : @{@ *(.data) @}@ @}@ ++@end smallexample ++ ++@kindex FILL(@var{expression}) ++@cindex holes, filling ++@cindex unspecified memory ++You may use the @code{FILL} command to set the fill pattern for the ++current section. It is followed by an expression in parentheses. Any ++otherwise unspecified regions of memory within the section (for example, ++gaps left due to the required alignment of input sections) are filled ++with the value of the expression, repeated as ++necessary. A @code{FILL} statement covers memory locations after the ++point at which it occurs in the section definition; by including more ++than one @code{FILL} statement, you can have different fill patterns in ++different parts of an output section. ++ ++This example shows how to fill unspecified regions of memory with the ++value @samp{0x90}: ++@smallexample ++FILL(0x90909090) ++@end smallexample ++ ++The @code{FILL} command is similar to the @samp{=@var{fillexp}} output ++section attribute, but it only affects the ++part of the section following the @code{FILL} command, rather than the ++entire section. If both are used, the @code{FILL} command takes ++precedence. @xref{Output Section Fill}, for details on the fill ++expression. ++ ++@kindex LINKER_VERSION ++@cindex LINKER_VERSION ++Inserts a string containing the version of the linker at the current ++point. Note - by default this directive is disabled and will do ++nothing. It only becomes active if the ++@option{--enable-linker-version} command line option is used. ++ ++Built-in linker scripts for ELF based targets already include this ++directive in their @samp{.comment} section. ++ ++@node Output Section Keywords ++@subsection Output Section Keywords ++There are a couple of keywords which can appear as output section ++commands. ++ ++@table @code ++@kindex CREATE_OBJECT_SYMBOLS ++@cindex input filename symbols ++@cindex filename symbols ++@item CREATE_OBJECT_SYMBOLS ++The command tells the linker to create a symbol for each input file. ++The name of each symbol will be the name of the corresponding input ++file. The section of each symbol will be the output section in which ++the @code{CREATE_OBJECT_SYMBOLS} command appears. ++ ++This is conventional for the a.out object file format. It is not ++normally used for any other object file format. ++ ++@kindex CONSTRUCTORS ++@cindex C++ constructors, arranging in link ++@cindex constructors, arranging in link ++@item CONSTRUCTORS ++When linking using the a.out object file format, the linker uses an ++unusual set construct to support C++ global constructors and ++destructors. When linking object file formats which do not support ++arbitrary sections, such as ECOFF and XCOFF, the linker will ++automatically recognize C++ global constructors and destructors by name. ++For these object file formats, the @code{CONSTRUCTORS} command tells the ++linker to place constructor information in the output section where the ++@code{CONSTRUCTORS} command appears. The @code{CONSTRUCTORS} command is ++ignored for other object file formats. ++ ++The symbol @w{@code{__CTOR_LIST__}} marks the start of the global ++constructors, and the symbol @w{@code{__CTOR_END__}} marks the end. ++Similarly, @w{@code{__DTOR_LIST__}} and @w{@code{__DTOR_END__}} mark ++the start and end of the global destructors. The ++first word in the list is the number of entries, followed by the address ++of each constructor or destructor, followed by a zero word. The ++compiler must arrange to actually run the code. For these object file ++formats @sc{gnu} C++ normally calls constructors from a subroutine ++@code{__main}; a call to @code{__main} is automatically inserted into ++the startup code for @code{main}. @sc{gnu} C++ normally runs ++destructors either by using @code{atexit}, or directly from the function ++@code{exit}. ++ ++For object file formats such as @code{COFF} or @code{ELF} which support ++arbitrary section names, @sc{gnu} C++ will normally arrange to put the ++addresses of global constructors and destructors into the @code{.ctors} ++and @code{.dtors} sections. Placing the following sequence into your ++linker script will build the sort of table which the @sc{gnu} C++ ++runtime code expects to see. ++ ++@smallexample ++ __CTOR_LIST__ = .; ++ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) ++ *(.ctors) ++ LONG(0) ++ __CTOR_END__ = .; ++ __DTOR_LIST__ = .; ++ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) ++ *(.dtors) ++ LONG(0) ++ __DTOR_END__ = .; ++@end smallexample ++ ++If you are using the @sc{gnu} C++ support for initialization priority, ++which provides some control over the order in which global constructors ++are run, you must sort the constructors at link time to ensure that they ++are executed in the correct order. When using the @code{CONSTRUCTORS} ++command, use @samp{SORT_BY_NAME(CONSTRUCTORS)} instead. When using the ++@code{.ctors} and @code{.dtors} sections, use @samp{*(SORT_BY_NAME(.ctors))} and ++@samp{*(SORT_BY_NAME(.dtors))} instead of just @samp{*(.ctors)} and ++@samp{*(.dtors)}. ++ ++Normally the compiler and linker will handle these issues automatically, ++and you will not need to concern yourself with them. However, you may ++need to consider this if you are using C++ and writing your own linker ++scripts. ++ ++@end table ++ ++@node Output Section Discarding ++@subsection Output Section Discarding ++@cindex discarding sections ++@cindex sections, discarding ++@cindex removing sections ++The linker will not normally create output sections with no contents. ++This is for convenience when referring to input sections that may or ++may not be present in any of the input files. For example: ++@smallexample ++.foo : @{ *(.foo) @} ++@end smallexample ++@noindent ++will only create a @samp{.foo} section in the output file if there is a ++@samp{.foo} section in at least one input file, and if the input ++sections are not all empty. Other link script directives that allocate ++space in an output section will also create the output section. So ++too will assignments to dot even if the assignment does not create ++space, except for @samp{. = 0}, @samp{. = . + 0}, @samp{. = sym}, ++@samp{. = . + sym} and @samp{. = ALIGN (. != 0, expr, 1)} when ++@samp{sym} is an absolute symbol of value 0 defined in the script. ++This allows you to force output of an empty section with @samp{. = .}. ++ ++The linker will ignore address assignments (@pxref{Output Section Address}) ++on discarded output sections, except when the linker script defines ++symbols in the output section. In that case the linker will obey ++the address assignments, possibly advancing dot even though the ++section is discarded. ++ ++@cindex /DISCARD/ ++The special output section name @samp{/DISCARD/} may be used to discard ++input sections. Any input sections which are assigned to an output ++section named @samp{/DISCARD/} are not included in the output file. ++ ++This can be used to discard input sections marked with the ELF flag ++@code{SHF_GNU_RETAIN}, which would otherwise have been saved from linker ++garbage collection. ++ ++Note, sections that match the @samp{/DISCARD/} output section will be ++discarded even if they are in an ELF section group which has other ++members which are not being discarded. This is deliberate. ++Discarding takes precedence over grouping. ++ ++@node Output Section Attributes ++@subsection Output Section Attributes ++@cindex output section attributes ++We showed above that the full description of an output section looked ++like this: ++ ++@smallexample ++@group ++@var{section} [@var{address}] [(@var{type})] : ++ [AT(@var{lma})] ++ [ALIGN(@var{section_align}) | ALIGN_WITH_INPUT] ++ [SUBALIGN(@var{subsection_align})] ++ [@var{constraint}] ++ @{ ++ @var{output-section-command} ++ @var{output-section-command} ++ @dots{} ++ @} [>@var{region}] [AT>@var{lma_region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}] ++@end group ++@end smallexample ++ ++We've already described @var{section}, @var{address}, and ++@var{output-section-command}. In this section we will describe the ++remaining section attributes. ++ ++@menu ++* Output Section Type:: Output section type ++* Output Section LMA:: Output section LMA ++* Forced Output Alignment:: Forced Output Alignment ++* Forced Input Alignment:: Forced Input Alignment ++* Output Section Constraint:: Output section constraint ++* Output Section Region:: Output section region ++* Output Section Phdr:: Output section phdr ++* Output Section Fill:: Output section fill ++@end menu ++ ++@node Output Section Type ++@subsubsection Output Section Type ++Each output section may have a type. The type is a keyword in ++parentheses. The following types are defined: ++ ++@table @code ++ ++@item NOLOAD ++The section should be marked as not loadable, so that it will not be ++loaded into memory when the program is run. ++ ++@item READONLY ++The section should be marked as read-only. ++ ++@item DSECT ++@item COPY ++@item INFO ++@item OVERLAY ++These type names are supported for backward compatibility, and are ++rarely used. They all have the same effect: the section should be ++marked as not allocatable, so that no memory is allocated for the ++section when the program is run. ++ ++@item TYPE = @var{type} ++Set the section type to the integer @var{type}. When generating an ELF ++output file, type names @code{SHT_PROGBITS}, @code{SHT_STRTAB}, ++@code{SHT_NOTE}, @code{SHT_NOBITS}, @code{SHT_INIT_ARRAY}, ++@code{SHT_FINI_ARRAY}, and @code{SHT_PREINIT_ARRAY} are also allowed ++for @var{type}. It is the user's responsibility to ensure that any ++special requirements of the section type are met. ++ ++Note - the TYPE only is used if some or all of the contents of the ++section do not have an implicit type of their own. So for example: ++@smallexample ++ .foo . TYPE = SHT_PROGBITS @{ *(.bar) @} ++@end smallexample ++will set the type of section @samp{.foo} to the type of the section ++@samp{.bar} in the input files, which may not be the SHT_PROGBITS ++type. Whereas: ++@smallexample ++ .foo . TYPE = SHT_PROGBITS @{ BYTE(1) @} ++@end smallexample ++will set the type of @samp{.foo} to SHT_PROGBBITS. If it is necessary ++to override the type of incoming sections and force the output section ++type then an extra piece of untyped data will be needed: ++@smallexample ++ .foo . TYPE = SHT_PROGBITS @{ BYTE(1); *(.bar) @} ++@end smallexample ++ ++@item READONLY ( TYPE = @var{type} ) ++This form of the syntax combines the @var{READONLY} type with the ++type specified by @var{type}. ++ ++@end table ++ ++@kindex NOLOAD ++@cindex prevent unnecessary loading ++@cindex loading, preventing ++The linker normally sets the attributes of an output section based on ++the input sections which map into it. You can override this by using ++the section type. For example, in the script sample below, the ++@samp{ROM} section is addressed at memory location @samp{0} and does not ++need to be loaded when the program is run. ++@smallexample ++@group ++SECTIONS @{ ++ ROM 0 (NOLOAD) : @{ @dots{} @} ++ @dots{} ++@} ++@end group ++@end smallexample ++ ++@node Output Section LMA ++@subsubsection Output Section LMA ++@kindex AT>@var{lma_region} ++@kindex AT(@var{lma}) ++@cindex load address ++@cindex section load address ++Every section has a virtual address (VMA) and a load address (LMA); see ++@ref{Basic Script Concepts}. The virtual address is specified by the ++@pxref{Output Section Address} described earlier. The load address is ++specified by the @code{AT} or @code{AT>} keywords. Specifying a load ++address is optional. ++ ++The @code{AT} keyword takes an expression as an argument. This ++specifies the exact load address of the section. The @code{AT>} keyword ++takes the name of a memory region as an argument. @xref{MEMORY}. The ++load address of the section is set to the next free address in the ++region, aligned to the section's alignment requirements. ++ ++If neither @code{AT} nor @code{AT>} is specified for an allocatable ++section, the linker will use the following heuristic to determine the ++load address: ++ ++@itemize @bullet ++@item ++If the section has a specific VMA address, then this is used as ++the LMA address as well. ++ ++@item ++If the section is not allocatable then its LMA is set to its VMA. ++ ++@item ++Otherwise if a memory region can be found that is compatible ++with the current section, and this region contains at least one ++section, then the LMA is set so the difference between the ++VMA and LMA is the same as the difference between the VMA and LMA of ++the last section in the located region. ++ ++@item ++If no memory regions have been declared then a default region ++that covers the entire address space is used in the previous step. ++ ++@item ++If no suitable region could be found, or there was no previous ++section then the LMA is set equal to the VMA. ++@end itemize ++ ++@cindex ROM initialized data ++@cindex initialized data in ROM ++This feature is designed to make it easy to build a ROM image. For ++example, the following linker script creates three output sections: one ++called @samp{.text}, which starts at @code{0x1000}, one called ++@samp{.mdata}, which is loaded at the end of the @samp{.text} section ++even though its VMA is @code{0x2000}, and one called @samp{.bss} to hold ++uninitialized data at address @code{0x3000}. The symbol @code{_data} is ++defined with the value @code{0x2000}, which shows that the location ++counter holds the VMA value, not the LMA value. ++ ++@smallexample ++@group ++SECTIONS ++ @{ ++ .text 0x1000 : @{ *(.text) _etext = . ; @} ++ .mdata 0x2000 : ++ AT ( ADDR (.text) + SIZEOF (.text) ) ++ @{ _data = . ; *(.data); _edata = . ; @} ++ .bss 0x3000 : ++ @{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;@} ++@} ++@end group ++@end smallexample ++ ++The run-time initialization code for use with a program generated with ++this linker script would include something like the following, to copy ++the initialized data from the ROM image to its runtime address. Notice ++how this code takes advantage of the symbols defined by the linker ++script. ++ ++@smallexample ++@group ++extern char _etext, _data, _edata, _bstart, _bend; ++char *src = &_etext; ++char *dst = &_data; ++ ++/* ROM has data at end of text; copy it. */ ++while (dst < &_edata) ++ *dst++ = *src++; ++ ++/* Zero bss. */ ++for (dst = &_bstart; dst< &_bend; dst++) ++ *dst = 0; ++@end group ++@end smallexample ++ ++@node Forced Output Alignment ++@subsubsection Forced Output Alignment ++@kindex ALIGN(@var{section_align}) ++@cindex forcing output section alignment ++@cindex output section alignment ++You can increase an output section's alignment by using ALIGN. As an ++alternative you can enforce that the difference between the VMA and LMA remains ++intact throughout this output section with the ALIGN_WITH_INPUT attribute. ++ ++@node Forced Input Alignment ++@subsubsection Forced Input Alignment ++@kindex SUBALIGN(@var{subsection_align}) ++@cindex forcing input section alignment ++@cindex input section alignment ++You can force input section alignment within an output section by using ++SUBALIGN. The value specified overrides any alignment given by input ++sections, whether larger or smaller. ++ ++@node Output Section Constraint ++@subsubsection Output Section Constraint ++@kindex ONLY_IF_RO ++@kindex ONLY_IF_RW ++@cindex constraints on output sections ++You can specify that an output section should only be created if all ++of its input sections are read-only or all of its input sections are ++read-write by using the keyword @code{ONLY_IF_RO} and ++@code{ONLY_IF_RW} respectively. ++ ++@node Output Section Region ++@subsubsection Output Section Region ++@kindex >@var{region} ++@cindex section, assigning to memory region ++@cindex memory regions and sections ++You can assign a section to a previously defined region of memory by ++using @samp{>@var{region}}. @xref{MEMORY}. ++ ++Here is a simple example: ++@smallexample ++@group ++MEMORY @{ rom : ORIGIN = 0x1000, LENGTH = 0x1000 @} ++SECTIONS @{ ROM : @{ *(.text) @} >rom @} ++@end group ++@end smallexample ++ ++@node Output Section Phdr ++@subsubsection Output Section Phdr ++@kindex :@var{phdr} ++@cindex section, assigning to program header ++@cindex program headers and sections ++You can assign a section to a previously defined program segment by ++using @samp{:@var{phdr}}. @xref{PHDRS}. If a section is assigned to ++one or more segments, then all subsequent allocated sections will be ++assigned to those segments as well, unless they use an explicitly ++@code{:@var{phdr}} modifier. You can use @code{:NONE} to tell the ++linker to not put the section in any segment at all. ++ ++Here is a simple example: ++@smallexample ++@group ++PHDRS @{ text PT_LOAD ; @} ++SECTIONS @{ .text : @{ *(.text) @} :text @} ++@end group ++@end smallexample ++ ++@node Output Section Fill ++@subsubsection Output Section Fill ++@kindex =@var{fillexp} ++@cindex section fill pattern ++@cindex fill pattern, entire section ++You can set the fill pattern for an entire section by using ++@samp{=@var{fillexp}}. @var{fillexp} is an expression ++(@pxref{Expressions}). Any otherwise unspecified regions of memory ++within the output section (for example, gaps left due to the required ++alignment of input sections) will be filled with the value, repeated as ++necessary. If the fill expression is a simple hex number, ie. a string ++of hex digit starting with @samp{0x} and without a trailing @samp{k} or @samp{M}, then ++an arbitrarily long sequence of hex digits can be used to specify the ++fill pattern; Leading zeros become part of the pattern too. For all ++other cases, including extra parentheses or a unary @code{+}, the fill ++pattern is the four least significant bytes of the value of the ++expression. In all cases, the number is big-endian. ++ ++You can also change the fill value with a @code{FILL} command in the ++output section commands; (@pxref{Output Section Data}). ++ ++Here is a simple example: ++@smallexample ++@group ++SECTIONS @{ .text : @{ *(.text) @} =0x90909090 @} ++@end group ++@end smallexample ++ ++@node Overlay Description ++@subsection Overlay Description ++@kindex OVERLAY ++@cindex overlays ++An overlay description provides an easy way to describe sections which ++are to be loaded as part of a single memory image but are to be run at ++the same memory address. At run time, some sort of overlay manager will ++copy the overlaid sections in and out of the runtime memory address as ++required, perhaps by simply manipulating addressing bits. This approach ++can be useful, for example, when a certain region of memory is faster ++than another. ++ ++Overlays are described using the @code{OVERLAY} command. The ++@code{OVERLAY} command is used within a @code{SECTIONS} command, like an ++output section description. The full syntax of the @code{OVERLAY} ++command is as follows: ++@smallexample ++@group ++OVERLAY [@var{start}] : [NOCROSSREFS] [AT ( @var{ldaddr} )] ++ @{ ++ @var{secname1} ++ @{ ++ @var{output-section-command} ++ @var{output-section-command} ++ @dots{} ++ @} [:@var{phdr}@dots{}] [=@var{fill}] ++ @var{secname2} ++ @{ ++ @var{output-section-command} ++ @var{output-section-command} ++ @dots{} ++ @} [:@var{phdr}@dots{}] [=@var{fill}] ++ @dots{} ++ @} [>@var{region}] [:@var{phdr}@dots{}] [=@var{fill}] [,] ++@end group ++@end smallexample ++ ++Everything is optional except @code{OVERLAY} (a keyword), and each ++section must have a name (@var{secname1} and @var{secname2} above). The ++section definitions within the @code{OVERLAY} construct are identical to ++those within the general @code{SECTIONS} construct (@pxref{SECTIONS}), ++except that no addresses and no memory regions may be defined for ++sections within an @code{OVERLAY}. ++ ++The comma at the end may be required if a @var{fill} is used and ++the next @var{sections-command} looks like a continuation of the expression. ++ ++The sections are all defined with the same starting address. The load ++addresses of the sections are arranged such that they are consecutive in ++memory starting at the load address used for the @code{OVERLAY} as a ++whole (as with normal section definitions, the load address is optional, ++and defaults to the start address; the start address is also optional, ++and defaults to the current value of the location counter). ++ ++If the @code{NOCROSSREFS} keyword is used, and there are any ++references among the sections, the linker will report an error. Since ++the sections all run at the same address, it normally does not make ++sense for one section to refer directly to another. ++@xref{Miscellaneous Commands, NOCROSSREFS}. ++ ++For each section within the @code{OVERLAY}, the linker automatically ++provides two symbols. The symbol @code{__load_start_@var{secname}} is ++defined as the starting load address of the section. The symbol ++@code{__load_stop_@var{secname}} is defined as the final load address of ++the section. Any characters within @var{secname} which are not legal ++within C identifiers are removed. C (or assembler) code may use these ++symbols to move the overlaid sections around as necessary. ++ ++At the end of the overlay, the value of the location counter is set to ++the start address of the overlay plus the size of the largest section. ++ ++Here is an example. Remember that this would appear inside a ++@code{SECTIONS} construct. ++@smallexample ++@group ++ OVERLAY 0x1000 : AT (0x4000) ++ @{ ++ .text0 @{ o1/*.o(.text) @} ++ .text1 @{ o2/*.o(.text) @} ++ @} ++@end group ++@end smallexample ++@noindent ++This will define both @samp{.text0} and @samp{.text1} to start at ++address 0x1000. @samp{.text0} will be loaded at address 0x4000, and ++@samp{.text1} will be loaded immediately after @samp{.text0}. The ++following symbols will be defined if referenced: @code{__load_start_text0}, ++@code{__load_stop_text0}, @code{__load_start_text1}, ++@code{__load_stop_text1}. ++ ++C code to copy overlay @code{.text1} into the overlay area might look ++like the following. ++ ++@smallexample ++@group ++ extern char __load_start_text1, __load_stop_text1; ++ memcpy ((char *) 0x1000, &__load_start_text1, ++ &__load_stop_text1 - &__load_start_text1); ++@end group ++@end smallexample ++ ++Note that the @code{OVERLAY} command is just syntactic sugar, since ++everything it does can be done using the more basic commands. The above ++example could have been written identically as follows. ++ ++@smallexample ++@group ++ .text0 0x1000 : AT (0x4000) @{ o1/*.o(.text) @} ++ PROVIDE (__load_start_text0 = LOADADDR (.text0)); ++ PROVIDE (__load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0)); ++ .text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) @{ o2/*.o(.text) @} ++ PROVIDE (__load_start_text1 = LOADADDR (.text1)); ++ PROVIDE (__load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1)); ++ . = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1)); ++@end group ++@end smallexample ++ ++@node MEMORY ++@section MEMORY Command ++@kindex MEMORY ++@cindex memory regions ++@cindex regions of memory ++@cindex allocating memory ++@cindex discontinuous memory ++The linker's default configuration permits allocation of all available ++memory. You can override this by using the @code{MEMORY} command. ++ ++The @code{MEMORY} command describes the location and size of blocks of ++memory in the target. You can use it to describe which memory regions ++may be used by the linker, and which memory regions it must avoid. You ++can then assign sections to particular memory regions. The linker will ++set section addresses based on the memory regions, and will warn about ++regions that become too full. The linker will not shuffle sections ++around to fit into the available regions. ++ ++A linker script may contain many uses of the @code{MEMORY} command, ++however, all memory blocks defined are treated as if they were ++specified inside a single @code{MEMORY} command. The syntax for ++@code{MEMORY} is: ++@smallexample ++@group ++MEMORY ++ @{ ++ @var{name} [(@var{attr})] : ORIGIN = @var{origin}, LENGTH = @var{len} ++ @dots{} ++ @} ++@end group ++@end smallexample ++ ++The @var{name} is a name used in the linker script to refer to the ++region. The region name has no meaning outside of the linker script. ++Region names are stored in a separate name space, and will not conflict ++with symbol names, file names, or section names. Each memory region ++must have a distinct name within the @code{MEMORY} command. However you can ++add later alias names to existing memory regions with the @ref{REGION_ALIAS} ++command. ++ ++@cindex memory region attributes ++The @var{attr} string is an optional list of attributes that specify ++whether to use a particular memory region for an input section which is ++not explicitly mapped in the linker script. As described in ++@ref{SECTIONS}, if you do not specify an output section for some input ++section, the linker will create an output section with the same name as ++the input section. If you define region attributes, the linker will use ++them to select the memory region for the output section that it creates. ++ ++The @var{attr} string must consist only of the following characters: ++@table @samp ++@item R ++Read-only section ++@item W ++Read/write section ++@item X ++Executable section ++@item A ++Allocatable section ++@item I ++Initialized section ++@item L ++Same as @samp{I} ++@item ! ++Invert the sense of any of the attributes that follow ++@end table ++ ++If an unmapped section matches any of the listed attributes other than ++@samp{!}, it will be placed in the memory region. The @samp{!} ++attribute reverses the test for the characters that follow, so that an ++unmapped section will be placed in the memory region only if it does ++not match any of the attributes listed afterwards. Thus an attribute ++string of @samp{RW!X} will match any unmapped section that has either ++or both of the @samp{R} and @samp{W} attributes, but only as long as ++the section does not also have the @samp{X} attribute. ++ ++@kindex ORIGIN = ++@kindex o = ++@kindex org = ++The @var{origin} is an numerical expression for the start address of ++the memory region. The expression must evaluate to a constant and it ++cannot involve any symbols. The keyword @code{ORIGIN} may be ++abbreviated to @code{org} or @code{o} (but not, for example, ++@code{ORG}). ++ ++@kindex LENGTH = ++@kindex len = ++@kindex l = ++The @var{len} is an expression for the size in bytes of the memory ++region. As with the @var{origin} expression, the expression must ++be numerical only and must evaluate to a constant. The keyword ++@code{LENGTH} may be abbreviated to @code{len} or @code{l}. ++ ++In the following example, we specify that there are two memory regions ++available for allocation: one starting at @samp{0} for 256 kilobytes, ++and the other starting at @samp{0x40000000} for four megabytes. The ++linker will place into the @samp{rom} memory region every section which ++is not explicitly mapped into a memory region, and is either read-only ++or executable. The linker will place other sections which are not ++explicitly mapped into a memory region into the @samp{ram} memory ++region. ++ ++@smallexample ++@group ++MEMORY ++ @{ ++ rom (rx) : ORIGIN = 0, LENGTH = 256K ++ ram (!rx) : org = 0x40000000, l = 4M ++ @} ++@end group ++@end smallexample ++ ++Once you define a memory region, you can direct the linker to place ++specific output sections into that memory region by using the ++@samp{>@var{region}} output section attribute. For example, if you have ++a memory region named @samp{mem}, you would use @samp{>mem} in the ++output section definition. @xref{Output Section Region}. If no address ++was specified for the output section, the linker will set the address to ++the next available address within the memory region. If the combined ++output sections directed to a memory region are too large for the ++region, the linker will issue an error message. ++ ++It is possible to access the origin and length of a memory in an ++expression via the @code{ORIGIN(@var{memory})} and ++@code{LENGTH(@var{memory})} functions: ++ ++@smallexample ++@group ++ _fstack = ORIGIN(ram) + LENGTH(ram) - 4; ++@end group ++@end smallexample ++ ++@node PHDRS ++@section PHDRS Command ++@kindex PHDRS ++@cindex program headers ++@cindex ELF program headers ++@cindex program segments ++@cindex segments, ELF ++The ELF object file format uses @dfn{program headers}, also knows as ++@dfn{segments}. The program headers describe how the program should be ++loaded into memory. You can print them out by using the @code{objdump} ++program with the @samp{-p} option. ++ ++When you run an ELF program on a native ELF system, the system loader ++reads the program headers in order to figure out how to load the ++program. This will only work if the program headers are set correctly. ++This manual does not describe the details of how the system loader ++interprets program headers; for more information, see the ELF ABI. ++ ++The linker will create reasonable program headers by default. However, ++in some cases, you may need to specify the program headers more ++precisely. You may use the @code{PHDRS} command for this purpose. When ++the linker sees the @code{PHDRS} command in the linker script, it will ++not create any program headers other than the ones specified. ++ ++The linker only pays attention to the @code{PHDRS} command when ++generating an ELF output file. In other cases, the linker will simply ++ignore @code{PHDRS}. ++ ++This is the syntax of the @code{PHDRS} command. The words @code{PHDRS}, ++@code{FILEHDR}, @code{AT}, and @code{FLAGS} are keywords. ++ ++@smallexample ++@group ++PHDRS ++@{ ++ @var{name} @var{type} [ FILEHDR ] [ PHDRS ] [ AT ( @var{address} ) ] ++ [ FLAGS ( @var{flags} ) ] ; ++@} ++@end group ++@end smallexample ++ ++The @var{name} is used only for reference in the @code{SECTIONS} command ++of the linker script. It is not put into the output file. Program ++header names are stored in a separate name space, and will not conflict ++with symbol names, file names, or section names. Each program header ++must have a distinct name. The headers are processed in order and it ++is usual for them to map to sections in ascending load address order. ++ ++Certain program header types describe segments of memory which the ++system loader will load from the file. In the linker script, you ++specify the contents of these segments by placing allocatable output ++sections in the segments. You use the @samp{:@var{phdr}} output section ++attribute to place a section in a particular segment. @xref{Output ++Section Phdr}. ++ ++It is normal to put certain sections in more than one segment. This ++merely implies that one segment of memory contains another. You may ++repeat @samp{:@var{phdr}}, using it once for each segment which should ++contain the section. ++ ++If you place a section in one or more segments using @samp{:@var{phdr}}, ++then the linker will place all subsequent allocatable sections which do ++not specify @samp{:@var{phdr}} in the same segments. This is for ++convenience, since generally a whole set of contiguous sections will be ++placed in a single segment. You can use @code{:NONE} to override the ++default segment and tell the linker to not put the section in any ++segment at all. ++ ++@kindex FILEHDR ++@kindex PHDRS ++You may use the @code{FILEHDR} and @code{PHDRS} keywords after ++the program header type to further describe the contents of the segment. ++The @code{FILEHDR} keyword means that the segment should include the ELF ++file header. The @code{PHDRS} keyword means that the segment should ++include the ELF program headers themselves. If applied to a loadable ++segment (@code{PT_LOAD}), all prior loadable segments must have one of ++these keywords. ++ ++The @var{type} may be one of the following. The numbers indicate the ++value of the keyword. ++ ++@table @asis ++@item @code{PT_NULL} (0) ++Indicates an unused program header. ++ ++@item @code{PT_LOAD} (1) ++Indicates that this program header describes a segment to be loaded from ++the file. ++ ++@item @code{PT_DYNAMIC} (2) ++Indicates a segment where dynamic linking information can be found. ++ ++@item @code{PT_INTERP} (3) ++Indicates a segment where the name of the program interpreter may be ++found. ++ ++@item @code{PT_NOTE} (4) ++Indicates a segment holding note information. ++ ++@item @code{PT_SHLIB} (5) ++A reserved program header type, defined but not specified by the ELF ++ABI. ++ ++@item @code{PT_PHDR} (6) ++Indicates a segment where the program headers may be found. ++ ++@item @code{PT_TLS} (7) ++Indicates a segment containing thread local storage. ++ ++@item @var{expression} ++An expression giving the numeric type of the program header. This may ++be used for types not defined above. ++@end table ++ ++You can specify that a segment should be loaded at a particular address ++in memory by using an @code{AT} expression. This is identical to the ++@code{AT} command used as an output section attribute (@pxref{Output ++Section LMA}). The @code{AT} command for a program header overrides the ++output section attribute. ++ ++The linker will normally set the segment flags based on the sections ++which comprise the segment. You may use the @code{FLAGS} keyword to ++explicitly specify the segment flags. The value of @var{flags} must be ++an integer. It is used to set the @code{p_flags} field of the program ++header. ++ ++Here is an example of @code{PHDRS}. This shows a typical set of program ++headers used on a native ELF system. ++ ++@example ++@group ++PHDRS ++@{ ++ headers PT_PHDR PHDRS ; ++ interp PT_INTERP ; ++ text PT_LOAD FILEHDR PHDRS ; ++ data PT_LOAD ; ++ dynamic PT_DYNAMIC ; ++@} ++ ++SECTIONS ++@{ ++ . = SIZEOF_HEADERS; ++ .interp : @{ *(.interp) @} :text :interp ++ .text : @{ *(.text) @} :text ++ .rodata : @{ *(.rodata) @} /* defaults to :text */ ++ @dots{} ++ . = . + 0x1000; /* move to a new page in memory */ ++ .data : @{ *(.data) @} :data ++ .dynamic : @{ *(.dynamic) @} :data :dynamic ++ @dots{} ++@} ++@end group ++@end example ++ ++@node VERSION ++@section VERSION Command ++@kindex VERSION @{script text@} ++@cindex symbol versions ++@cindex version script ++@cindex versions of symbols ++The linker supports symbol versions when using ELF. Symbol versions are ++only useful when using shared libraries. The dynamic linker can use ++symbol versions to select a specific version of a function when it runs ++a program that may have been linked against an earlier version of the ++shared library. ++ ++You can include a version script directly in the main linker script, or ++you can supply the version script as an implicit linker script. You can ++also use the @samp{--version-script} linker option. ++ ++The syntax of the @code{VERSION} command is simply ++@smallexample ++VERSION @{ version-script-commands @} ++@end smallexample ++ ++The format of the version script commands is identical to that used by ++Sun's linker in Solaris 2.5. The version script defines a tree of ++version nodes. You specify the node names and interdependencies in the ++version script. You can specify which symbols are bound to which ++version nodes, and you can reduce a specified set of symbols to local ++scope so that they are not globally visible outside of the shared ++library. ++ ++The easiest way to demonstrate the version script language is with a few ++examples. ++ ++@smallexample ++VERS_1.1 @{ ++ global: ++ foo1; ++ local: ++ old*; ++ original*; ++ new*; ++@}; ++ ++VERS_1.2 @{ ++ foo2; ++@} VERS_1.1; ++ ++VERS_2.0 @{ ++ bar1; bar2; ++ extern "C++" @{ ++ ns::*; ++ "f(int, double)"; ++ @}; ++@} VERS_1.2; ++@end smallexample ++ ++This example version script defines three version nodes. The first ++version node defined is @samp{VERS_1.1}; it has no other dependencies. ++The script binds the symbol @samp{foo1} to @samp{VERS_1.1}. It reduces ++a number of symbols to local scope so that they are not visible outside ++of the shared library; this is done using wildcard patterns, so that any ++symbol whose name begins with @samp{old}, @samp{original}, or @samp{new} ++is matched. The wildcard patterns available are the same as those used ++in the shell when matching filenames (also known as ``globbing''). ++However, if you specify the symbol name inside double quotes, then the ++name is treated as literal, rather than as a glob pattern. ++ ++Next, the version script defines node @samp{VERS_1.2}. This node ++depends upon @samp{VERS_1.1}. The script binds the symbol @samp{foo2} ++to the version node @samp{VERS_1.2}. ++ ++Finally, the version script defines node @samp{VERS_2.0}. This node ++depends upon @samp{VERS_1.2}. The scripts binds the symbols @samp{bar1} ++and @samp{bar2} are bound to the version node @samp{VERS_2.0}. ++ ++When the linker finds a symbol defined in a library which is not ++specifically bound to a version node, it will effectively bind it to an ++unspecified base version of the library. You can bind all otherwise ++unspecified symbols to a given version node by using @samp{global: *;} ++somewhere in the version script. Note that it's slightly crazy to use ++wildcards in a global spec except on the last version node. Global ++wildcards elsewhere run the risk of accidentally adding symbols to the ++set exported for an old version. That's wrong since older versions ++ought to have a fixed set of symbols. ++ ++The names of the version nodes have no specific meaning other than what ++they might suggest to the person reading them. The @samp{2.0} version ++could just as well have appeared in between @samp{1.1} and @samp{1.2}. ++However, this would be a confusing way to write a version script. ++ ++Node name can be omitted, provided it is the only version node ++in the version script. Such version script doesn't assign any versions to ++symbols, only selects which symbols will be globally visible out and which ++won't. ++ ++@smallexample ++@{ global: foo; bar; local: *; @}; ++@end smallexample ++ ++When you link an application against a shared library that has versioned ++symbols, the application itself knows which version of each symbol it ++requires, and it also knows which version nodes it needs from each ++shared library it is linked against. Thus at runtime, the dynamic ++loader can make a quick check to make sure that the libraries you have ++linked against do in fact supply all of the version nodes that the ++application will need to resolve all of the dynamic symbols. In this ++way it is possible for the dynamic linker to know with certainty that ++all external symbols that it needs will be resolvable without having to ++search for each symbol reference. ++ ++The symbol versioning is in effect a much more sophisticated way of ++doing minor version checking that SunOS does. The fundamental problem ++that is being addressed here is that typically references to external ++functions are bound on an as-needed basis, and are not all bound when ++the application starts up. If a shared library is out of date, a ++required interface may be missing; when the application tries to use ++that interface, it may suddenly and unexpectedly fail. With symbol ++versioning, the user will get a warning when they start their program if ++the libraries being used with the application are too old. ++ ++There are several GNU extensions to Sun's versioning approach. The ++first of these is the ability to bind a symbol to a version node in the ++source file where the symbol is defined instead of in the versioning ++script. This was done mainly to reduce the burden on the library ++maintainer. You can do this by putting something like: ++@smallexample ++__asm__(".symver original_foo,foo@@VERS_1.1"); ++@end smallexample ++@noindent ++in the C source file. This renames the function @samp{original_foo} to ++be an alias for @samp{foo} bound to the version node @samp{VERS_1.1}. ++The @samp{local:} directive can be used to prevent the symbol ++@samp{original_foo} from being exported. A @samp{.symver} directive ++takes precedence over a version script. ++ ++The second GNU extension is to allow multiple versions of the same ++function to appear in a given shared library. In this way you can make ++an incompatible change to an interface without increasing the major ++version number of the shared library, while still allowing applications ++linked against the old interface to continue to function. ++ ++To do this, you must use multiple @samp{.symver} directives in the ++source file. Here is an example: ++ ++@smallexample ++__asm__(".symver original_foo,foo@@"); ++__asm__(".symver old_foo,foo@@VERS_1.1"); ++__asm__(".symver old_foo1,foo@@VERS_1.2"); ++__asm__(".symver new_foo,foo@@@@VERS_2.0"); ++@end smallexample ++ ++In this example, @samp{foo@@} represents the symbol @samp{foo} bound to the ++unspecified base version of the symbol. The source file that contains this ++example would define 4 C functions: @samp{original_foo}, @samp{old_foo}, ++@samp{old_foo1}, and @samp{new_foo}. ++ ++When you have multiple definitions of a given symbol, there needs to be ++some way to specify a default version to which external references to ++this symbol will be bound. You can do this with the ++@samp{foo@@@@VERS_2.0} type of @samp{.symver} directive. You can only ++declare one version of a symbol as the default in this manner; otherwise ++you would effectively have multiple definitions of the same symbol. ++ ++If you wish to bind a reference to a specific version of the symbol ++within the shared library, you can use the aliases of convenience ++(i.e., @samp{old_foo}), or you can use the @samp{.symver} directive to ++specifically bind to an external version of the function in question. ++ ++You can also specify the language in the version script: ++ ++@smallexample ++VERSION extern "lang" @{ version-script-commands @} ++@end smallexample ++ ++The supported @samp{lang}s are @samp{C}, @samp{C++}, and @samp{Java}. ++The linker will iterate over the list of symbols at the link time and ++demangle them according to @samp{lang} before matching them to the ++patterns specified in @samp{version-script-commands}. The default ++@samp{lang} is @samp{C}. ++ ++Demangled names may contains spaces and other special characters. As ++described above, you can use a glob pattern to match demangled names, ++or you can use a double-quoted string to match the string exactly. In ++the latter case, be aware that minor differences (such as differing ++whitespace) between the version script and the demangler output will ++cause a mismatch. As the exact string generated by the demangler ++might change in the future, even if the mangled name does not, you ++should check that all of your version directives are behaving as you ++expect when you upgrade. ++ ++@node Expressions ++@section Expressions in Linker Scripts ++@cindex expressions ++@cindex arithmetic ++The syntax for expressions in the linker script language is identical to ++that of C expressions, except that whitespace is required in some ++places to resolve syntactic ambiguities. All expressions are ++evaluated as integers. All expressions are evaluated in the same ++size, which is 32 bits if both the host and target are 32 bits, and is ++otherwise 64 bits. ++ ++You can use and set symbol values in expressions. ++ ++The linker defines several special purpose builtin functions for use in ++expressions. ++ ++@menu ++* Constants:: Constants ++* Symbolic Constants:: Symbolic constants ++* Symbols:: Symbol Names ++* Orphan Sections:: Orphan Sections ++* Location Counter:: The Location Counter ++* Operators:: Operators ++* Evaluation:: Evaluation ++* Expression Section:: The Section of an Expression ++* Builtin Functions:: Builtin Functions ++@end menu ++ ++@node Constants ++@subsection Constants ++@cindex integer notation ++@cindex constants in linker scripts ++All constants are integers. ++ ++As in C, the linker considers an integer beginning with @samp{0} to be ++octal, and an integer beginning with @samp{0x} or @samp{0X} to be ++hexadecimal. Alternatively the linker accepts suffixes of @samp{h} or ++@samp{H} for hexadecimal, @samp{o} or @samp{O} for octal, @samp{b} or ++@samp{B} for binary and @samp{d} or @samp{D} for decimal. Any integer ++value without a prefix or a suffix is considered to be decimal. ++ ++@cindex scaled integers ++@cindex K and M integer suffixes ++@cindex M and K integer suffixes ++@cindex suffixes for integers ++@cindex integer suffixes ++In addition, you can use the suffixes @code{K} and @code{M} to scale a ++constant by ++@c TEXI2ROFF-KILL ++@ifnottex ++@c END TEXI2ROFF-KILL ++@code{1024} or @code{1024*1024} ++@c TEXI2ROFF-KILL ++@end ifnottex ++@tex ++${\rm 1024}$ or ${\rm 1024}^2$ ++@end tex ++@c END TEXI2ROFF-KILL ++respectively. For example, the following ++all refer to the same quantity: ++ ++@smallexample ++_fourk_1 = 4K; ++_fourk_2 = 4096; ++_fourk_3 = 0x1000; ++_fourk_4 = 10000o; ++@end smallexample ++ ++Note - the @code{K} and @code{M} suffixes cannot be used in ++conjunction with the base suffixes mentioned above. ++ ++@node Symbolic Constants ++@subsection Symbolic Constants ++@cindex symbolic constants ++@kindex CONSTANT ++It is possible to refer to target-specific constants via the use of ++the @code{CONSTANT(@var{name})} operator, where @var{name} is one of: ++ ++@table @code ++@item MAXPAGESIZE ++@kindex MAXPAGESIZE ++The target's maximum page size. ++ ++@item COMMONPAGESIZE ++@kindex COMMONPAGESIZE ++The target's default page size. ++@end table ++ ++So for example: ++ ++@smallexample ++ .text ALIGN (CONSTANT (MAXPAGESIZE)) : @{ *(.text) @} ++@end smallexample ++ ++will create a text section aligned to the largest page boundary ++supported by the target. ++ ++@node Symbols ++@subsection Symbol Names ++@cindex symbol names ++@cindex names ++@cindex quoted symbol names ++@kindex " ++Unless quoted, symbol names start with a letter, underscore, or period ++and may include letters, digits, underscores, periods, and hyphens. ++Unquoted symbol names must not conflict with any keywords. You can ++specify a symbol which contains odd characters or has the same name as a ++keyword by surrounding the symbol name in double quotes: ++@smallexample ++"SECTION" = 9; ++"with a space" = "also with a space" + 10; ++@end smallexample ++ ++Since symbols can contain many non-alphabetic characters, it is safest ++to delimit symbols with spaces. For example, @samp{A-B} is one symbol, ++whereas @samp{A - B} is an expression involving subtraction. ++ ++@node Orphan Sections ++@subsection Orphan Sections ++@cindex orphan ++Orphan sections are sections present in the input files which ++are not explicitly placed into the output file by the linker ++script. The linker will still copy these sections into the ++output file by either finding, or creating a suitable output section ++in which to place the orphaned input section. ++ ++If the name of an orphaned input section exactly matches the name of ++an existing output section, then the orphaned input section will be ++placed at the end of that output section. ++ ++If there is no output section with a matching name then new output ++sections will be created. Each new output section will have the same ++name as the orphan section placed within it. If there are multiple ++orphan sections with the same name, these will all be combined into ++one new output section. ++ ++If new output sections are created to hold orphaned input sections, ++then the linker must decide where to place these new output sections ++in relation to existing output sections. On most modern targets, the ++linker attempts to place orphan sections after sections of the same ++attribute, such as code vs data, loadable vs non-loadable, etc. If no ++sections with matching attributes are found, or your target lacks this ++support, the orphan section is placed at the end of the file. ++ ++The command-line options @samp{--orphan-handling} and @samp{--unique} ++(@pxref{Options,,Command-line Options}) can be used to control which ++output sections an orphan is placed in. ++ ++@node Location Counter ++@subsection The Location Counter ++@kindex . ++@cindex dot ++@cindex location counter ++@cindex current output location ++The special linker variable @dfn{dot} @samp{.} always contains the ++current output location counter. Since the @code{.} always refers to a ++location in an output section, it may only appear in an expression ++within a @code{SECTIONS} command. The @code{.} symbol may appear ++anywhere that an ordinary symbol is allowed in an expression. ++ ++@cindex holes ++Assigning a value to @code{.} will cause the location counter to be ++moved. This may be used to create holes in the output section. The ++location counter may not be moved backwards inside an output section, ++and may not be moved backwards outside of an output section if so ++doing creates areas with overlapping LMAs. ++ ++@smallexample ++SECTIONS ++@{ ++ output : ++ @{ ++ file1(.text) ++ . = . + 1000; ++ file2(.text) ++ . += 1000; ++ file3(.text) ++ @} = 0x12345678; ++@} ++@end smallexample ++@noindent ++In the previous example, the @samp{.text} section from @file{file1} is ++located at the beginning of the output section @samp{output}. It is ++followed by a 1000 byte gap. Then the @samp{.text} section from ++@file{file2} appears, also with a 1000 byte gap following before the ++@samp{.text} section from @file{file3}. The notation @samp{= 0x12345678} ++specifies what data to write in the gaps (@pxref{Output Section Fill}). ++ ++@cindex dot inside sections ++Note: @code{.} actually refers to the byte offset from the start of the ++current containing object. Normally this is the @code{SECTIONS} ++statement, whose start address is 0, hence @code{.} can be used as an ++absolute address. If @code{.} is used inside a section description ++however, it refers to the byte offset from the start of that section, ++not an absolute address. Thus in a script like this: ++ ++@smallexample ++SECTIONS ++@{ ++ . = 0x100 ++ .text: @{ ++ *(.text) ++ . = 0x200 ++ @} ++ . = 0x500 ++ .data: @{ ++ *(.data) ++ . += 0x600 ++ @} ++@} ++@end smallexample ++ ++The @samp{.text} section will be assigned a starting address of 0x100 ++and a size of exactly 0x200 bytes, even if there is not enough data in ++the @samp{.text} input sections to fill this area. (If there is too ++much data, an error will be produced because this would be an attempt to ++move @code{.} backwards). The @samp{.data} section will start at 0x500 ++and it will have an extra 0x600 bytes worth of space after the end of ++the values from the @samp{.data} input sections and before the end of ++the @samp{.data} output section itself. ++ ++@cindex dot outside sections ++Setting symbols to the value of the location counter outside of an ++output section statement can result in unexpected values if the linker ++needs to place orphan sections. For example, given the following: ++ ++@smallexample ++SECTIONS ++@{ ++ start_of_text = . ; ++ .text: @{ *(.text) @} ++ end_of_text = . ; ++ ++ start_of_data = . ; ++ .data: @{ *(.data) @} ++ end_of_data = . ; ++@} ++@end smallexample ++ ++If the linker needs to place some input section, e.g. @code{.rodata}, ++not mentioned in the script, it might choose to place that section ++between @code{.text} and @code{.data}. You might think the linker ++should place @code{.rodata} on the blank line in the above script, but ++blank lines are of no particular significance to the linker. As well, ++the linker doesn't associate the above symbol names with their ++sections. Instead, it assumes that all assignments or other ++statements belong to the previous output section, except for the ++special case of an assignment to @code{.}. I.e., the linker will ++place the orphan @code{.rodata} section as if the script was written ++as follows: ++ ++@smallexample ++SECTIONS ++@{ ++ start_of_text = . ; ++ .text: @{ *(.text) @} ++ end_of_text = . ; ++ ++ start_of_data = . ; ++ .rodata: @{ *(.rodata) @} ++ .data: @{ *(.data) @} ++ end_of_data = . ; ++@} ++@end smallexample ++ ++This may or may not be the script author's intention for the value of ++@code{start_of_data}. One way to influence the orphan section ++placement is to assign the location counter to itself, as the linker ++assumes that an assignment to @code{.} is setting the start address of ++a following output section and thus should be grouped with that ++section. So you could write: ++ ++@smallexample ++SECTIONS ++@{ ++ start_of_text = . ; ++ .text: @{ *(.text) @} ++ end_of_text = . ; ++ ++ . = . ; ++ start_of_data = . ; ++ .data: @{ *(.data) @} ++ end_of_data = . ; ++@} ++@end smallexample ++ ++Now, the orphan @code{.rodata} section will be placed between ++@code{end_of_text} and @code{start_of_data}. ++ ++@need 2000 ++@node Operators ++@subsection Operators ++@cindex operators for arithmetic ++@cindex arithmetic operators ++@cindex precedence in expressions ++The linker recognizes the standard C set of arithmetic operators, with ++the standard bindings and precedence levels: ++@c TEXI2ROFF-KILL ++@ifnottex ++@c END TEXI2ROFF-KILL ++@smallexample ++precedence associativity Operators Notes ++(highest) ++1 left ! - ~ (1) ++2 left * / % ++3 left + - ++4 left >> << ++5 left == != > < <= >= ++6 left & ++7 left | ++8 left && ++9 left || ++10 right ? : ++11 right &= += -= *= /= (2) ++(lowest) ++@end smallexample ++Notes: ++(1) Prefix operators ++(2) @xref{Assignments}. ++@c TEXI2ROFF-KILL ++@end ifnottex ++@tex ++\vskip \baselineskip ++%"lispnarrowing" is the extra indent used generally for smallexample ++\hskip\lispnarrowing\vbox{\offinterlineskip ++\hrule ++\halign ++{\vrule#&\strut\hfil\ #\ \hfil&\vrule#&\strut\hfil\ #\ \hfil&\vrule#&\strut\hfil\ {\tt #}\ \hfil&\vrule#\cr ++height2pt&\omit&&\omit&&\omit&\cr ++&Precedence&& Associativity &&{\rm Operators}&\cr ++height2pt&\omit&&\omit&&\omit&\cr ++\noalign{\hrule} ++height2pt&\omit&&\omit&&\omit&\cr ++&highest&&&&&\cr ++% '176 is tilde, '~' in tt font ++&1&&left&&\qquad- \char'176\ !\qquad\dag&\cr ++&2&&left&&* / \%&\cr ++&3&&left&&+ -&\cr ++&4&&left&&>> <<&\cr ++&5&&left&&== != > < <= >=&\cr ++&6&&left&&\&&\cr ++&7&&left&&|&\cr ++&8&&left&&{\&\&}&\cr ++&9&&left&&||&\cr ++&10&&right&&? :&\cr ++&11&&right&&\qquad\&= += -= *= /=\qquad\ddag&\cr ++&lowest&&&&&\cr ++height2pt&\omit&&\omit&&\omit&\cr} ++\hrule} ++@end tex ++@iftex ++{ ++@obeylines@parskip=0pt@parindent=0pt ++@dag@quad Prefix operators. ++@ddag@quad @xref{Assignments}. ++} ++@end iftex ++@c END TEXI2ROFF-KILL ++ ++@node Evaluation ++@subsection Evaluation ++@cindex lazy evaluation ++@cindex expression evaluation order ++The linker evaluates expressions lazily. It only computes the value of ++an expression when absolutely necessary. ++ ++The linker needs some information, such as the value of the start ++address of the first section, and the origins and lengths of memory ++regions, in order to do any linking at all. These values are computed ++as soon as possible when the linker reads in the linker script. ++ ++However, other values (such as symbol values) are not known or needed ++until after storage allocation. Such values are evaluated later, when ++other information (such as the sizes of output sections) is available ++for use in the symbol assignment expression. ++ ++The sizes of sections cannot be known until after allocation, so ++assignments dependent upon these are not performed until after ++allocation. ++ ++Some expressions, such as those depending upon the location counter ++@samp{.}, must be evaluated during section allocation. ++ ++If the result of an expression is required, but the value is not ++available, then an error results. For example, a script like the ++following ++@smallexample ++@group ++SECTIONS ++ @{ ++ .text 9+this_isnt_constant : ++ @{ *(.text) @} ++ @} ++@end group ++@end smallexample ++@noindent ++will cause the error message @samp{non constant expression for initial ++address}. ++ ++@node Expression Section ++@subsection The Section of an Expression ++@cindex expression sections ++@cindex absolute expressions ++@cindex relative expressions ++@cindex absolute and relocatable symbols ++@cindex relocatable and absolute symbols ++@cindex symbols, relocatable and absolute ++Addresses and symbols may be section relative, or absolute. A section ++relative symbol is relocatable. If you request relocatable output ++using the @samp{-r} option, a further link operation may change the ++value of a section relative symbol. On the other hand, an absolute ++symbol will retain the same value throughout any further link ++operations. ++ ++Some terms in linker expressions are addresses. This is true of ++section relative symbols and for builtin functions that return an ++address, such as @code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and ++@code{SEGMENT_START}. Other terms are simply numbers, or are builtin ++functions that return a non-address value, such as @code{LENGTH}. ++One complication is that unless you set @code{LD_FEATURE ("SANE_EXPR")} ++(@pxref{Miscellaneous Commands}), numbers and absolute symbols are treated ++differently depending on their location, for compatibility with older ++versions of @code{ld}. Expressions appearing outside an output ++section definition treat all numbers as absolute addresses. ++Expressions appearing inside an output section definition treat ++absolute symbols as numbers. If @code{LD_FEATURE ("SANE_EXPR")} is ++given, then absolute symbols and numbers are simply treated as numbers ++everywhere. ++ ++In the following simple example, ++ ++@smallexample ++@group ++SECTIONS ++ @{ ++ . = 0x100; ++ __executable_start = 0x100; ++ .data : ++ @{ ++ . = 0x10; ++ __data_start = 0x10; ++ *(.data) ++ @} ++ @dots{} ++ @} ++@end group ++@end smallexample ++ ++both @code{.} and @code{__executable_start} are set to the absolute ++address 0x100 in the first two assignments, then both @code{.} and ++@code{__data_start} are set to 0x10 relative to the @code{.data} ++section in the second two assignments. ++ ++For expressions involving numbers, relative addresses and absolute ++addresses, ld follows these rules to evaluate terms: ++ ++@itemize @bullet ++@item ++Unary operations on an absolute address or number, and binary ++operations on two absolute addresses or two numbers, or between one ++absolute address and a number, apply the operator to the value(s). ++@item ++Unary operations on a relative address, and binary operations on two ++relative addresses in the same section or between one relative address ++and a number, apply the operator to the offset part of the address(es). ++@item ++Other binary operations, that is, between two relative addresses not ++in the same section, or between a relative address and an absolute ++address, first convert any non-absolute term to an absolute address ++before applying the operator. ++@end itemize ++ ++The result section of each sub-expression is as follows: ++ ++@itemize @bullet ++@item ++An operation involving only numbers results in a number. ++@item ++The result of comparisons, @samp{&&} and @samp{||} is also a number. ++@item ++The result of other binary arithmetic and logical operations on two ++relative addresses in the same section or two absolute addresses ++(after above conversions) is also a number when ++@code{LD_FEATURE ("SANE_EXPR")} or inside an output section definition ++but an absolute address otherwise. ++@item ++The result of other operations on relative addresses or one ++relative address and a number, is a relative address in the same ++section as the relative operand(s). ++@item ++The result of other operations on absolute addresses (after above ++conversions) is an absolute address. ++@end itemize ++ ++You can use the builtin function @code{ABSOLUTE} to force an expression ++to be absolute when it would otherwise be relative. For example, to ++create an absolute symbol set to the address of the end of the output ++section @samp{.data}: ++@smallexample ++SECTIONS ++ @{ ++ .data : @{ *(.data) _edata = ABSOLUTE(.); @} ++ @} ++@end smallexample ++@noindent ++If @samp{ABSOLUTE} were not used, @samp{_edata} would be relative to the ++@samp{.data} section. ++ ++Using @code{LOADADDR} also forces an expression absolute, since this ++particular builtin function returns an absolute address. ++ ++@node Builtin Functions ++@subsection Builtin Functions ++@cindex functions in expressions ++The linker script language includes a number of builtin functions for ++use in linker script expressions. ++ ++@table @code ++@item ABSOLUTE(@var{exp}) ++@kindex ABSOLUTE(@var{exp}) ++@cindex expression, absolute ++Return the absolute (non-relocatable, as opposed to non-negative) value ++of the expression @var{exp}. Primarily useful to assign an absolute ++value to a symbol within a section definition, where symbol values are ++normally section relative. @xref{Expression Section}. ++ ++@item ADDR(@var{section}) ++@kindex ADDR(@var{section}) ++@cindex section address in expression ++Return the address (VMA) of the named @var{section}. Your ++script must previously have defined the location of that section. In ++the following example, @code{start_of_output_1}, @code{symbol_1} and ++@code{symbol_2} are assigned equivalent values, except that ++@code{symbol_1} will be relative to the @code{.output1} section while ++the other two will be absolute: ++@smallexample ++@group ++SECTIONS @{ @dots{} ++ .output1 : ++ @{ ++ start_of_output_1 = ABSOLUTE(.); ++ @dots{} ++ @} ++ .output : ++ @{ ++ symbol_1 = ADDR(.output1); ++ symbol_2 = start_of_output_1; ++ @} ++@dots{} @} ++@end group ++@end smallexample ++ ++@item ALIGN(@var{align}) ++@itemx ALIGN(@var{exp},@var{align}) ++@kindex ALIGN(@var{align}) ++@kindex ALIGN(@var{exp},@var{align}) ++@cindex round up location counter ++@cindex align location counter ++@cindex round up expression ++@cindex align expression ++Return the location counter (@code{.}) or arbitrary expression aligned ++to the next @var{align} boundary. The single operand @code{ALIGN} ++doesn't change the value of the location counter---it just does ++arithmetic on it. The two operand @code{ALIGN} allows an arbitrary ++expression to be aligned upwards (@code{ALIGN(@var{align})} is ++equivalent to @code{ALIGN(ABSOLUTE(.), @var{align})}). ++ ++Here is an example which aligns the output @code{.data} section to the ++next @code{0x2000} byte boundary after the preceding section and sets a ++variable within the section to the next @code{0x8000} boundary after the ++input sections: ++@smallexample ++@group ++SECTIONS @{ @dots{} ++ .data ALIGN(0x2000): @{ ++ *(.data) ++ variable = ALIGN(0x8000); ++ @} ++@dots{} @} ++@end group ++@end smallexample ++@noindent ++The first use of @code{ALIGN} in this example specifies the location of ++a section because it is used as the optional @var{address} attribute of ++a section definition (@pxref{Output Section Address}). The second use ++of @code{ALIGN} is used to defines the value of a symbol. ++ ++The builtin function @code{NEXT} is closely related to @code{ALIGN}. ++ ++@item ALIGNOF(@var{section}) ++@kindex ALIGNOF(@var{section}) ++@cindex section alignment ++Return the alignment in bytes of the named @var{section}, if that section has ++been allocated. If the section has not been allocated when this is ++evaluated, the linker will report an error. In the following example, ++the alignment of the @code{.output} section is stored as the first ++value in that section. ++@smallexample ++@group ++SECTIONS@{ @dots{} ++ .output @{ ++ LONG (ALIGNOF (.output)) ++ @dots{} ++ @} ++@dots{} @} ++@end group ++@end smallexample ++ ++@item BLOCK(@var{exp}) ++@kindex BLOCK(@var{exp}) ++This is a synonym for @code{ALIGN}, for compatibility with older linker ++scripts. It is most often seen when setting the address of an output ++section. ++ ++@item DATA_SEGMENT_ALIGN(@var{maxpagesize}, @var{commonpagesize}) ++@kindex DATA_SEGMENT_ALIGN(@var{maxpagesize}, @var{commonpagesize}) ++This is equivalent to either ++@smallexample ++(ALIGN(@var{maxpagesize}) + (. & (@var{maxpagesize} - 1))) ++@end smallexample ++or ++@smallexample ++(ALIGN(@var{maxpagesize}) ++ + ((. + @var{commonpagesize} - 1) & (@var{maxpagesize} - @var{commonpagesize}))) ++@end smallexample ++@noindent ++depending on whether the latter uses fewer @var{commonpagesize} sized pages ++for the data segment (area between the result of this expression and ++@code{DATA_SEGMENT_END}) than the former or not. ++If the latter form is used, it means @var{commonpagesize} bytes of runtime ++memory will be saved at the expense of up to @var{commonpagesize} wasted ++bytes in the on-disk file. ++ ++This expression can only be used directly in @code{SECTIONS} commands, not in ++any output section descriptions and only once in the linker script. ++@var{commonpagesize} should be less or equal to @var{maxpagesize} and should ++be the system page size the object wants to be optimized for while still ++running on system page sizes up to @var{maxpagesize}. Note however ++that @samp{-z relro} protection will not be effective if the system ++page size is larger than @var{commonpagesize}. ++ ++@noindent ++Example: ++@smallexample ++ . = DATA_SEGMENT_ALIGN(0x10000, 0x2000); ++@end smallexample ++ ++@item DATA_SEGMENT_END(@var{exp}) ++@kindex DATA_SEGMENT_END(@var{exp}) ++This defines the end of data segment for @code{DATA_SEGMENT_ALIGN} ++evaluation purposes. ++ ++@smallexample ++ . = DATA_SEGMENT_END(.); ++@end smallexample ++ ++@item DATA_SEGMENT_RELRO_END(@var{offset}, @var{exp}) ++@kindex DATA_SEGMENT_RELRO_END(@var{offset}, @var{exp}) ++This defines the end of the @code{PT_GNU_RELRO} segment when ++@samp{-z relro} option is used. ++When @samp{-z relro} option is not present, @code{DATA_SEGMENT_RELRO_END} ++does nothing, otherwise @code{DATA_SEGMENT_ALIGN} is padded so that ++@var{exp} + @var{offset} is aligned to the @var{commonpagesize} ++argument given to @code{DATA_SEGMENT_ALIGN}. If present in the linker ++script, it must be placed between @code{DATA_SEGMENT_ALIGN} and ++@code{DATA_SEGMENT_END}. Evaluates to the second argument plus any ++padding needed at the end of the @code{PT_GNU_RELRO} segment due to ++section alignment. ++ ++@smallexample ++ . = DATA_SEGMENT_RELRO_END(24, .); ++@end smallexample ++ ++@item DEFINED(@var{symbol}) ++@kindex DEFINED(@var{symbol}) ++@cindex symbol defaults ++Return 1 if @var{symbol} is in the linker global symbol table and is ++defined before the statement using DEFINED in the script, otherwise ++return 0. You can use this function to provide ++default values for symbols. For example, the following script fragment ++shows how to set a global symbol @samp{begin} to the first location in ++the @samp{.text} section---but if a symbol called @samp{begin} already ++existed, its value is preserved: ++ ++@smallexample ++@group ++SECTIONS @{ @dots{} ++ .text : @{ ++ begin = DEFINED(begin) ? begin : . ; ++ @dots{} ++ @} ++ @dots{} ++@} ++@end group ++@end smallexample ++ ++@item LENGTH(@var{memory}) ++@kindex LENGTH(@var{memory}) ++Return the length of the memory region named @var{memory}. ++ ++@item LOADADDR(@var{section}) ++@kindex LOADADDR(@var{section}) ++@cindex section load address in expression ++Return the absolute LMA of the named @var{section}. (@pxref{Output ++Section LMA}). ++ ++@item LOG2CEIL(@var{exp}) ++@kindex LOG2CEIL(@var{exp}) ++Return the binary logarithm of @var{exp} rounded towards infinity. ++@code{LOG2CEIL(0)} returns 0. ++ ++@kindex MAX ++@item MAX(@var{exp1}, @var{exp2}) ++Returns the maximum of @var{exp1} and @var{exp2}. ++ ++@kindex MIN ++@item MIN(@var{exp1}, @var{exp2}) ++Returns the minimum of @var{exp1} and @var{exp2}. ++ ++@item NEXT(@var{exp}) ++@kindex NEXT(@var{exp}) ++@cindex unallocated address, next ++Return the next unallocated address that is a multiple of @var{exp}. ++This function is closely related to @code{ALIGN(@var{exp})}; unless you ++use the @code{MEMORY} command to define discontinuous memory for the ++output file, the two functions are equivalent. ++ ++@item ORIGIN(@var{memory}) ++@kindex ORIGIN(@var{memory}) ++Return the origin of the memory region named @var{memory}. ++ ++@item SEGMENT_START(@var{segment}, @var{default}) ++@kindex SEGMENT_START(@var{segment}, @var{default}) ++Return the base address of the named @var{segment}. If an explicit ++value has already been given for this segment (with a command-line ++@samp{-T} option) then that value will be returned otherwise the value ++will be @var{default}. At present, the @samp{-T} command-line option ++can only be used to set the base address for the ``text'', ``data'', and ++``bss'' sections, but you can use @code{SEGMENT_START} with any segment ++name. ++ ++@item SIZEOF(@var{section}) ++@kindex SIZEOF(@var{section}) ++@cindex section size ++Return the size in bytes of the named @var{section}, if that section has ++been allocated. If the section has not been allocated when this is ++evaluated, the linker will report an error. In the following example, ++@code{symbol_1} and @code{symbol_2} are assigned identical values: ++@smallexample ++@group ++SECTIONS@{ @dots{} ++ .output @{ ++ .start = . ; ++ @dots{} ++ .end = . ; ++ @} ++ symbol_1 = .end - .start ; ++ symbol_2 = SIZEOF(.output); ++@dots{} @} ++@end group ++@end smallexample ++ ++@item SIZEOF_HEADERS ++@kindex SIZEOF_HEADERS ++@cindex header size ++Return the size in bytes of the output file's headers. This is ++information which appears at the start of the output file. You can use ++this number when setting the start address of the first section, if you ++choose, to facilitate paging. ++ ++@cindex not enough room for program headers ++@cindex program headers, not enough room ++When producing an ELF output file, if the linker script uses the ++@code{SIZEOF_HEADERS} builtin function, the linker must compute the ++number of program headers before it has determined all the section ++addresses and sizes. If the linker later discovers that it needs ++additional program headers, it will report an error @samp{not enough ++room for program headers}. To avoid this error, you must avoid using ++the @code{SIZEOF_HEADERS} function, or you must rework your linker ++script to avoid forcing the linker to use additional program headers, or ++you must define the program headers yourself using the @code{PHDRS} ++command (@pxref{PHDRS}). ++@end table ++ ++@node Implicit Linker Scripts ++@section Implicit Linker Scripts ++@cindex implicit linker scripts ++If you specify a linker input file which the linker can not recognize as ++an object file or an archive file, it will try to read the file as a ++linker script. If the file can not be parsed as a linker script, the ++linker will report an error. ++ ++An implicit linker script will not replace the default linker script. ++ ++Typically an implicit linker script would contain only symbol ++assignments, or the @code{INPUT}, @code{GROUP}, or @code{VERSION} ++commands. ++ ++Any input files read because of an implicit linker script will be read ++at the position in the command line where the implicit linker script was ++read. This can affect archive searching. ++ ++@node Plugins ++@chapter Linker Plugins ++ ++@cindex plugins ++@cindex linker plugins ++The linker can use dynamically loaded plugins to modify its behavior. ++For example, the link-time optimization feature that some compilers ++support is implemented with a linker plugin. ++ ++Currently there is only one plugin shipped by default, but more may ++be added here later. ++ ++Plugins are enabled via the use of the @option{-plugin @var{name}} ++command line option. @xref{Options}. ++ ++@menu ++* libdep Plugin:: Static Library Dependencies Plugin ++@end menu ++ ++@node libdep Plugin ++@section Static Library Dependencies Plugin ++@cindex static library dependencies ++Originally, static libraries were contained in an archive file consisting ++just of a collection of relocatable object files. Later they evolved to ++optionally include a symbol table, to assist in finding the needed objects ++within a library. There their evolution ended, and dynamic libraries ++rose to ascendance. ++ ++One useful feature of dynamic libraries was that, more than just collecting ++multiple objects into a single file, they also included a list of their ++dependencies, such that one could specify just the name of a single dynamic ++library at link time, and all of its dependencies would be implicitly ++referenced as well. But static libraries lacked this feature, so if a ++link invocation was switched from using dynamic libraries to static ++libraries, the link command would usually fail unless it was rewritten to ++explicitly list the dependencies of the static library. ++ ++The GNU @command{ar} utility now supports a @option{--record-libdeps} option ++to embed dependency lists into static libraries as well, and the @file{libdep} ++plugin may be used to read this dependency information at link time. The ++dependency information is stored as a single string, carrying @option{-l} ++and @option{-L} arguments as they would normally appear in a linker ++command line. As such, the information can be written with any text ++utility and stored into any archive, even if GNU @command{ar} is not ++being used to create the archive. The information is stored in an ++archive member named @samp{__.LIBDEP}. ++ ++For example, given a library @file{libssl.a} that depends on another ++library @file{libcrypto.a} which may be found in @file{/usr/local/lib}, ++the @samp{__.LIBDEP} member of @file{libssl.a} would contain ++ ++@smallexample ++-L/usr/local/lib -lcrypto ++@end smallexample ++ ++@ifset GENERIC ++@node Machine Dependent ++@chapter Machine Dependent Features ++ ++@cindex machine dependencies ++@command{ld} has additional features on some platforms; the following ++sections describe them. Machines where @command{ld} has no additional ++functionality are not listed. ++ ++@menu ++@ifset H8300 ++* H8/300:: @command{ld} and the H8/300 ++@end ifset ++@ifset M68HC11 ++* M68HC11/68HC12:: @code{ld} and the Motorola 68HC11 and 68HC12 families ++@end ifset ++@ifset ARM ++* ARM:: @command{ld} and the ARM family ++@end ifset ++@ifset HPPA ++* HPPA ELF32:: @command{ld} and HPPA 32-bit ELF ++@end ifset ++@ifset M68K ++* M68K:: @command{ld} and the Motorola 68K family ++@end ifset ++@ifset MIPS ++* MIPS:: @command{ld} and the MIPS family ++@end ifset ++@ifset MMIX ++* MMIX:: @command{ld} and MMIX ++@end ifset ++@ifset MSP430 ++* MSP430:: @command{ld} and MSP430 ++@end ifset ++@ifset NDS32 ++* NDS32:: @command{ld} and NDS32 ++@end ifset ++@ifset NIOSII ++* Nios II:: @command{ld} and the Altera Nios II ++@end ifset ++@ifset POWERPC ++* PowerPC ELF32:: @command{ld} and PowerPC 32-bit ELF Support ++@end ifset ++@ifset POWERPC64 ++* PowerPC64 ELF64:: @command{ld} and PowerPC64 64-bit ELF Support ++@end ifset ++@ifset S/390 ++* S/390 ELF:: @command{ld} and S/390 ELF Support ++@end ifset ++@ifset SPU ++* SPU ELF:: @command{ld} and SPU ELF Support ++@end ifset ++@ifset TICOFF ++* TI COFF:: @command{ld} and TI COFF ++@end ifset ++@ifset WIN32 ++* WIN32:: @command{ld} and WIN32 (cygwin/mingw) ++@end ifset ++@ifset XTENSA ++* Xtensa:: @command{ld} and Xtensa Processors ++@end ifset ++@end menu ++@end ifset ++ ++@ifset H8300 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node H8/300 ++@section @command{ld} and the H8/300 ++ ++@cindex H8/300 support ++For the H8/300, @command{ld} can perform these global optimizations when ++you specify the @samp{--relax} command-line option. ++ ++@table @emph ++@cindex relaxing on H8/300 ++@item relaxing address modes ++@command{ld} finds all @code{jsr} and @code{jmp} instructions whose ++targets are within eight bits, and turns them into eight-bit ++program-counter relative @code{bsr} and @code{bra} instructions, ++respectively. ++ ++@cindex synthesizing on H8/300 ++@item synthesizing instructions ++@c FIXME: specifically mov.b, or any mov instructions really? -> mov.b only, at least on H8, H8H, H8S ++@command{ld} finds all @code{mov.b} instructions which use the ++sixteen-bit absolute address form, but refer to the top ++page of memory, and changes them to use the eight-bit address form. ++(That is: the linker turns @samp{mov.b @code{@@}@var{aa}:16} into ++@samp{mov.b @code{@@}@var{aa}:8} whenever the address @var{aa} is in the ++top page of memory). ++ ++@command{ld} finds all @code{mov} instructions which use the register ++indirect with 32-bit displacement addressing mode, but use a small ++displacement inside 16-bit displacement range, and changes them to use ++the 16-bit displacement form. (That is: the linker turns @samp{mov.b ++@code{@@}@var{d}:32,ERx} into @samp{mov.b @code{@@}@var{d}:16,ERx} ++whenever the displacement @var{d} is in the 16 bit signed integer ++range. Only implemented in ELF-format ld). ++ ++@item bit manipulation instructions ++@command{ld} finds all bit manipulation instructions like @code{band, bclr, ++biand, bild, bior, bist, bixor, bld, bnot, bor, bset, bst, btst, bxor} ++which use 32 bit and 16 bit absolute address form, but refer to the top ++page of memory, and changes them to use the 8 bit address form. ++(That is: the linker turns @samp{bset #xx:3,@code{@@}@var{aa}:32} into ++@samp{bset #xx:3,@code{@@}@var{aa}:8} whenever the address @var{aa} is in ++the top page of memory). ++ ++@item system control instructions ++@command{ld} finds all @code{ldc.w, stc.w} instructions which use the ++32 bit absolute address form, but refer to the top page of memory, and ++changes them to use 16 bit address form. ++(That is: the linker turns @samp{ldc.w @code{@@}@var{aa}:32,ccr} into ++@samp{ldc.w @code{@@}@var{aa}:16,ccr} whenever the address @var{aa} is in ++the top page of memory). ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifclear GENERIC ++@ifset Renesas ++@c This stuff is pointless to say unless you're especially concerned ++@c with Renesas chips; don't enable it for generic case, please. ++@node Renesas ++@chapter @command{ld} and Other Renesas Chips ++ ++@command{ld} also supports the Renesas (formerly Hitachi) H8/300H, ++H8/500, and SH chips. No special features, commands, or command-line ++options are required for these chips. ++@end ifset ++@end ifclear ++ ++@ifset ARM ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@ifset M68HC11 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node M68HC11/68HC12 ++@section @command{ld} and the Motorola 68HC11 and 68HC12 families ++ ++@cindex M68HC11 and 68HC12 support ++ ++@subsection Linker Relaxation ++ ++For the Motorola 68HC11, @command{ld} can perform these global ++optimizations when you specify the @samp{--relax} command-line option. ++ ++@table @emph ++@cindex relaxing on M68HC11 ++@item relaxing address modes ++@command{ld} finds all @code{jsr} and @code{jmp} instructions whose ++targets are within eight bits, and turns them into eight-bit ++program-counter relative @code{bsr} and @code{bra} instructions, ++respectively. ++ ++@command{ld} also looks at all 16-bit extended addressing modes and ++transforms them in a direct addressing mode when the address is in ++page 0 (between 0 and 0x0ff). ++ ++@item relaxing gcc instruction group ++When @command{gcc} is called with @option{-mrelax}, it can emit group ++of instructions that the linker can optimize to use a 68HC11 direct ++addressing mode. These instructions consists of @code{bclr} or ++@code{bset} instructions. ++ ++@end table ++ ++@subsection Trampoline Generation ++ ++@cindex trampoline generation on M68HC11 ++@cindex trampoline generation on M68HC12 ++For 68HC11 and 68HC12, @command{ld} can generate trampoline code to ++call a far function using a normal @code{jsr} instruction. The linker ++will also change the relocation to some far function to use the ++trampoline address instead of the function address. This is typically the ++case when a pointer to a function is taken. The pointer will in fact ++point to the function trampoline. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@node ARM ++@section @command{ld} and the ARM family ++ ++@cindex ARM interworking support ++@kindex --support-old-code ++For the ARM, @command{ld} will generate code stubs to allow functions calls ++between ARM and Thumb code. These stubs only work with code that has ++been compiled and assembled with the @samp{-mthumb-interwork} command ++line option. If it is necessary to link with old ARM object files or ++libraries, which have not been compiled with the -mthumb-interwork ++option then the @samp{--support-old-code} command-line switch should be ++given to the linker. This will make it generate larger stub functions ++which will work with non-interworking aware ARM code. Note, however, ++the linker does not support generating stubs for function calls to ++non-interworking aware Thumb code. ++ ++@cindex thumb entry point ++@cindex entry point, thumb ++@kindex --thumb-entry=@var{entry} ++The @samp{--thumb-entry} switch is a duplicate of the generic ++@samp{--entry} switch, in that it sets the program's starting address. ++But it also sets the bottom bit of the address, so that it can be ++branched to using a BX instruction, and the program will start ++executing in Thumb mode straight away. ++ ++@cindex PE import table prefixing ++@kindex --use-nul-prefixed-import-tables ++The @samp{--use-nul-prefixed-import-tables} switch is specifying, that ++the import tables idata4 and idata5 have to be generated with a zero ++element prefix for import libraries. This is the old style to generate ++import tables. By default this option is turned off. ++ ++@cindex BE8 ++@kindex --be8 ++The @samp{--be8} switch instructs @command{ld} to generate BE8 format ++executables. This option is only valid when linking big-endian ++objects - ie ones which have been assembled with the @option{-EB} ++option. The resulting image will contain big-endian data and ++little-endian code. ++ ++@cindex TARGET1 ++@kindex --target1-rel ++@kindex --target1-abs ++The @samp{R_ARM_TARGET1} relocation is typically used for entries in the ++@samp{.init_array} section. It is interpreted as either @samp{R_ARM_REL32} ++or @samp{R_ARM_ABS32}, depending on the target. The @samp{--target1-rel} ++and @samp{--target1-abs} switches override the default. ++ ++@cindex TARGET2 ++@kindex --target2=@var{type} ++The @samp{--target2=type} switch overrides the default definition of the ++@samp{R_ARM_TARGET2} relocation. Valid values for @samp{type}, their ++meanings, and target defaults are as follows: ++@table @samp ++@item rel ++@samp{R_ARM_REL32} (arm*-*-elf, arm*-*-eabi) ++@item abs ++@samp{R_ARM_ABS32} ++@item got-rel ++@samp{R_ARM_GOT_PREL} (arm*-*-linux, arm*-*-*bsd) ++@end table ++ ++@cindex FIX_V4BX ++@kindex --fix-v4bx ++The @samp{R_ARM_V4BX} relocation (defined by the ARM AAELF ++specification) enables objects compiled for the ARMv4 architecture to be ++interworking-safe when linked with other objects compiled for ARMv4t, but ++also allows pure ARMv4 binaries to be built from the same ARMv4 objects. ++ ++In the latter case, the switch @option{--fix-v4bx} must be passed to the ++linker, which causes v4t @code{BX rM} instructions to be rewritten as ++@code{MOV PC,rM}, since v4 processors do not have a @code{BX} instruction. ++ ++In the former case, the switch should not be used, and @samp{R_ARM_V4BX} ++relocations are ignored. ++ ++@cindex FIX_V4BX_INTERWORKING ++@kindex --fix-v4bx-interworking ++Replace @code{BX rM} instructions identified by @samp{R_ARM_V4BX} ++relocations with a branch to the following veneer: ++ ++@smallexample ++TST rM, #1 ++MOVEQ PC, rM ++BX Rn ++@end smallexample ++ ++This allows generation of libraries/applications that work on ARMv4 cores ++and are still interworking safe. Note that the above veneer clobbers the ++condition flags, so may cause incorrect program behavior in rare cases. ++ ++@cindex USE_BLX ++@kindex --use-blx ++The @samp{--use-blx} switch enables the linker to use ARM/Thumb ++BLX instructions (available on ARMv5t and above) in various ++situations. Currently it is used to perform calls via the PLT from Thumb ++code using BLX rather than using BX and a mode-switching stub before ++each PLT entry. This should lead to such calls executing slightly faster. ++ ++@cindex VFP11_DENORM_FIX ++@kindex --vfp11-denorm-fix ++The @samp{--vfp11-denorm-fix} switch enables a link-time workaround for a ++bug in certain VFP11 coprocessor hardware, which sometimes allows ++instructions with denorm operands (which must be handled by support code) ++to have those operands overwritten by subsequent instructions before ++the support code can read the intended values. ++ ++The bug may be avoided in scalar mode if you allow at least one ++intervening instruction between a VFP11 instruction which uses a register ++and another instruction which writes to the same register, or at least two ++intervening instructions if vector mode is in use. The bug only affects ++full-compliance floating-point mode: you do not need this workaround if ++you are using "runfast" mode. Please contact ARM for further details. ++ ++If you know you are using buggy VFP11 hardware, you can ++enable this workaround by specifying the linker option ++@samp{--vfp-denorm-fix=scalar} if you are using the VFP11 scalar ++mode only, or @samp{--vfp-denorm-fix=vector} if you are using ++vector mode (the latter also works for scalar code). The default is ++@samp{--vfp-denorm-fix=none}. ++ ++If the workaround is enabled, instructions are scanned for ++potentially-troublesome sequences, and a veneer is created for each ++such sequence which may trigger the erratum. The veneer consists of the ++first instruction of the sequence and a branch back to the subsequent ++instruction. The original instruction is then replaced with a branch to ++the veneer. The extra cycles required to call and return from the veneer ++are sufficient to avoid the erratum in both the scalar and vector cases. ++ ++@cindex ARM1176 erratum workaround ++@kindex --fix-arm1176 ++@kindex --no-fix-arm1176 ++The @samp{--fix-arm1176} switch enables a link-time workaround for an erratum ++in certain ARM1176 processors. The workaround is enabled by default if you ++are targeting ARM v6 (excluding ARM v6T2) or earlier. It can be disabled ++unconditionally by specifying @samp{--no-fix-arm1176}. ++ ++Further information is available in the ``ARM1176JZ-S and ARM1176JZF-S ++Programmer Advice Notice'' available on the ARM documentation website at: ++http://infocenter.arm.com/. ++ ++@cindex STM32L4xx erratum workaround ++@kindex --fix-stm32l4xx-629360 ++ ++The @samp{--fix-stm32l4xx-629360} switch enables a link-time ++workaround for a bug in the bus matrix / memory controller for some of ++the STM32 Cortex-M4 based products (STM32L4xx). When accessing ++off-chip memory via the affected bus for bus reads of 9 words or more, ++the bus can generate corrupt data and/or abort. These are only ++core-initiated accesses (not DMA), and might affect any access: ++integer loads such as LDM, POP and floating-point loads such as VLDM, ++VPOP. Stores are not affected. ++ ++The bug can be avoided by splitting memory accesses into the ++necessary chunks to keep bus reads below 8 words. ++ ++The workaround is not enabled by default, this is equivalent to use ++@samp{--fix-stm32l4xx-629360=none}. If you know you are using buggy ++STM32L4xx hardware, you can enable the workaround by specifying the ++linker option @samp{--fix-stm32l4xx-629360}, or the equivalent ++@samp{--fix-stm32l4xx-629360=default}. ++ ++If the workaround is enabled, instructions are scanned for ++potentially-troublesome sequences, and a veneer is created for each ++such sequence which may trigger the erratum. The veneer consists in a ++replacement sequence emulating the behaviour of the original one and a ++branch back to the subsequent instruction. The original instruction is ++then replaced with a branch to the veneer. ++ ++The workaround does not always preserve the memory access order for ++the LDMDB instruction, when the instruction loads the PC. ++ ++The workaround is not able to handle problematic instructions when ++they are in the middle of an IT block, since a branch is not allowed ++there. In that case, the linker reports a warning and no replacement ++occurs. ++ ++The workaround is not able to replace problematic instructions with a ++PC-relative branch instruction if the @samp{.text} section is too ++large. In that case, when the branch that replaces the original code ++cannot be encoded, the linker reports a warning and no replacement ++occurs. ++ ++@cindex NO_ENUM_SIZE_WARNING ++@kindex --no-enum-size-warning ++The @option{--no-enum-size-warning} switch prevents the linker from ++warning when linking object files that specify incompatible EABI ++enumeration size attributes. For example, with this switch enabled, ++linking of an object file using 32-bit enumeration values with another ++using enumeration values fitted into the smallest possible space will ++not be diagnosed. ++ ++@cindex NO_WCHAR_SIZE_WARNING ++@kindex --no-wchar-size-warning ++The @option{--no-wchar-size-warning} switch prevents the linker from ++warning when linking object files that specify incompatible EABI ++@code{wchar_t} size attributes. For example, with this switch enabled, ++linking of an object file using 32-bit @code{wchar_t} values with another ++using 16-bit @code{wchar_t} values will not be diagnosed. ++ ++@cindex PIC_VENEER ++@kindex --pic-veneer ++The @samp{--pic-veneer} switch makes the linker use PIC sequences for ++ARM/Thumb interworking veneers, even if the rest of the binary ++is not PIC. This avoids problems on uClinux targets where ++@samp{--emit-relocs} is used to generate relocatable binaries. ++ ++@cindex STUB_GROUP_SIZE ++@kindex --stub-group-size=@var{N} ++The linker will automatically generate and insert small sequences of ++code into a linked ARM ELF executable whenever an attempt is made to ++perform a function call to a symbol that is too far away. The ++placement of these sequences of instructions - called stubs - is ++controlled by the command-line option @option{--stub-group-size=N}. ++The placement is important because a poor choice can create a need for ++duplicate stubs, increasing the code size. The linker will try to ++group stubs together in order to reduce interruptions to the flow of ++code, but it needs guidance as to how big these groups should be and ++where they should be placed. ++ ++The value of @samp{N}, the parameter to the ++@option{--stub-group-size=} option controls where the stub groups are ++placed. If it is negative then all stubs are placed after the first ++branch that needs them. If it is positive then the stubs can be ++placed either before or after the branches that need them. If the ++value of @samp{N} is 1 (either +1 or -1) then the linker will choose ++exactly where to place groups of stubs, using its built in heuristics. ++A value of @samp{N} greater than 1 (or smaller than -1) tells the ++linker that a single group of stubs can service at most @samp{N} bytes ++from the input sections. ++ ++The default, if @option{--stub-group-size=} is not specified, is ++@samp{N = +1}. ++ ++Farcalls stubs insertion is fully supported for the ARM-EABI target ++only, because it relies on object files properties not present ++otherwise. ++ ++@cindex Cortex-A8 erratum workaround ++@kindex --fix-cortex-a8 ++@kindex --no-fix-cortex-a8 ++The @samp{--fix-cortex-a8} switch enables a link-time workaround for an erratum in certain Cortex-A8 processors. The workaround is enabled by default if you are targeting the ARM v7-A architecture profile. It can be enabled otherwise by specifying @samp{--fix-cortex-a8}, or disabled unconditionally by specifying @samp{--no-fix-cortex-a8}. ++ ++The erratum only affects Thumb-2 code. Please contact ARM for further details. ++ ++@cindex Cortex-A53 erratum 835769 workaround ++@kindex --fix-cortex-a53-835769 ++@kindex --no-fix-cortex-a53-835769 ++The @samp{--fix-cortex-a53-835769} switch enables a link-time workaround for erratum 835769 present on certain early revisions of Cortex-A53 processors. The workaround is disabled by default. It can be enabled by specifying @samp{--fix-cortex-a53-835769}, or disabled unconditionally by specifying @samp{--no-fix-cortex-a53-835769}. ++ ++Please contact ARM for further details. ++ ++@kindex --merge-exidx-entries ++@kindex --no-merge-exidx-entries ++@cindex Merging exidx entries ++The @samp{--no-merge-exidx-entries} switch disables the merging of adjacent exidx entries in debuginfo. ++ ++@kindex --long-plt ++@cindex 32-bit PLT entries ++The @samp{--long-plt} option enables the use of 16 byte PLT entries ++which support up to 4Gb of code. The default is to use 12 byte PLT ++entries which only support 512Mb of code. ++ ++@kindex --no-apply-dynamic-relocs ++@cindex AArch64 rela addend ++The @samp{--no-apply-dynamic-relocs} option makes AArch64 linker do not apply ++link-time values for dynamic relocations. ++ ++@cindex Placement of SG veneers ++All SG veneers are placed in the special output section @code{.gnu.sgstubs}. ++Its start address must be set, either with the command-line option ++@samp{--section-start} or in a linker script, to indicate where to place these ++veneers in memory. ++ ++@kindex --cmse-implib ++@cindex Secure gateway import library ++The @samp{--cmse-implib} option requests that the import libraries ++specified by the @samp{--out-implib} and @samp{--in-implib} options are ++secure gateway import libraries, suitable for linking a non-secure ++executable against secure code as per ARMv8-M Security Extensions. ++ ++@kindex --in-implib=@var{file} ++@cindex Input import library ++The @samp{--in-implib=file} specifies an input import library whose symbols ++must keep the same address in the executable being produced. A warning is ++given if no @samp{--out-implib} is given but new symbols have been introduced ++in the executable that should be listed in its import library. Otherwise, if ++@samp{--out-implib} is specified, the symbols are added to the output import ++library. A warning is also given if some symbols present in the input import ++library have disappeared from the executable. This option is only effective ++for Secure Gateway import libraries, ie. when @samp{--cmse-implib} is ++specified. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset HPPA ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node HPPA ELF32 ++@section @command{ld} and HPPA 32-bit ELF Support ++@cindex HPPA multiple sub-space stubs ++@kindex --multi-subspace ++When generating a shared library, @command{ld} will by default generate ++import stubs suitable for use with a single sub-space application. ++The @samp{--multi-subspace} switch causes @command{ld} to generate export ++stubs, and different (larger) import stubs suitable for use with ++multiple sub-spaces. ++ ++@cindex HPPA stub grouping ++@kindex --stub-group-size=@var{N} ++Long branch stubs and import/export stubs are placed by @command{ld} in ++stub sections located between groups of input sections. ++@samp{--stub-group-size} specifies the maximum size of a group of input ++sections handled by one stub section. Since branch offsets are signed, ++a stub section may serve two groups of input sections, one group before ++the stub section, and one group after it. However, when using ++conditional branches that require stubs, it may be better (for branch ++prediction) that stub sections only serve one group of input sections. ++A negative value for @samp{N} chooses this scheme, ensuring that ++branches to stubs always use a negative offset. Two special values of ++@samp{N} are recognized, @samp{1} and @samp{-1}. These both instruct ++@command{ld} to automatically size input section groups for the branch types ++detected, with the same behaviour regarding stub placement as other ++positive or negative values of @samp{N} respectively. ++ ++Note that @samp{--stub-group-size} does not split input sections. A ++single input section larger than the group size specified will of course ++create a larger group (of one section). If input sections are too ++large, it may not be possible for a branch to reach its stub. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset M68K ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node M68K ++@section @command{ld} and the Motorola 68K family ++ ++@cindex Motorola 68K GOT generation ++@kindex --got=@var{type} ++The @samp{--got=@var{type}} option lets you choose the GOT generation scheme. ++The choices are @samp{single}, @samp{negative}, @samp{multigot} and ++@samp{target}. When @samp{target} is selected the linker chooses ++the default GOT generation scheme for the current target. ++@samp{single} tells the linker to generate a single GOT with ++entries only at non-negative offsets. ++@samp{negative} instructs the linker to generate a single GOT with ++entries at both negative and positive offsets. Not all environments ++support such GOTs. ++@samp{multigot} allows the linker to generate several GOTs in the ++output file. All GOT references from a single input object ++file access the same GOT, but references from different input object ++files might access different GOTs. Not all environments support such GOTs. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset MIPS ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node MIPS ++@section @command{ld} and the MIPS family ++ ++@cindex MIPS microMIPS instruction choice selection ++@kindex --insn32 ++@kindex --no-insn32 ++The @samp{--insn32} and @samp{--no-insn32} options control the choice of ++microMIPS instructions used in code generated by the linker, such as that ++in the PLT or lazy binding stubs, or in relaxation. If @samp{--insn32} is ++used, then the linker only uses 32-bit instruction encodings. By default ++or if @samp{--no-insn32} is used, all instruction encodings are used, ++including 16-bit ones where possible. ++ ++@cindex MIPS branch relocation check control ++@kindex --ignore-branch-isa ++@kindex --no-ignore-branch-isa ++The @samp{--ignore-branch-isa} and @samp{--no-ignore-branch-isa} options ++control branch relocation checks for invalid ISA mode transitions. If ++@samp{--ignore-branch-isa} is used, then the linker accepts any branch ++relocations and any ISA mode transition required is lost in relocation ++calculation, except for some cases of @code{BAL} instructions which meet ++relaxation conditions and are converted to equivalent @code{JALX} ++instructions as the associated relocation is calculated. By default ++or if @samp{--no-ignore-branch-isa} is used a check is made causing ++the loss of an ISA mode transition to produce an error. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset MMIX ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node MMIX ++@section @code{ld} and MMIX ++For MMIX, there is a choice of generating @code{ELF} object files or ++@code{mmo} object files when linking. The simulator @code{mmix} ++understands the @code{mmo} format. The binutils @code{objcopy} utility ++can translate between the two formats. ++ ++There is one special section, the @samp{.MMIX.reg_contents} section. ++Contents in this section is assumed to correspond to that of global ++registers, and symbols referring to it are translated to special symbols, ++equal to registers. In a final link, the start address of the ++@samp{.MMIX.reg_contents} section corresponds to the first allocated ++global register multiplied by 8. Register @code{$255} is not included in ++this section; it is always set to the program entry, which is at the ++symbol @code{Main} for @code{mmo} files. ++ ++Global symbols with the prefix @code{__.MMIX.start.}, for example ++@code{__.MMIX.start..text} and @code{__.MMIX.start..data} are special. ++The default linker script uses these to set the default start address ++of a section. ++ ++Initial and trailing multiples of zero-valued 32-bit words in a section, ++are left out from an mmo file. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset MSP430 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node MSP430 ++@section @code{ld} and MSP430 ++For the MSP430 it is possible to select the MPU architecture. The flag @samp{-m [mpu type]} ++will select an appropriate linker script for selected MPU type. (To get a list of known MPUs ++just pass @samp{-m help} option to the linker). ++ ++@cindex MSP430 extra sections ++The linker will recognize some extra sections which are MSP430 specific: ++ ++@table @code ++@item @samp{.vectors} ++Defines a portion of ROM where interrupt vectors located. ++ ++@item @samp{.bootloader} ++Defines the bootloader portion of the ROM (if applicable). Any code ++in this section will be uploaded to the MPU. ++ ++@item @samp{.infomem} ++Defines an information memory section (if applicable). Any code in ++this section will be uploaded to the MPU. ++ ++@item @samp{.infomemnobits} ++This is the same as the @samp{.infomem} section except that any code ++in this section will not be uploaded to the MPU. ++ ++@item @samp{.noinit} ++Denotes a portion of RAM located above @samp{.bss} section. ++ ++The last two sections are used by gcc. ++@end table ++ ++@table @option ++@cindex MSP430 Options ++@kindex --code-region ++@item --code-region=[either,lower,upper,none] ++This will transform .text* sections to [either,lower,upper].text* sections. The ++argument passed to GCC for -mcode-region is propagated to the linker ++using this option. ++ ++@kindex --data-region ++@item --data-region=[either,lower,upper,none] ++This will transform .data*, .bss* and .rodata* sections to ++[either,lower,upper].[data,bss,rodata]* sections. The argument passed to GCC ++for -mdata-region is propagated to the linker using this option. ++ ++@kindex --disable-sec-transformation ++@item --disable-sec-transformation ++Prevent the transformation of sections as specified by the @code{--code-region} ++and @code{--data-region} options. ++This is useful if you are compiling and linking using a single call to the GCC ++wrapper, and want to compile the source files using -m[code,data]-region but ++not transform the sections for prebuilt libraries and objects. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset NDS32 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node NDS32 ++@section @code{ld} and NDS32 ++@kindex relaxing on NDS32 ++For NDS32, there are some options to select relaxation behavior. The linker ++relaxes objects according to these options. ++ ++@table @code ++@item @samp{--m[no-]fp-as-gp} ++Disable/enable fp-as-gp relaxation. ++ ++@item @samp{--mexport-symbols=FILE} ++Exporting symbols and their address into FILE as linker script. ++ ++@item @samp{--m[no-]ex9} ++Disable/enable link-time EX9 relaxation. ++ ++@item @samp{--mexport-ex9=FILE} ++Export the EX9 table after linking. ++ ++@item @samp{--mimport-ex9=FILE} ++Import the Ex9 table for EX9 relaxation. ++ ++@item @samp{--mupdate-ex9} ++Update the existing EX9 table. ++ ++@item @samp{--mex9-limit=NUM} ++Maximum number of entries in the ex9 table. ++ ++@item @samp{--mex9-loop-aware} ++Avoid generating the EX9 instruction inside the loop. ++ ++@item @samp{--m[no-]ifc} ++Disable/enable the link-time IFC optimization. ++ ++@item @samp{--mifc-loop-aware} ++Avoid generating the IFC instruction inside the loop. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset NIOSII ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node Nios II ++@section @command{ld} and the Altera Nios II ++@cindex Nios II call relaxation ++@kindex --relax on Nios II ++ ++Call and immediate jump instructions on Nios II processors are limited to ++transferring control to addresses in the same 256MB memory segment, ++which may result in @command{ld} giving ++@samp{relocation truncated to fit} errors with very large programs. ++The command-line option @option{--relax} enables the generation of ++trampolines that can access the entire 32-bit address space for calls ++outside the normal @code{call} and @code{jmpi} address range. These ++trampolines are inserted at section boundaries, so may not themselves ++be reachable if an input section and its associated call trampolines are ++larger than 256MB. ++ ++The @option{--relax} option is enabled by default unless @option{-r} ++is also specified. You can disable trampoline generation by using the ++@option{--no-relax} linker option. You can also disable this optimization ++locally by using the @samp{set .noat} directive in assembly-language ++source files, as the linker-inserted trampolines use the @code{at} ++register as a temporary. ++ ++Note that the linker @option{--relax} option is independent of assembler ++relaxation options, and that using the GNU assembler's @option{-relax-all} ++option interferes with the linker's more selective call instruction relaxation. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset POWERPC ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node PowerPC ELF32 ++@section @command{ld} and PowerPC 32-bit ELF Support ++@cindex PowerPC long branches ++@kindex --relax on PowerPC ++Branches on PowerPC processors are limited to a signed 26-bit ++displacement, which may result in @command{ld} giving ++@samp{relocation truncated to fit} errors with very large programs. ++@samp{--relax} enables the generation of trampolines that can access ++the entire 32-bit address space. These trampolines are inserted at ++section boundaries, so may not themselves be reachable if an input ++section exceeds 33M in size. You may combine @samp{-r} and ++@samp{--relax} to add trampolines in a partial link. In that case ++both branches to undefined symbols and inter-section branches are also ++considered potentially out of range, and trampolines inserted. ++ ++@cindex PowerPC ELF32 options ++@table @option ++@cindex PowerPC PLT ++@kindex --bss-plt ++@item --bss-plt ++Current PowerPC GCC accepts a @samp{-msecure-plt} option that ++generates code capable of using a newer PLT and GOT layout that has ++the security advantage of no executable section ever needing to be ++writable and no writable section ever being executable. PowerPC ++@command{ld} will generate this layout, including stubs to access the ++PLT, if all input files (including startup and static libraries) were ++compiled with @samp{-msecure-plt}. @samp{--bss-plt} forces the old ++BSS PLT (and GOT layout) which can give slightly better performance. ++ ++@kindex --secure-plt ++@item --secure-plt ++@command{ld} will use the new PLT and GOT layout if it is linking new ++@samp{-fpic} or @samp{-fPIC} code, but does not do so automatically ++when linking non-PIC code. This option requests the new PLT and GOT ++layout. A warning will be given if some object file requires the old ++style BSS PLT. ++ ++@cindex PowerPC GOT ++@kindex --sdata-got ++@item --sdata-got ++The new secure PLT and GOT are placed differently relative to other ++sections compared to older BSS PLT and GOT placement. The location of ++@code{.plt} must change because the new secure PLT is an initialized ++section while the old PLT is uninitialized. The reason for the ++@code{.got} change is more subtle: The new placement allows ++@code{.got} to be read-only in applications linked with ++@samp{-z relro -z now}. However, this placement means that ++@code{.sdata} cannot always be used in shared libraries, because the ++PowerPC ABI accesses @code{.sdata} in shared libraries from the GOT ++pointer. @samp{--sdata-got} forces the old GOT placement. PowerPC ++GCC doesn't use @code{.sdata} in shared libraries, so this option is ++really only useful for other compilers that may do so. ++ ++@cindex PowerPC stub symbols ++@kindex --emit-stub-syms ++@item --emit-stub-syms ++This option causes @command{ld} to label linker stubs with a local ++symbol that encodes the stub type and destination. ++ ++@cindex PowerPC TLS optimization ++@kindex --no-tls-optimize ++@item --no-tls-optimize ++PowerPC @command{ld} normally performs some optimization of code ++sequences used to access Thread-Local Storage. Use this option to ++disable the optimization. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset POWERPC64 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node PowerPC64 ELF64 ++@section @command{ld} and PowerPC64 64-bit ELF Support ++ ++@cindex PowerPC64 ELF64 options ++@table @option ++@cindex PowerPC64 stub grouping ++@kindex --stub-group-size ++@item --stub-group-size ++Long branch stubs, PLT call stubs and TOC adjusting stubs are placed ++by @command{ld} in stub sections located between groups of input sections. ++@samp{--stub-group-size} specifies the maximum size of a group of input ++sections handled by one stub section. Since branch offsets are signed, ++a stub section may serve two groups of input sections, one group before ++the stub section, and one group after it. However, when using ++conditional branches that require stubs, it may be better (for branch ++prediction) that stub sections only serve one group of input sections. ++A negative value for @samp{N} chooses this scheme, ensuring that ++branches to stubs always use a negative offset. Two special values of ++@samp{N} are recognized, @samp{1} and @samp{-1}. These both instruct ++@command{ld} to automatically size input section groups for the branch types ++detected, with the same behaviour regarding stub placement as other ++positive or negative values of @samp{N} respectively. ++ ++Note that @samp{--stub-group-size} does not split input sections. A ++single input section larger than the group size specified will of course ++create a larger group (of one section). If input sections are too ++large, it may not be possible for a branch to reach its stub. ++ ++@cindex PowerPC64 stub symbols ++@kindex --emit-stub-syms ++@item --emit-stub-syms ++This option causes @command{ld} to label linker stubs with a local ++symbol that encodes the stub type and destination. ++ ++@cindex PowerPC64 dot symbols ++@kindex --dotsyms ++@kindex --no-dotsyms ++@item --dotsyms ++@itemx --no-dotsyms ++These two options control how @command{ld} interprets version patterns ++in a version script. Older PowerPC64 compilers emitted both a ++function descriptor symbol with the same name as the function, and a ++code entry symbol with the name prefixed by a dot (@samp{.}). To ++properly version a function @samp{foo}, the version script thus needs ++to control both @samp{foo} and @samp{.foo}. The option ++@samp{--dotsyms}, on by default, automatically adds the required ++dot-prefixed patterns. Use @samp{--no-dotsyms} to disable this ++feature. ++ ++@cindex PowerPC64 register save/restore functions ++@kindex --save-restore-funcs ++@kindex --no-save-restore-funcs ++@item --save-restore-funcs ++@itemx --no-save-restore-funcs ++These two options control whether PowerPC64 @command{ld} automatically ++provides out-of-line register save and restore functions used by ++@samp{-Os} code. The default is to provide any such referenced ++function for a normal final link, and to not do so for a relocatable ++link. ++ ++@cindex PowerPC64 TLS optimization ++@kindex --no-tls-optimize ++@item --no-tls-optimize ++PowerPC64 @command{ld} normally performs some optimization of code ++sequences used to access Thread-Local Storage. Use this option to ++disable the optimization. ++ ++@cindex PowerPC64 __tls_get_addr optimization ++@kindex --tls-get-addr-optimize ++@kindex --no-tls-get-addr-optimize ++@kindex --tls-get-addr-regsave ++@kindex --no-tls-get-addr-regsave ++@item --tls-get-addr-optimize ++@itemx --no-tls-get-addr-optimize ++These options control how PowerPC64 @command{ld} uses a special ++stub to call __tls_get_addr. PowerPC64 glibc 2.22 and later support ++an optimization that allows the second and subsequent calls to ++@code{__tls_get_addr} for a given symbol to be resolved by the special ++stub without calling in to glibc. By default the linker enables ++generation of the stub when glibc advertises the availability of ++__tls_get_addr_opt. ++Using @option{--tls-get-addr-optimize} with an older glibc won't do ++much besides slow down your applications, but may be useful if linking ++an application against an older glibc with the expectation that it ++will normally be used on systems having a newer glibc. ++@option{--tls-get-addr-regsave} forces generation of a stub that saves ++and restores volatile registers around the call into glibc. Normally, ++this is done when the linker detects a call to __tls_get_addr_desc. ++Such calls then go via the register saving stub to __tls_get_addr_opt. ++@option{--no-tls-get-addr-regsave} disables generation of the ++register saves. ++ ++@cindex PowerPC64 OPD optimization ++@kindex --no-opd-optimize ++@item --no-opd-optimize ++PowerPC64 @command{ld} normally removes @code{.opd} section entries ++corresponding to deleted link-once functions, or functions removed by ++the action of @samp{--gc-sections} or linker script @code{/DISCARD/}. ++Use this option to disable @code{.opd} optimization. ++ ++@cindex PowerPC64 OPD spacing ++@kindex --non-overlapping-opd ++@item --non-overlapping-opd ++Some PowerPC64 compilers have an option to generate compressed ++@code{.opd} entries spaced 16 bytes apart, overlapping the third word, ++the static chain pointer (unused in C) with the first word of the next ++entry. This option expands such entries to the full 24 bytes. ++ ++@cindex PowerPC64 TOC optimization ++@kindex --no-toc-optimize ++@item --no-toc-optimize ++PowerPC64 @command{ld} normally removes unused @code{.toc} section ++entries. Such entries are detected by examining relocations that ++reference the TOC in code sections. A reloc in a deleted code section ++marks a TOC word as unneeded, while a reloc in a kept code section ++marks a TOC word as needed. Since the TOC may reference itself, TOC ++relocs are also examined. TOC words marked as both needed and ++unneeded will of course be kept. TOC words without any referencing ++reloc are assumed to be part of a multi-word entry, and are kept or ++discarded as per the nearest marked preceding word. This works ++reliably for compiler generated code, but may be incorrect if assembly ++code is used to insert TOC entries. Use this option to disable the ++optimization. ++ ++@cindex PowerPC64 inline PLT call optimization ++@kindex --no-inline-optimize ++@item --no-inline-optimize ++PowerPC64 @command{ld} normally replaces inline PLT call sequences ++marked with @code{R_PPC64_PLTSEQ}, @code{R_PPC64_PLTCALL}, ++@code{R_PPC64_PLT16_HA} and @code{R_PPC64_PLT16_LO_DS} relocations by ++a number of @code{nop}s and a direct call when the function is defined ++locally and can't be overridden by some other definition. This option ++disables that optimization. ++ ++@cindex PowerPC64 multi-TOC ++@kindex --no-multi-toc ++@item --no-multi-toc ++If given any toc option besides @code{-mcmodel=medium} or ++@code{-mcmodel=large}, PowerPC64 GCC generates code for a TOC model ++where TOC ++entries are accessed with a 16-bit offset from r2. This limits the ++total TOC size to 64K. PowerPC64 @command{ld} extends this limit by ++grouping code sections such that each group uses less than 64K for its ++TOC entries, then inserts r2 adjusting stubs between inter-group ++calls. @command{ld} does not split apart input sections, so cannot ++help if a single input file has a @code{.toc} section that exceeds ++64K, most likely from linking multiple files with @command{ld -r}. ++Use this option to turn off this feature. ++ ++@cindex PowerPC64 TOC sorting ++@kindex --no-toc-sort ++@item --no-toc-sort ++By default, @command{ld} sorts TOC sections so that those whose file ++happens to have a section called @code{.init} or @code{.fini} are ++placed first, followed by TOC sections referenced by code generated ++with PowerPC64 gcc's @code{-mcmodel=small}, and lastly TOC sections ++referenced only by code generated with PowerPC64 gcc's ++@code{-mcmodel=medium} or @code{-mcmodel=large} options. Doing this ++results in better TOC grouping for multi-TOC. Use this option to turn ++off this feature. ++ ++@cindex PowerPC64 PLT stub alignment ++@kindex --plt-align ++@kindex --no-plt-align ++@item --plt-align ++@itemx --no-plt-align ++Use these options to control whether individual PLT call stubs are ++aligned to a 32-byte boundary, or to the specified power of two ++boundary when using @code{--plt-align=}. A negative value may be ++specified to pad PLT call stubs so that they do not cross the ++specified power of two boundary (or the minimum number of boundaries ++if a PLT stub is so large that it must cross a boundary). By default ++PLT call stubs are aligned to 32-byte boundaries. ++ ++@cindex PowerPC64 PLT call stub static chain ++@kindex --plt-static-chain ++@kindex --no-plt-static-chain ++@item --plt-static-chain ++@itemx --no-plt-static-chain ++Use these options to control whether PLT call stubs load the static ++chain pointer (r11). @code{ld} defaults to not loading the static ++chain since there is never any need to do so on a PLT call. ++ ++@cindex PowerPC64 PLT call stub thread safety ++@kindex --plt-thread-safe ++@kindex --no-plt-thread-safe ++@item --plt-thread-safe ++@itemx --no-plt-thread-safe ++With power7's weakly ordered memory model, it is possible when using ++lazy binding for ld.so to update a plt entry in one thread and have ++another thread see the individual plt entry words update in the wrong ++order, despite ld.so carefully writing in the correct order and using ++memory write barriers. To avoid this we need some sort of read ++barrier in the call stub, or use LD_BIND_NOW=1. By default, @code{ld} ++looks for calls to commonly used functions that create threads, and if ++seen, adds the necessary barriers. Use these options to change the ++default behaviour. ++ ++@cindex PowerPC64 ELFv2 PLT localentry optimization ++@kindex --plt-localentry ++@kindex --no-plt-localentry ++@item --plt-localentry ++@itemx --no-localentry ++ELFv2 functions with localentry:0 are those with a single entry point, ++ie. global entry == local entry, and that have no requirement on r2 ++(the TOC/GOT pointer) or r12, and guarantee r2 is unchanged on return. ++Such an external function can be called via the PLT without saving r2 ++or restoring it on return, avoiding a common load-hit-store for small ++functions. The optimization is attractive, with up to 40% reduction ++in execution time for a small function, but can result in symbol ++interposition failures. Also, minor changes in a shared library, ++including system libraries, can cause a function that was localentry:0 ++to become localentry:8. This will result in a dynamic loader ++complaint and failure to run. The option is experimental, use with ++care. @option{--no-plt-localentry} is the default. ++ ++@cindex PowerPC64 Power10 stubs ++@kindex --power10-stubs ++@kindex --no-power10-stubs ++@item --power10-stubs ++@itemx --no-power10-stubs ++When PowerPC64 @command{ld} links input object files containing ++relocations used on power10 prefixed instructions it normally creates ++linkage stubs (PLT call and long branch) using power10 instructions ++for @code{@@notoc} PLT calls where @code{r2} is not known. The ++power10 notoc stubs are smaller and faster, so are preferred for ++power10. @option{--power10-stubs} and @option{--no-power10-stubs} ++allow you to override the linker's selection of stub instructions. ++@option{--power10-stubs=auto} allows the user to select the default ++auto mode. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset S/390 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node S/390 ELF ++@section @command{ld} and S/390 ELF Support ++ ++@cindex S/390 ELF options ++@table @option ++ ++@cindex S/390 ++@kindex --s390-pgste ++@item --s390-pgste ++This option marks the result file with a @code{PT_S390_PGSTE} ++segment. The Linux kernel is supposed to allocate 4k page tables for ++binaries marked that way. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset SPU ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node SPU ELF ++@section @command{ld} and SPU ELF Support ++ ++@cindex SPU ELF options ++@table @option ++ ++@cindex SPU plugins ++@kindex --plugin ++@item --plugin ++This option marks an executable as a PIC plugin module. ++ ++@cindex SPU overlays ++@kindex --no-overlays ++@item --no-overlays ++Normally, @command{ld} recognizes calls to functions within overlay ++regions, and redirects such calls to an overlay manager via a stub. ++@command{ld} also provides a built-in overlay manager. This option ++turns off all this special overlay handling. ++ ++@cindex SPU overlay stub symbols ++@kindex --emit-stub-syms ++@item --emit-stub-syms ++This option causes @command{ld} to label overlay stubs with a local ++symbol that encodes the stub type and destination. ++ ++@cindex SPU extra overlay stubs ++@kindex --extra-overlay-stubs ++@item --extra-overlay-stubs ++This option causes @command{ld} to add overlay call stubs on all ++function calls out of overlay regions. Normally stubs are not added ++on calls to non-overlay regions. ++ ++@cindex SPU local store size ++@kindex --local-store=lo:hi ++@item --local-store=lo:hi ++@command{ld} usually checks that a final executable for SPU fits in ++the address range 0 to 256k. This option may be used to change the ++range. Disable the check entirely with @option{--local-store=0:0}. ++ ++@cindex SPU ++@kindex --stack-analysis ++@item --stack-analysis ++SPU local store space is limited. Over-allocation of stack space ++unnecessarily limits space available for code and data, while ++under-allocation results in runtime failures. If given this option, ++@command{ld} will provide an estimate of maximum stack usage. ++@command{ld} does this by examining symbols in code sections to ++determine the extents of functions, and looking at function prologues ++for stack adjusting instructions. A call-graph is created by looking ++for relocations on branch instructions. The graph is then searched ++for the maximum stack usage path. Note that this analysis does not ++find calls made via function pointers, and does not handle recursion ++and other cycles in the call graph. Stack usage may be ++under-estimated if your code makes such calls. Also, stack usage for ++dynamic allocation, e.g. alloca, will not be detected. If a link map ++is requested, detailed information about each function's stack usage ++and calls will be given. ++ ++@cindex SPU ++@kindex --emit-stack-syms ++@item --emit-stack-syms ++This option, if given along with @option{--stack-analysis} will result ++in @command{ld} emitting stack sizing symbols for each function. ++These take the form @code{__stack_} for global ++functions, and @code{__stack__} for static ++functions. @code{} is the section id in hex. The value of ++such symbols is the stack requirement for the corresponding function. ++The symbol size will be zero, type @code{STT_NOTYPE}, binding ++@code{STB_LOCAL}, and section @code{SHN_ABS}. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset TICOFF ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node TI COFF ++@section @command{ld}'s Support for Various TI COFF Versions ++@cindex TI COFF versions ++@kindex --format=@var{version} ++The @samp{--format} switch allows selection of one of the various ++TI COFF versions. The latest of this writing is 2; versions 0 and 1 are ++also supported. The TI COFF versions also vary in header byte-order ++format; @command{ld} will read any version or byte order, but the output ++header format depends on the default specified by the specific target. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset WIN32 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node WIN32 ++@section @command{ld} and WIN32 (cygwin/mingw) ++ ++This section describes some of the win32 specific @command{ld} issues. ++See @ref{Options,,Command-line Options} for detailed description of the ++command-line options mentioned here. ++ ++@table @emph ++@cindex import libraries ++@item import libraries ++The standard Windows linker creates and uses so-called import ++libraries, which contains information for linking to dll's. They are ++regular static archives and are handled as any other static ++archive. The cygwin and mingw ports of @command{ld} have specific ++support for creating such libraries provided with the ++@samp{--out-implib} command-line option. ++ ++@item Resource only DLLs ++It is possible to create a DLL that only contains resources, ie just a ++@samp{.rsrc} section, but in order to do so a custom linker script ++must be used. This is because the built-in default linker scripts ++will always create @samp{.text} and @samp{.idata} sections, even if ++there is no input to go into them. ++ ++The script should look like this, although the @code{OUTPUT_FORMAT} ++should be changed to match the desired format. ++ ++@example ++OUTPUT_FORMAT(pei-i386) ++SECTIONS ++@{ ++ . = SIZEOF_HEADERS; ++ . = ALIGN(__section_alignment__); ++ .rsrc __image_base__ + __section_alignment__ : ALIGN(4) ++ @{ ++ KEEP (*(.rsrc)) ++ KEEP (*(.rsrc$*)) ++ @} ++ /DISCARD/ : @{ *(*) @} ++@} ++@end example ++ ++With this script saved to a file called, eg @file{rsrc.ld}, a command ++line like this can be used to create the resource only DLL ++@file{rsrc.dll} from an input file called @file{rsrc.o}: ++ ++@smallexample ++ld -dll --subsystem windows -e 0 -s rsrc.o -o rsrc.dll -T rsrc.ld ++@end smallexample ++ ++@item exporting DLL symbols ++@cindex exporting DLL symbols ++The cygwin/mingw @command{ld} has several ways to export symbols for dll's. ++ ++@table @emph ++@item using auto-export functionality ++@cindex using auto-export functionality ++By default @command{ld} exports symbols with the auto-export functionality, ++which is controlled by the following command-line options: ++ ++@itemize ++@item --export-all-symbols [This is the default] ++@item --exclude-symbols ++@item --exclude-libs ++@item --exclude-modules-for-implib ++@item --version-script ++@end itemize ++ ++When auto-export is in operation, @command{ld} will export all the non-local ++(global and common) symbols it finds in a DLL, with the exception of a few ++symbols known to belong to the system's runtime and libraries. As it will ++often not be desirable to export all of a DLL's symbols, which may include ++private functions that are not part of any public interface, the command-line ++options listed above may be used to filter symbols out from the list for ++exporting. The @samp{--output-def} option can be used in order to see the ++final list of exported symbols with all exclusions taken into effect. ++ ++If @samp{--export-all-symbols} is not given explicitly on the ++command line, then the default auto-export behavior will be @emph{disabled} ++if either of the following are true: ++ ++@itemize ++@item A DEF file is used. ++@item Any symbol in any object file was marked with the __declspec(dllexport) attribute. ++@end itemize ++ ++@item using a DEF file ++@cindex using a DEF file ++Another way of exporting symbols is using a DEF file. A DEF file is ++an ASCII file containing definitions of symbols which should be ++exported when a dll is created. Usually it is named @samp{.def} and is added as any other object file to the linker's ++command line. The file's name must end in @samp{.def} or @samp{.DEF}. ++ ++@example ++gcc -o .def ++@end example ++ ++Using a DEF file turns off the normal auto-export behavior, unless the ++@samp{--export-all-symbols} option is also used. ++ ++Here is an example of a DEF file for a shared library called @samp{xyz.dll}: ++ ++@example ++LIBRARY "xyz.dll" BASE=0x20000000 ++ ++EXPORTS ++foo ++bar ++_bar = bar ++another_foo = abc.dll.afoo ++var1 DATA ++doo = foo == foo2 ++eoo DATA == var1 ++@end example ++ ++This example defines a DLL with a non-default base address and seven ++symbols in the export table. The third exported symbol @code{_bar} is an ++alias for the second. The fourth symbol, @code{another_foo} is resolved ++by "forwarding" to another module and treating it as an alias for ++@code{afoo} exported from the DLL @samp{abc.dll}. The final symbol ++@code{var1} is declared to be a data object. The @samp{doo} symbol in ++export library is an alias of @samp{foo}, which gets the string name ++in export table @samp{foo2}. The @samp{eoo} symbol is an data export ++symbol, which gets in export table the name @samp{var1}. ++ ++The optional @code{LIBRARY } command indicates the @emph{internal} ++name of the output DLL. If @samp{} does not include a suffix, ++the default library suffix, @samp{.DLL} is appended. ++ ++When the .DEF file is used to build an application, rather than a ++library, the @code{NAME } command should be used instead of ++@code{LIBRARY}. If @samp{} does not include a suffix, the default ++executable suffix, @samp{.EXE} is appended. ++ ++With either @code{LIBRARY } or @code{NAME } the optional ++specification @code{BASE = } may be used to specify a ++non-default base address for the image. ++ ++If neither @code{LIBRARY } nor @code{NAME } is specified, ++or they specify an empty string, the internal name is the same as the ++filename specified on the command line. ++ ++The complete specification of an export symbol is: ++ ++@example ++EXPORTS ++ ( ( ( [ = ] ) ++ | ( = . )) ++ [ @@ ] [NONAME] [DATA] [CONSTANT] [PRIVATE] [== ] ) * ++@end example ++ ++Declares @samp{} as an exported symbol from the DLL, or declares ++@samp{} as an exported alias for @samp{}; or declares ++@samp{} as a "forward" alias for the symbol ++@samp{} in the DLL @samp{}. ++Optionally, the symbol may be exported by the specified ordinal ++@samp{} alias. The optional @samp{} is the to be used ++string in import/export table for the symbol. ++ ++The optional keywords that follow the declaration indicate: ++ ++@code{NONAME}: Do not put the symbol name in the DLL's export table. It ++will still be exported by its ordinal alias (either the value specified ++by the .def specification or, otherwise, the value assigned by the ++linker). The symbol name, however, does remain visible in the import ++library (if any), unless @code{PRIVATE} is also specified. ++ ++@code{DATA}: The symbol is a variable or object, rather than a function. ++The import lib will export only an indirect reference to @code{foo} as ++the symbol @code{_imp__foo} (ie, @code{foo} must be resolved as ++@code{*_imp__foo}). ++ ++@code{CONSTANT}: Like @code{DATA}, but put the undecorated @code{foo} as ++well as @code{_imp__foo} into the import library. Both refer to the ++read-only import address table's pointer to the variable, not to the ++variable itself. This can be dangerous. If the user code fails to add ++the @code{dllimport} attribute and also fails to explicitly add the ++extra indirection that the use of the attribute enforces, the ++application will behave unexpectedly. ++ ++@code{PRIVATE}: Put the symbol in the DLL's export table, but do not put ++it into the static import library used to resolve imports at link time. The ++symbol can still be imported using the @code{LoadLibrary/GetProcAddress} ++API at runtime or by using the GNU ld extension of linking directly to ++the DLL without an import library. ++ ++See ld/deffilep.y in the binutils sources for the full specification of ++other DEF file statements ++ ++@cindex creating a DEF file ++While linking a shared dll, @command{ld} is able to create a DEF file ++with the @samp{--output-def } command-line option. ++ ++@item Using decorations ++@cindex Using decorations ++Another way of marking symbols for export is to modify the source code ++itself, so that when building the DLL each symbol to be exported is ++declared as: ++ ++@example ++__declspec(dllexport) int a_variable ++__declspec(dllexport) void a_function(int with_args) ++@end example ++ ++All such symbols will be exported from the DLL. If, however, ++any of the object files in the DLL contain symbols decorated in ++this way, then the normal auto-export behavior is disabled, unless ++the @samp{--export-all-symbols} option is also used. ++ ++Note that object files that wish to access these symbols must @emph{not} ++decorate them with dllexport. Instead, they should use dllimport, ++instead: ++ ++@example ++__declspec(dllimport) int a_variable ++__declspec(dllimport) void a_function(int with_args) ++@end example ++ ++This complicates the structure of library header files, because ++when included by the library itself the header must declare the ++variables and functions as dllexport, but when included by client ++code the header must declare them as dllimport. There are a number ++of idioms that are typically used to do this; often client code can ++omit the __declspec() declaration completely. See ++@samp{--enable-auto-import} and @samp{automatic data imports} for more ++information. ++@end table ++ ++@cindex automatic data imports ++@item automatic data imports ++The standard Windows dll format supports data imports from dlls only ++by adding special decorations (dllimport/dllexport), which let the ++compiler produce specific assembler instructions to deal with this ++issue. This increases the effort necessary to port existing Un*x ++code to these platforms, especially for large ++c++ libraries and applications. The auto-import feature, which was ++initially provided by Paul Sokolovsky, allows one to omit the ++decorations to achieve a behavior that conforms to that on POSIX/Un*x ++platforms. This feature is enabled with the @samp{--enable-auto-import} ++command-line option, although it is enabled by default on cygwin/mingw. ++The @samp{--enable-auto-import} option itself now serves mainly to ++suppress any warnings that are ordinarily emitted when linked objects ++trigger the feature's use. ++ ++auto-import of variables does not always work flawlessly without ++additional assistance. Sometimes, you will see this message ++ ++"variable '' can't be auto-imported. Please read the ++documentation for ld's @code{--enable-auto-import} for details." ++ ++The @samp{--enable-auto-import} documentation explains why this error ++occurs, and several methods that can be used to overcome this difficulty. ++One of these methods is the @emph{runtime pseudo-relocs} feature, described ++below. ++ ++@cindex runtime pseudo-relocation ++For complex variables imported from DLLs (such as structs or classes), ++object files typically contain a base address for the variable and an ++offset (@emph{addend}) within the variable--to specify a particular ++field or public member, for instance. Unfortunately, the runtime loader used ++in win32 environments is incapable of fixing these references at runtime ++without the additional information supplied by dllimport/dllexport decorations. ++The standard auto-import feature described above is unable to resolve these ++references. ++ ++The @samp{--enable-runtime-pseudo-relocs} switch allows these references to ++be resolved without error, while leaving the task of adjusting the references ++themselves (with their non-zero addends) to specialized code provided by the ++runtime environment. Recent versions of the cygwin and mingw environments and ++compilers provide this runtime support; older versions do not. However, the ++support is only necessary on the developer's platform; the compiled result will ++run without error on an older system. ++ ++@samp{--enable-runtime-pseudo-relocs} is not the default; it must be explicitly ++enabled as needed. ++ ++@cindex direct linking to a dll ++@item direct linking to a dll ++The cygwin/mingw ports of @command{ld} support the direct linking, ++including data symbols, to a dll without the usage of any import ++libraries. This is much faster and uses much less memory than does the ++traditional import library method, especially when linking large ++libraries or applications. When @command{ld} creates an import lib, each ++function or variable exported from the dll is stored in its own bfd, even ++though a single bfd could contain many exports. The overhead involved in ++storing, loading, and processing so many bfd's is quite large, and explains the ++tremendous time, memory, and storage needed to link against particularly ++large or complex libraries when using import libs. ++ ++Linking directly to a dll uses no extra command-line switches other than ++@samp{-L} and @samp{-l}, because @command{ld} already searches for a number ++of names to match each library. All that is needed from the developer's ++perspective is an understanding of this search, in order to force ld to ++select the dll instead of an import library. ++ ++ ++For instance, when ld is called with the argument @samp{-lxxx} it will attempt ++to find, in the first directory of its search path, ++ ++@example ++libxxx.dll.a ++xxx.dll.a ++libxxx.a ++xxx.lib ++libxxx.lib ++cygxxx.dll (*) ++libxxx.dll ++xxx.dll ++@end example ++ ++before moving on to the next directory in the search path. ++ ++(*) Actually, this is not @samp{cygxxx.dll} but in fact is @samp{xxx.dll}, ++where @samp{} is set by the @command{ld} option ++@samp{--dll-search-prefix=}. In the case of cygwin, the standard gcc spec ++file includes @samp{--dll-search-prefix=cyg}, so in effect we actually search for ++@samp{cygxxx.dll}. ++ ++Other win32-based unix environments, such as mingw or pw32, may use other ++@samp{}es, although at present only cygwin makes use of this feature. It ++was originally intended to help avoid name conflicts among dll's built for the ++various win32/un*x environments, so that (for example) two versions of a zlib dll ++could coexist on the same machine. ++ ++The generic cygwin/mingw path layout uses a @samp{bin} directory for ++applications and dll's and a @samp{lib} directory for the import ++libraries (using cygwin nomenclature): ++ ++@example ++bin/ ++ cygxxx.dll ++lib/ ++ libxxx.dll.a (in case of dll's) ++ libxxx.a (in case of static archive) ++@end example ++ ++Linking directly to a dll without using the import library can be ++done two ways: ++ ++1. Use the dll directly by adding the @samp{bin} path to the link line ++@example ++gcc -Wl,-verbose -o a.exe -L../bin/ -lxxx ++@end example ++ ++However, as the dll's often have version numbers appended to their names ++(@samp{cygncurses-5.dll}) this will often fail, unless one specifies ++@samp{-L../bin -lncurses-5} to include the version. Import libs are generally ++not versioned, and do not have this difficulty. ++ ++2. Create a symbolic link from the dll to a file in the @samp{lib} ++directory according to the above mentioned search pattern. This ++should be used to avoid unwanted changes in the tools needed for ++making the app/dll. ++ ++@example ++ln -s bin/cygxxx.dll lib/[cyg|lib|]xxx.dll[.a] ++@end example ++ ++Then you can link without any make environment changes. ++ ++@example ++gcc -Wl,-verbose -o a.exe -L../lib/ -lxxx ++@end example ++ ++This technique also avoids the version number problems, because the following is ++perfectly legal ++ ++@example ++bin/ ++ cygxxx-5.dll ++lib/ ++ libxxx.dll.a -> ../bin/cygxxx-5.dll ++@end example ++ ++Linking directly to a dll without using an import lib will work ++even when auto-import features are exercised, and even when ++@samp{--enable-runtime-pseudo-relocs} is used. ++ ++Given the improvements in speed and memory usage, one might justifiably ++wonder why import libraries are used at all. There are three reasons: ++ ++1. Until recently, the link-directly-to-dll functionality did @emph{not} ++work with auto-imported data. ++ ++2. Sometimes it is necessary to include pure static objects within the ++import library (which otherwise contains only bfd's for indirection ++symbols that point to the exports of a dll). Again, the import lib ++for the cygwin kernel makes use of this ability, and it is not ++possible to do this without an import lib. ++ ++3. Symbol aliases can only be resolved using an import lib. This is ++critical when linking against OS-supplied dll's (eg, the win32 API) ++in which symbols are usually exported as undecorated aliases of their ++stdcall-decorated assembly names. ++ ++So, import libs are not going away. But the ability to replace ++true import libs with a simple symbolic link to (or a copy of) ++a dll, in many cases, is a useful addition to the suite of tools ++binutils makes available to the win32 developer. Given the ++massive improvements in memory requirements during linking, storage ++requirements, and linking speed, we expect that many developers ++will soon begin to use this feature whenever possible. ++ ++@item symbol aliasing ++@table @emph ++@item adding additional names ++Sometimes, it is useful to export symbols with additional names. ++A symbol @samp{foo} will be exported as @samp{foo}, but it can also be ++exported as @samp{_foo} by using special directives in the DEF file ++when creating the dll. This will affect also the optional created ++import library. Consider the following DEF file: ++ ++@example ++LIBRARY "xyz.dll" BASE=0x61000000 ++ ++EXPORTS ++foo ++_foo = foo ++@end example ++ ++The line @samp{_foo = foo} maps the symbol @samp{foo} to @samp{_foo}. ++ ++Another method for creating a symbol alias is to create it in the ++source code using the "weak" attribute: ++ ++@example ++void foo () @{ /* Do something. */; @} ++void _foo () __attribute__ ((weak, alias ("foo"))); ++@end example ++ ++See the gcc manual for more information about attributes and weak ++symbols. ++ ++@item renaming symbols ++Sometimes it is useful to rename exports. For instance, the cygwin ++kernel does this regularly. A symbol @samp{_foo} can be exported as ++@samp{foo} but not as @samp{_foo} by using special directives in the ++DEF file. (This will also affect the import library, if it is ++created). In the following example: ++ ++@example ++LIBRARY "xyz.dll" BASE=0x61000000 ++ ++EXPORTS ++_foo = foo ++@end example ++ ++The line @samp{_foo = foo} maps the exported symbol @samp{foo} to ++@samp{_foo}. ++@end table ++ ++Note: using a DEF file disables the default auto-export behavior, ++unless the @samp{--export-all-symbols} command-line option is used. ++If, however, you are trying to rename symbols, then you should list ++@emph{all} desired exports in the DEF file, including the symbols ++that are not being renamed, and do @emph{not} use the ++@samp{--export-all-symbols} option. If you list only the ++renamed symbols in the DEF file, and use @samp{--export-all-symbols} ++to handle the other symbols, then the both the new names @emph{and} ++the original names for the renamed symbols will be exported. ++In effect, you'd be aliasing those symbols, not renaming them, ++which is probably not what you wanted. ++ ++@cindex weak externals ++@item weak externals ++The Windows object format, PE, specifies a form of weak symbols called ++weak externals. When a weak symbol is linked and the symbol is not ++defined, the weak symbol becomes an alias for some other symbol. There ++are three variants of weak externals: ++@itemize ++@item Definition is searched for in objects and libraries, historically ++called lazy externals. ++@item Definition is searched for only in other objects, not in libraries. ++This form is not presently implemented. ++@item No search; the symbol is an alias. This form is not presently ++implemented. ++@end itemize ++As a GNU extension, weak symbols that do not specify an alternate symbol ++are supported. If the symbol is undefined when linking, the symbol ++uses a default value. ++ ++@cindex aligned common symbols ++@item aligned common symbols ++As a GNU extension to the PE file format, it is possible to specify the ++desired alignment for a common symbol. This information is conveyed from ++the assembler or compiler to the linker by means of GNU-specific commands ++carried in the object file's @samp{.drectve} section, which are recognized ++by @command{ld} and respected when laying out the common symbols. Native ++tools will be able to process object files employing this GNU extension, ++but will fail to respect the alignment instructions, and may issue noisy ++warnings about unknown linker directives. ++ ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset XTENSA ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node Xtensa ++@section @code{ld} and Xtensa Processors ++ ++@cindex Xtensa processors ++The default @command{ld} behavior for Xtensa processors is to interpret ++@code{SECTIONS} commands so that lists of explicitly named sections in a ++specification with a wildcard file will be interleaved when necessary to ++keep literal pools within the range of PC-relative load offsets. For ++example, with the command: ++ ++@smallexample ++SECTIONS ++@{ ++ .text : @{ ++ *(.literal .text) ++ @} ++@} ++@end smallexample ++ ++@noindent ++@command{ld} may interleave some of the @code{.literal} ++and @code{.text} sections from different object files to ensure that the ++literal pools are within the range of PC-relative load offsets. A valid ++interleaving might place the @code{.literal} sections from an initial ++group of files followed by the @code{.text} sections of that group of ++files. Then, the @code{.literal} sections from the rest of the files ++and the @code{.text} sections from the rest of the files would follow. ++ ++@cindex @option{--relax} on Xtensa ++@cindex relaxing on Xtensa ++Relaxation is enabled by default for the Xtensa version of @command{ld} and ++provides two important link-time optimizations. The first optimization ++is to combine identical literal values to reduce code size. A redundant ++literal will be removed and all the @code{L32R} instructions that use it ++will be changed to reference an identical literal, as long as the ++location of the replacement literal is within the offset range of all ++the @code{L32R} instructions. The second optimization is to remove ++unnecessary overhead from assembler-generated ``longcall'' sequences of ++@code{L32R}/@code{CALLX@var{n}} when the target functions are within ++range of direct @code{CALL@var{n}} instructions. ++ ++For each of these cases where an indirect call sequence can be optimized ++to a direct call, the linker will change the @code{CALLX@var{n}} ++instruction to a @code{CALL@var{n}} instruction, remove the @code{L32R} ++instruction, and remove the literal referenced by the @code{L32R} ++instruction if it is not used for anything else. Removing the ++@code{L32R} instruction always reduces code size but can potentially ++hurt performance by changing the alignment of subsequent branch targets. ++By default, the linker will always preserve alignments, either by ++switching some instructions between 24-bit encodings and the equivalent ++density instructions or by inserting a no-op in place of the @code{L32R} ++instruction that was removed. If code size is more important than ++performance, the @option{--size-opt} option can be used to prevent the ++linker from widening density instructions or inserting no-ops, except in ++a few cases where no-ops are required for correctness. ++ ++The following Xtensa-specific command-line options can be used to ++control the linker: ++ ++@cindex Xtensa options ++@table @option ++@item --size-opt ++When optimizing indirect calls to direct calls, optimize for code size ++more than performance. With this option, the linker will not insert ++no-ops or widen density instructions to preserve branch target ++alignment. There may still be some cases where no-ops are required to ++preserve the correctness of the code. ++ ++@item --abi-windowed ++@itemx --abi-call0 ++Choose ABI for the output object and for the generated PLT code. ++PLT code inserted by the linker must match ABI of the output object ++because windowed and call0 ABI use incompatible function call ++conventions. ++Default ABI is chosen by the ABI tag in the @code{.xtensa.info} section ++of the first input object. ++A warning is issued if ABI tags of input objects do not match each other ++or the chosen output object ABI. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifclear SingleFormat ++@node BFD ++@chapter BFD ++ ++@cindex back end ++@cindex object file management ++@cindex object formats available ++@kindex objdump -i ++The linker accesses object and archive files using the BFD libraries. ++These libraries allow the linker to use the same routines to operate on ++object files whatever the object file format. A different object file ++format can be supported simply by creating a new BFD back end and adding ++it to the library. To conserve runtime memory, however, the linker and ++associated tools are usually configured to support only a subset of the ++object file formats available. You can use @code{objdump -i} ++(@pxref{objdump,,objdump,binutils.info,The GNU Binary Utilities}) to ++list all the formats available for your configuration. ++ ++@cindex BFD requirements ++@cindex requirements for BFD ++As with most implementations, BFD is a compromise between ++several conflicting requirements. The major factor influencing ++BFD design was efficiency: any time used converting between ++formats is time which would not have been spent had BFD not ++been involved. This is partly offset by abstraction payback; since ++BFD simplifies applications and back ends, more time and care ++may be spent optimizing algorithms for a greater speed. ++ ++One minor artifact of the BFD solution which you should bear in ++mind is the potential for information loss. There are two places where ++useful information can be lost using the BFD mechanism: during ++conversion and during output. @xref{BFD information loss}. ++ ++@menu ++* BFD outline:: How it works: an outline of BFD ++@end menu ++ ++@node BFD outline ++@section How It Works: An Outline of BFD ++@cindex opening object files ++@include bfdsumm.texi ++@end ifclear ++ ++@node Reporting Bugs ++@chapter Reporting Bugs ++@cindex bugs in @command{ld} ++@cindex reporting bugs in @command{ld} ++ ++Your bug reports play an essential role in making @command{ld} reliable. ++ ++Reporting a bug may help you by bringing a solution to your problem, or ++it may not. But in any case the principal function of a bug report is ++to help the entire community by making the next version of @command{ld} ++work better. Bug reports are your contribution to the maintenance of ++@command{ld}. ++ ++In order for a bug report to serve its purpose, you must include the ++information that enables us to fix the bug. ++ ++@menu ++* Bug Criteria:: Have you found a bug? ++* Bug Reporting:: How to report bugs ++@end menu ++ ++@node Bug Criteria ++@section Have You Found a Bug? ++@cindex bug criteria ++ ++If you are not sure whether you have found a bug, here are some guidelines: ++ ++@itemize @bullet ++@cindex fatal signal ++@cindex linker crash ++@cindex crash of linker ++@item ++If the linker gets a fatal signal, for any input whatever, that is a ++@command{ld} bug. Reliable linkers never crash. ++ ++@cindex error on valid input ++@item ++If @command{ld} produces an error message for valid input, that is a bug. ++ ++@cindex invalid input ++@item ++If @command{ld} does not produce an error message for invalid input, that ++may be a bug. In the general case, the linker can not verify that ++object files are correct. ++ ++@item ++If you are an experienced user of linkers, your suggestions for ++improvement of @command{ld} are welcome in any case. ++@end itemize ++ ++@node Bug Reporting ++@section How to Report Bugs ++@cindex bug reports ++@cindex @command{ld} bugs, reporting ++ ++A number of companies and individuals offer support for @sc{gnu} ++products. If you obtained @command{ld} from a support organization, we ++recommend you contact that organization first. ++ ++You can find contact information for many support companies and ++individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs ++distribution. ++ ++@ifset BUGURL ++Otherwise, send bug reports for @command{ld} to ++@value{BUGURL}. ++@end ifset ++ ++The fundamental principle of reporting bugs usefully is this: ++@strong{report all the facts}. If you are not sure whether to state a ++fact or leave it out, state it! ++ ++Often people omit facts because they think they know what causes the ++problem and assume that some details do not matter. Thus, you might ++assume that the name of a symbol you use in an example does not ++matter. Well, probably it does not, but one cannot be sure. Perhaps ++the bug is a stray memory reference which happens to fetch from the ++location where that name is stored in memory; perhaps, if the name ++were different, the contents of that location would fool the linker ++into doing the right thing despite the bug. Play it safe and give a ++specific, complete example. That is the easiest thing for you to do, ++and the most helpful. ++ ++Keep in mind that the purpose of a bug report is to enable us to fix ++the bug if it is new to us. Therefore, always write your bug reports ++on the assumption that the bug has not been reported previously. ++ ++Sometimes people give a few sketchy facts and ask, ``Does this ring a ++bell?'' This cannot help us fix a bug, so it is basically useless. We ++respond by asking for enough details to enable us to investigate. ++You might as well expedite matters by sending them to begin with. ++ ++To enable us to fix the bug, you should include all these things: ++ ++@itemize @bullet ++@item ++The version of @command{ld}. @command{ld} announces it if you start it with ++the @samp{--version} argument. ++ ++Without this, we will not know whether there is any point in looking for ++the bug in the current version of @command{ld}. ++ ++@item ++Any patches you may have applied to the @command{ld} source, including any ++patches made to the @code{BFD} library. ++ ++@item ++The type of machine you are using, and the operating system name and ++version number. ++ ++@item ++What compiler (and its version) was used to compile @command{ld}---e.g. ++``@code{gcc-2.7}''. ++ ++@item ++The command arguments you gave the linker to link your example and ++observe the bug. To guarantee you will not omit something important, ++list them all. A copy of the Makefile (or the output from make) is ++sufficient. ++ ++If we were to try to guess the arguments, we would probably guess wrong ++and then we might not encounter the bug. ++ ++@item ++A complete input file, or set of input files, that will reproduce the ++bug. It is generally most helpful to send the actual object files ++provided that they are reasonably small. Say no more than 10K. For ++bigger files you can either make them available by FTP or HTTP or else ++state that you are willing to send the object file(s) to whomever ++requests them. (Note - your email will be going to a mailing list, so ++we do not want to clog it up with large attachments). But small ++attachments are best. ++ ++If the source files were assembled using @code{gas} or compiled using ++@code{gcc}, then it may be OK to send the source files rather than the ++object files. In this case, be sure to say exactly what version of ++@code{gas} or @code{gcc} was used to produce the object files. Also say ++how @code{gas} or @code{gcc} were configured. ++ ++@item ++A description of what behavior you observe that you believe is ++incorrect. For example, ``It gets a fatal signal.'' ++ ++Of course, if the bug is that @command{ld} gets a fatal signal, then we ++will certainly notice it. But if the bug is incorrect output, we might ++not notice unless it is glaringly wrong. You might as well not give us ++a chance to make a mistake. ++ ++Even if the problem you experience is a fatal signal, you should still ++say so explicitly. Suppose something strange is going on, such as, your ++copy of @command{ld} is out of sync, or you have encountered a bug in the ++C library on your system. (This has happened!) Your copy might crash ++and ours would not. If you told us to expect a crash, then when ours ++fails to crash, we would know that the bug was not happening for us. If ++you had not told us to expect a crash, then we would not be able to draw ++any conclusion from our observations. ++ ++@item ++If you wish to suggest changes to the @command{ld} source, send us context ++diffs, as generated by @code{diff} with the @samp{-u}, @samp{-c}, or ++@samp{-p} option. Always send diffs from the old file to the new file. ++If you even discuss something in the @command{ld} source, refer to it by ++context, not by line number. ++ ++The line numbers in our development sources will not match those in your ++sources. Your line numbers would convey no useful information to us. ++@end itemize ++ ++Here are some things that are not necessary: ++ ++@itemize @bullet ++@item ++A description of the envelope of the bug. ++ ++Often people who encounter a bug spend a lot of time investigating ++which changes to the input file will make the bug go away and which ++changes will not affect it. ++ ++This is often time consuming and not very useful, because the way we ++will find the bug is by running a single example under the debugger ++with breakpoints, not by pure deduction from a series of examples. ++We recommend that you save your time for something else. ++ ++Of course, if you can find a simpler example to report @emph{instead} ++of the original one, that is a convenience for us. Errors in the ++output will be easier to spot, running under the debugger will take ++less time, and so on. ++ ++However, simplification is not vital; if you do not want to do this, ++report the bug anyway and send us the entire test case you used. ++ ++@item ++A patch for the bug. ++ ++A patch for the bug does help us if it is a good one. But do not omit ++the necessary information, such as the test case, on the assumption that ++a patch is all we need. We might see problems with your patch and decide ++to fix the problem another way, or we might not understand it at all. ++ ++Sometimes with a program as complicated as @command{ld} it is very hard to ++construct an example that will make the program follow a certain path ++through the code. If you do not send us the example, we will not be ++able to construct one, so we will not be able to verify that the bug is ++fixed. ++ ++And if we cannot understand what bug you are trying to fix, or why your ++patch should be an improvement, we will not install it. A test case will ++help us to understand. ++ ++@item ++A guess about what the bug is or what it depends on. ++ ++Such guesses are usually wrong. Even we cannot guess right about such ++things without first using the debugger to find the facts. ++@end itemize ++ ++@node MRI ++@appendix MRI Compatible Script Files ++@cindex MRI compatibility ++To aid users making the transition to @sc{gnu} @command{ld} from the MRI ++linker, @command{ld} can use MRI compatible linker scripts as an ++alternative to the more general-purpose linker scripting language ++described in @ref{Scripts}. MRI compatible linker scripts have a much ++simpler command set than the scripting language otherwise used with ++@command{ld}. @sc{gnu} @command{ld} supports the most commonly used MRI ++linker commands; these commands are described here. ++ ++In general, MRI scripts aren't of much use with the @code{a.out} object ++file format, since it only has three sections and MRI scripts lack some ++features to make use of them. ++ ++You can specify a file containing an MRI-compatible script using the ++@samp{-c} command-line option. ++ ++Each command in an MRI-compatible script occupies its own line; each ++command line starts with the keyword that identifies the command (though ++blank lines are also allowed for punctuation). If a line of an ++MRI-compatible script begins with an unrecognized keyword, @command{ld} ++issues a warning message, but continues processing the script. ++ ++Lines beginning with @samp{*} are comments. ++ ++You can write these commands using all upper-case letters, or all ++lower case; for example, @samp{chip} is the same as @samp{CHIP}. ++The following list shows only the upper-case form of each command. ++ ++@table @code ++@cindex @code{ABSOLUTE} (MRI) ++@item ABSOLUTE @var{secname} ++@itemx ABSOLUTE @var{secname}, @var{secname}, @dots{} @var{secname} ++Normally, @command{ld} includes in the output file all sections from all ++the input files. However, in an MRI-compatible script, you can use the ++@code{ABSOLUTE} command to restrict the sections that will be present in ++your output program. If the @code{ABSOLUTE} command is used at all in a ++script, then only the sections named explicitly in @code{ABSOLUTE} ++commands will appear in the linker output. You can still use other ++input sections (whatever you select on the command line, or using ++@code{LOAD}) to resolve addresses in the output file. ++ ++@cindex @code{ALIAS} (MRI) ++@item ALIAS @var{out-secname}, @var{in-secname} ++Use this command to place the data from input section @var{in-secname} ++in a section called @var{out-secname} in the linker output file. ++ ++@var{in-secname} may be an integer. ++ ++@cindex @code{ALIGN} (MRI) ++@item ALIGN @var{secname} = @var{expression} ++Align the section called @var{secname} to @var{expression}. The ++@var{expression} should be a power of two. ++ ++@cindex @code{BASE} (MRI) ++@item BASE @var{expression} ++Use the value of @var{expression} as the lowest address (other than ++absolute addresses) in the output file. ++ ++@cindex @code{CHIP} (MRI) ++@item CHIP @var{expression} ++@itemx CHIP @var{expression}, @var{expression} ++This command does nothing; it is accepted only for compatibility. ++ ++@cindex @code{END} (MRI) ++@item END ++This command does nothing whatever; it's only accepted for compatibility. ++ ++@cindex @code{FORMAT} (MRI) ++@item FORMAT @var{output-format} ++Similar to the @code{OUTPUT_FORMAT} command in the more general linker ++language, but restricted to S-records, if @var{output-format} is @samp{S} ++ ++@cindex @code{LIST} (MRI) ++@item LIST @var{anything}@dots{} ++Print (to the standard output file) a link map, as produced by the ++@command{ld} command-line option @samp{-M}. ++ ++The keyword @code{LIST} may be followed by anything on the ++same line, with no change in its effect. ++ ++@cindex @code{LOAD} (MRI) ++@item LOAD @var{filename} ++@itemx LOAD @var{filename}, @var{filename}, @dots{} @var{filename} ++Include one or more object file @var{filename} in the link; this has the ++same effect as specifying @var{filename} directly on the @command{ld} ++command line. ++ ++@cindex @code{NAME} (MRI) ++@item NAME @var{output-name} ++@var{output-name} is the name for the program produced by @command{ld}; the ++MRI-compatible command @code{NAME} is equivalent to the command-line ++option @samp{-o} or the general script language command @code{OUTPUT}. ++ ++@cindex @code{ORDER} (MRI) ++@item ORDER @var{secname}, @var{secname}, @dots{} @var{secname} ++@itemx ORDER @var{secname} @var{secname} @var{secname} ++Normally, @command{ld} orders the sections in its output file in the ++order in which they first appear in the input files. In an MRI-compatible ++script, you can override this ordering with the @code{ORDER} command. The ++sections you list with @code{ORDER} will appear first in your output ++file, in the order specified. ++ ++@cindex @code{PUBLIC} (MRI) ++@item PUBLIC @var{name}=@var{expression} ++@itemx PUBLIC @var{name},@var{expression} ++@itemx PUBLIC @var{name} @var{expression} ++Supply a value (@var{expression}) for external symbol ++@var{name} used in the linker input files. ++ ++@cindex @code{SECT} (MRI) ++@item SECT @var{secname}, @var{expression} ++@itemx SECT @var{secname}=@var{expression} ++@itemx SECT @var{secname} @var{expression} ++You can use any of these three forms of the @code{SECT} command to ++specify the start address (@var{expression}) for section @var{secname}. ++If you have more than one @code{SECT} statement for the same ++@var{secname}, only the @emph{first} sets the start address. ++@end table ++ ++@node GNU Free Documentation License ++@appendix GNU Free Documentation License ++@include fdl.texi ++ ++@node LD Index ++@unnumbered LD Index ++ ++@printindex cp ++ ++@tex ++% I think something like @@colophon should be in texinfo. In the ++% meantime: ++\long\def\colophon{\hbox to0pt{}\vfill ++\centerline{The body of this manual is set in} ++\centerline{\fontname\tenrm,} ++\centerline{with headings in {\bf\fontname\tenbf}} ++\centerline{and examples in {\tt\fontname\tentt}.} ++\centerline{{\it\fontname\tenit\/} and} ++\centerline{{\sl\fontname\tensl\/}} ++\centerline{are used for emphasis.}\vfill} ++\page\colophon ++% Blame: doc@@cygnus.com, 28mar91. ++@end tex ++ ++@bye +diff -rupN binutils.orig/ld/ldlex.h binutils-2.41/ld/ldlex.h +--- binutils.orig/ld/ldlex.h 2023-10-19 12:11:47.296940552 +0100 ++++ binutils-2.41/ld/ldlex.h 2023-10-19 12:11:56.517949627 +0100 +@@ -168,10 +168,15 @@ enum option_values + OPTION_CTF_VARIABLES, + OPTION_NO_CTF_VARIABLES, + OPTION_CTF_SHARE_TYPES, ++ OPTION_ERROR_EXECSTACK, ++ OPTION_NO_ERROR_EXECSTACK, ++ OPTION_WARN_EXECSTACK_OBJECTS, + OPTION_WARN_EXECSTACK, + OPTION_NO_WARN_EXECSTACK, + OPTION_WARN_RWX_SEGMENTS, + OPTION_NO_WARN_RWX_SEGMENTS, ++ OPTION_ERROR_RWX_SEGMENTS, ++ OPTION_NO_ERROR_RWX_SEGMENTS, + OPTION_ENABLE_LINKER_VERSION, + OPTION_DISABLE_LINKER_VERSION, + OPTION_REMAP_INPUTS, +diff -rupN binutils.orig/ld/lexsup.c binutils-2.41/ld/lexsup.c +--- binutils.orig/ld/lexsup.c 2023-10-19 12:11:47.297940553 +0100 ++++ binutils-2.41/ld/lexsup.c 2023-10-19 12:11:56.517949627 +0100 +@@ -551,14 +551,27 @@ static const struct ld_option ld_options + { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS}, + '\0', NULL, N_("Warn if global constructors/destructors are seen"), + TWO_DASHES }, ++ ++ { {"error-execstack", no_argument, NULL, OPTION_ERROR_EXECSTACK}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"no-error-execstack", no_argument, NULL, OPTION_NO_ERROR_EXECSTACK}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"warn-execstack-objects", no_argument, NULL, OPTION_WARN_EXECSTACK_OBJECTS}, ++ '\0', NULL, NULL, TWO_DASHES }, + { {"warn-execstack", no_argument, NULL, OPTION_WARN_EXECSTACK}, +- '\0', NULL, N_("Warn when creating an executable stack"), TWO_DASHES }, ++ '\0', NULL, NULL, TWO_DASHES }, + { {"no-warn-execstack", no_argument, NULL, OPTION_NO_WARN_EXECSTACK}, +- '\0', NULL, N_("Do not warn when creating an executable stack"), TWO_DASHES }, ++ '\0', NULL, NULL, TWO_DASHES }, ++ ++ { {"error-rwx-segments", no_argument, NULL, OPTION_ERROR_RWX_SEGMENTS}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"no-error-rwx-segments", no_argument, NULL, OPTION_NO_ERROR_RWX_SEGMENTS}, ++ '\0', NULL, NULL, TWO_DASHES }, + { {"warn-rwx-segments", no_argument, NULL, OPTION_WARN_RWX_SEGMENTS}, +- '\0', NULL, N_("Warn when creating executable segments"), TWO_DASHES }, ++ '\0', NULL, NULL, TWO_DASHES }, + { {"no-warn-rwx-segments", no_argument, NULL, OPTION_NO_WARN_RWX_SEGMENTS}, +- '\0', NULL, N_("Do not warn when creating executable segments"), TWO_DASHES }, ++ '\0', NULL, NULL, TWO_DASHES }, ++ + { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP}, + '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES }, + { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE}, +@@ -944,12 +957,29 @@ parse_args (unsigned argc, char **argv) + case OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS: + link_info.non_contiguous_regions_warnings = true; + break; ++ ++ case OPTION_ERROR_EXECSTACK: ++ link_info.error_execstack = 1; ++ break; ++ case OPTION_NO_ERROR_EXECSTACK: ++ link_info.error_execstack = 0; ++ break; ++ case OPTION_WARN_EXECSTACK_OBJECTS: ++ link_info.warn_execstack = 2; ++ break; + case OPTION_WARN_EXECSTACK: + link_info.warn_execstack = 1; + break; + case OPTION_NO_WARN_EXECSTACK: + link_info.warn_execstack = 0; + break; ++ ++ case OPTION_ERROR_RWX_SEGMENTS: ++ link_info.warn_is_error_for_rwx_segments = 1; ++ break; ++ case OPTION_NO_ERROR_RWX_SEGMENTS: ++ link_info.warn_is_error_for_rwx_segments = 0; ++ break; + case OPTION_WARN_RWX_SEGMENTS: + link_info.no_warn_rwx_segments = 0; + link_info.user_warn_rwx_segments = 1; +@@ -958,6 +988,7 @@ parse_args (unsigned argc, char **argv) + link_info.no_warn_rwx_segments = 1; + link_info.user_warn_rwx_segments = 1; + break; ++ + case 'e': + lang_add_entry (optarg, true); + break; +@@ -2239,24 +2270,32 @@ elf_static_list_options (FILE *file) + -z muldefs Allow multiple definitions\n")); + fprintf (file, _("\ + -z stack-size=SIZE Set size of stack segment\n")); ++ + fprintf (file, _("\ + -z execstack Mark executable as requiring executable stack\n")); + fprintf (file, _("\ +- -z noexecstack Mark executable as not requiring executable stack\n")); +-#if DEFAULT_LD_WARN_EXECSTACK == 1 ++ -z noexecstack Mark executable as not requiring executable stack\n")); + fprintf (file, _("\ +- --warn-execstack Generate a warning if the stack is executable (default)\n")); ++ --warn-execstack-objects Generate a warning if an object file requests an executable stack\n")); ++#if DEFAULT_LD_WARN_EXECSTACK == 0 ++ fprintf (file, _("\ ++ --warn-execstack Generate a warning if creating an executable stack\n")); + #else + fprintf (file, _("\ +- --warn-execstack Generate a warning if the stack is executable\n")); ++ --warn-execstack Generate a warning if creating an executable stack (default)\n")); + #endif + #if DEFAULT_LD_WARN_EXECSTACK == 0 + fprintf (file, _("\ +- --no-warn-execstack Do not generate a warning if the stack is executable (default)\n")); ++ --no-warn-execstack Do not generate a warning if creating an executable stack (default)\n")); + #else + fprintf (file, _("\ +- --no-warn-execstack Do not generate a warning if the stack is executable\n")); ++ --no-warn-execstack Do not generate a warning if creating an executable stack\n")); + #endif ++ fprintf (file, _("\ ++ --error-execstack Turn warnings about executable stacks into errors\n")); ++ fprintf (file, _("\ ++ --no-error-execstack Do not turn warnings about executable stacks into errors\n")); ++ + #if DEFAULT_LD_WARN_RWX_SEGMENTS + fprintf (file, _("\ + --warn-rwx-segments Generate a warning if a LOAD segment has RWX permissions (default)\n")); +@@ -2269,6 +2308,11 @@ elf_static_list_options (FILE *file) + --no-warn-rwx-segments Do not generate a warning if a LOAD segments has RWX permissions (default)\n")); + #endif + fprintf (file, _("\ ++ --error-rwx-segments Turn warnings about loadable RWX segments into errors\n")); ++ fprintf (file, _("\ ++ --no-error-rwx-segments Do not turn warnings about loadable RWX segments into errors\n")); ++ ++ fprintf (file, _("\ + -z unique-symbol Avoid duplicated local symbol names\n")); + fprintf (file, _("\ + -z nounique-symbol Keep duplicated local symbol names (default)\n")); +diff -rupN binutils.orig/ld/testsuite/ld-elf/commonpage2.d binutils-2.41/ld/testsuite/ld-elf/commonpage2.d +--- binutils.orig/ld/testsuite/ld-elf/commonpage2.d 2023-10-19 12:11:47.381940636 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/commonpage2.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,6 +1,6 @@ + #source: maxpage1.s + #as: --32 +-#ld: -z max-page-size=0x200000 -z common-page-size=0x100000 -T maxpage4.t ++#ld: -z max-page-size=0x200000 -z common-page-size=0x100000 -T maxpage4.t --no-warn-rwx-segments + #readelf: -l --wide + #target: x86_64-*-linux* + +diff -rupN binutils.orig/ld/testsuite/ld-elf/elf.exp binutils-2.41/ld/testsuite/ld-elf/elf.exp +--- binutils.orig/ld/testsuite/ld-elf/elf.exp 2023-10-19 12:11:47.385940640 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/elf.exp 2023-10-19 12:11:56.517949627 +0100 +@@ -216,7 +216,7 @@ if { [istarget *-*-*linux*] + || [istarget *-*-gnu*] } { + run_ld_link_tests [list \ + [list "stack exec" \ +- "-z execstack" \ ++ "-z execstack --no-error-execstack" \ + "" \ + "" \ + {stack.s} \ +@@ -263,14 +263,14 @@ if { [istarget *-*-*linux*] + # of the first test by forcing the flags. + run_ld_link_tests [list \ + [list "PR ld/29072 (warn about an executable .note.GNU-stack)" \ +- "-e 0 --warn-execstack --warn-rwx-segments" \ ++ "-e 0 --warn-execstack --warn-rwx-segments --no-error-rwx-segments --no-error-execstack" \ + "" \ + "" \ + {pr29072-a.s} \ + {{ld pr29072.a.warn}} \ + "pr29072-a.exe"] \ + [list "PR 29072 (warn about -z execstack)" \ +- "-z execstack --warn-execstack" \ ++ "-z execstack --warn-execstack --no-error-execstack" \ + "" \ + "" \ + {stack.s} \ +@@ -284,14 +284,14 @@ if { [istarget *-*-*linux*] + {} \ + "pr29072-d.exe"] \ + [list "Ensure that a warning issued when creating a segment with RWX permissions" \ +- "-e 0 -Tnobits-1.t --warn-rwx-segments" \ ++ "-e 0 -Tnobits-1.t --warn-rwx-segments --no-error-rwx-segments" \ + "" \ + "" \ + {nobits-1.s} \ + {{ld rwx-segments-1.l}} \ + "rwx-segments-1.exe"] \ + [list "Ensure that a warning issued when creating a TLS segment with execute permission" \ +- "-e 0 -T rwx-segments-2.t --warn-rwx-segments" \ ++ "-e 0 -T rwx-segments-2.t --warn-rwx-segments --no-error-rwx-segments" \ + "" \ + "" \ + {size-2.s} \ +@@ -311,7 +311,7 @@ if { [istarget *-*-*linux*] + if { [target_defaults_to_execstack] } { + run_ld_link_tests [list \ + [list "PR ld/29072 (warn about absent .note.GNU-stack)" \ +- "-e 0 -z stack-size=0x123400 --warn-execstack" \ ++ "-e 0 -z stack-size=0x123400 --warn-execstack --no-error-execstack" \ + "" \ + "" \ + {pr29072-b.s} \ +@@ -321,7 +321,7 @@ if { [istarget *-*-*linux*] + } else { + run_ld_link_tests [list \ + [list "PR ld/29072 (ignore absent .note.GNU-stack)" \ +- "-e 0 -z stack-size=0x123400" \ ++ "-e 0 -z stack-size=0x123400 --no-error-execstack" \ + "" \ + "" \ + {pr29072-b.s} \ +diff -rupN binutils.orig/ld/testsuite/ld-elf/elf.exp.orig binutils-2.41/ld/testsuite/ld-elf/elf.exp.orig +--- binutils.orig/ld/testsuite/ld-elf/elf.exp.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/elf.exp.orig 2023-07-03 00:00:00.000000000 +0100 +@@ -0,0 +1,632 @@ ++# Expect script for various ELF tests. ++# Copyright (C) 2002-2023 Free Software Foundation, Inc. ++# ++# This file is part of the GNU Binutils. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++# MA 02110-1301, USA. ++# ++ ++# Exclude non-ELF targets. ++ ++if ![is_elf_format] { ++ return ++} ++ ++# Return true if target is riscv little endian. ++# xfail the riscv little endain targets for the compressed1d1 test; ++# The riscv big endian targets and others should pass. ++proc riscv_little_endian { } { ++ if { [istarget "riscv32-*-*"] ++ || [istarget "riscv64-*-*"] ++ || [istarget "riscv32le-*-*"] ++ || [istarget "riscv64le-*-*"] } { ++ return 1 ++ } ++ return 0 ++} ++ ++set old_ldflags $LDFLAGS ++if { [istarget spu*-*-*] } { ++ set LDFLAGS "$LDFLAGS --local-store 0:0" ++} ++ ++# hpux .comm differs from everyone else ++set hpux "" ++set old_asflags $ASFLAGS ++if [istarget "*-*-hpux*"] { ++ set hpux "--defsym HPUX=1" ++ set ASFLAGS "$ASFLAGS --defsym HPUX=1" ++} ++ ++if { [istarget alpha*-*-* ] } { ++ # The compress1 test is written expecting 32-bit addresses; force the ++ # executable down into the low address space to match. ++ # ??? How can we adjust just the one testcase? ++ set LDFLAGS "$LDFLAGS -Ttext-segment 0x1000000" ++ set ASFLAGS "$ASFLAGS --defsym NO_SET=1" ++} ++ ++if [istarget "tic6x-*-*"] { ++ append ASFLAGS " -mpic -mpid=near" ++} ++ ++if { [istarget "*-*-solaris*"] } { ++ # Same for Solaris ++ set options_regsub(ld) {-melf_x86_64 -melf_x86_64_sol2} ++} ++ ++if { [is_remote host] } then { ++ remote_download host merge.ld ++} ++ ++# Note - the output file from the second test (symbol3w.a) is ++# used in the proc is_elf64 test below... ++run_ld_link_tests [list \ ++ [list "Build symbol3.a" \ ++ "" "" $hpux \ ++ {symbol3.s} {} "symbol3.a" ] \ ++ [list "Build symbol3w.a" \ ++ "" "" "" \ ++ {symbol3w.s} {} "symbol3w.a" ] \ ++] ++ ++ ++if [is_elf64 tmpdir/symbol3w.a] { ++ set ASFLAGS "$ASFLAGS --defsym ALIGN=3" ++ set pr23900_1_exp "pr23900-1-64.rd" ++ set pr25490_2_exp "pr25490-2-64.rd" ++ set pr25490_3_exp "pr25490-3-64.rd" ++ set pr25490_4_exp "pr25490-4-64.rd" ++ set pr25490_5_exp "pr25490-5-64.rd" ++ set pr25490_6_exp "pr25490-6-64.rd" ++} else { ++ set ASFLAGS "$ASFLAGS --defsym ALIGN=2" ++ set pr23900_1_exp "pr23900-1-32.rd" ++ if { [istarget avr-*-*] ++ || [istarget h8300-*-*] ++ || [istarget ip2k-*-*] ++ || [istarget m68hc11-*] ++ || [istarget "z80-*-*"] } { ++ set pr25490_2_exp "pr25490-2-16.rd" ++ set pr25490_3_exp "pr25490-3-16.rd" ++ set pr25490_4_exp "pr25490-4-16.rd" ++ set pr25490_5_exp "pr25490-5-16.rd" ++ set pr25490_6_exp "pr25490-6-16.rd" ++ } else { ++ set pr25490_2_exp "pr25490-2-32.rd" ++ set pr25490_3_exp "pr25490-3-32.rd" ++ set pr25490_4_exp "pr25490-4-32.rd" ++ set pr25490_5_exp "pr25490-5-32.rd" ++ set pr25490_6_exp "pr25490-6-32.rd" ++ } ++} ++ ++ ++ ++# Targets that use _bfd_generic_link_add_symbols won't pass pr21703 tests ++run_ld_link_tests { ++ {"PR ld/21703" ++ "--allow-multiple-definition tmpdir/pr21703-1.o tmpdir/pr21703-2.o" "" "" \ ++ {pr21703-1.s pr21703-2.s} {{readelf {-s} pr21703.sd}} "pr21703" } ++ {"PR ld/21703 -r" ++ "-r --allow-multiple-definition tmpdir/pr21703-3.o tmpdir/pr21703-4.o" "" "" \ ++ {pr21703-3.s pr21703-4.s} {{readelf {-s} pr21703-r.sd}} "pr21703.o" } ++} \[is_generic\] ++ ++if [is_underscore_target] { ++ set ASFLAGS "$ASFLAGS --defsym UNDERSCORE=1" ++} ++ ++set saved_ASFLAGS "$ASFLAGS" ++if { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } { ++ set ASFLAGS "$ASFLAGS -mx86-used-note=no" ++} ++ ++# Build libraries required for SHF_GNU_RETAIN tests. ++if { [check_gc_sections_available] && [supports_gnu_osabi] } { ++ run_ld_link_tests [list \ ++ [list "Build libretain5.a" "" "" "" \ ++ {retain5lib.s} {} "libretain5.a"] \ ++ [list "Build libretain6.a" "" "" "" \ ++ {retain6lib.s} {} "libretain6.a"] \ ++ ] ++} ++ ++set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] ++foreach t $test_list { ++ # We need to strip the ".d", but can leave the dirname. ++ verbose [file rootname $t] ++ run_dump_test [file rootname $t] ++} ++ ++set ASFLAGS "$saved_ASFLAGS" ++ ++# Check that the --out-implib option work correctly. ++# Targets that don't use elf.em won't support this. ++run_ld_link_tests [list \ ++ [list "Generate empty import library" \ ++ "--out-implib=tmpdir/implib.lib" "" \ ++ [concat "--defsym NO_GLOBAL=1" $hpux] \ ++ {implib.s} \ ++ {{ld empty-implib.out}} \ ++ "implib" ] \ ++ [list "Generate import library" \ ++ "--out-implib=tmpdir/implib.lib" "" \ ++ $hpux \ ++ {implib.s} \ ++ {{readelf {-s tmpdir/implib.lib} implib.rd}} \ ++ "implib" ] \ ++] \[uses_genelf\] ++ ++#v850 gas complains about .tbss.var section attributes. ++if { [check_gc_sections_available] && ![istarget "v850-*-*"] } { ++ run_ld_link_tests { ++ {"--gc-sections on tls variable" ++ "--gc-section" "" "" {tls_gc.s} {} "tls_gc"} ++ } ++} ++ ++proc target_defaults_to_execstack {} { ++ global base_dir ++ ++ # If the linker has been configured with --enable-default-execstack=no then ++ # this proc should always return 0. ++ if { [file exists $base_dir/config.status] } { ++ set status [remote_exec host grep "enable-default-execstack=no" $base_dir/config.status] ++ if { [lindex $status 0] == 0 } { ++ return 0 ++ } else { ++ verbose -log "$base_dir/config.status does not contain enable-default-execstack=no" ++ } ++ } else { ++ verbose -log "there is no file $base_dir/config.status" ++ } ++ ++ if { [istarget "aarch64*-*-*"] ++ || [istarget "arc*-*-*"] ++ || [istarget "cris*-*-*"] ++ || [istarget "ia64*-*-*"] ++ || [istarget "loongarch*-*-*"] ++ || [istarget "nios2*-*-*"] ++ || [istarget "powerpc64*-*-*"] ++ || [istarget "pru*-*-*"] ++ || [istarget "riscv*-*-*"] ++ || [istarget "tilegx*-*-*"] ++ || [istarget "tilepro*-*-*"] } { ++ return 0 ++ } ++ return 1 ++} ++ ++if { [istarget *-*-*linux*] ++ || [istarget *-*-nacl*] ++ || [istarget *-*-gnu*] } { ++ run_ld_link_tests [list \ ++ [list "stack exec" \ ++ "-z execstack" \ ++ "" \ ++ "" \ ++ {stack.s} \ ++ {{readelf {-Wl} stack-exec.rd}} \ ++ "stack-exec.exe"] \ ++ [list "stack noexec" \ ++ "-z noexecstack" \ ++ "" \ ++ "" \ ++ {stack.s} \ ++ {{readelf {-Wl} stack-noexec.rd}} \ ++ "stack-noexec.exe"] \ ++ [list "stack size" \ ++ "-z stack-size=0x123400 -z noexecstack" \ ++ "" \ ++ "" \ ++ {stack.s} \ ++ {{readelf {-Wl} stack-size.rd}} \ ++ "stack-size.exe"] \ ++ [list "PT_GNU_PROPERTY alignment" \ ++ "" \ ++ "" \ ++ "" \ ++ {pr23900-1.s} \ ++ [list [list "readelf" {-Wl} $pr23900_1_exp]] \ ++ "pr23900-1.exe"] \ ++ ] ++ ++ # Test the linker's generation of execstack and executable segment warnings. ++ # Since these are normally pruned from the linker's output we temporarily ++ # disable tha action here. ++ rename prune_warnings_extra old_prune_warnings_extra ++ proc prune_warnings_extra { text } { ++ return $text ++ } ++ ++ set curr_ldflags $LDFLAGS ++ if { [istarget powerpc*-*-*] && ![istarget powerpc64*-*-*] } { ++ # Don't generate an executable .plt section ++ set LDFLAGS "$LDFLAGS --secure-plt" ++ } ++ ++ # Since the warnings can be disabled by configure, ensure consistency ++ # of the first test by forcing the flags. ++ run_ld_link_tests [list \ ++ [list "PR ld/29072 (warn about an executable .note.GNU-stack)" \ ++ "-e 0 --warn-execstack --warn-rwx-segments" \ ++ "" \ ++ "" \ ++ {pr29072-a.s} \ ++ {{ld pr29072.a.warn}} \ ++ "pr29072-a.exe"] \ ++ [list "PR 29072 (warn about -z execstack)" \ ++ "-z execstack --warn-execstack" \ ++ "" \ ++ "" \ ++ {stack.s} \ ++ {{ld pr29072.c.warn}} \ ++ "pr29072-c.exe"] \ ++ [list "PR ld/29072 (suppress warnings about executable stack)" \ ++ "-e 0 --no-warn-execstack" \ ++ "" \ ++ "" \ ++ {pr29072-a.s} \ ++ {} \ ++ "pr29072-d.exe"] \ ++ [list "Ensure that a warning issued when creating a segment with RWX permissions" \ ++ "-e 0 -Tnobits-1.t --warn-rwx-segments" \ ++ "" \ ++ "" \ ++ {nobits-1.s} \ ++ {{ld rwx-segments-1.l}} \ ++ "rwx-segments-1.exe"] \ ++ [list "Ensure that a warning issued when creating a TLS segment with execute permission" \ ++ "-e 0 -T rwx-segments-2.t --warn-rwx-segments" \ ++ "" \ ++ "" \ ++ {size-2.s} \ ++ {{ld rwx-segments-2.l}} \ ++ "rwx-segments-2.exe"] \ ++ [list "Ensure that the RWX warning can be suppressed" \ ++ "-e 0 -Tnobits-1.t --no-warn-rwx-segments" \ ++ "" \ ++ "" \ ++ {nobits-1.s} \ ++ {} \ ++ "rwx-segments-3.exe"] \ ++ ] ++ ++ set LDFLAGS $curr_ldflags ++ ++ if { [target_defaults_to_execstack] } { ++ run_ld_link_tests [list \ ++ [list "PR ld/29072 (warn about absent .note.GNU-stack)" \ ++ "-e 0 -z stack-size=0x123400 --warn-execstack" \ ++ "" \ ++ "" \ ++ {pr29072-b.s} \ ++ {{ld pr29072.b.warn}} \ ++ "pr29072-b.exe"] \ ++ ] ++ } else { ++ run_ld_link_tests [list \ ++ [list "PR ld/29072 (ignore absent .note.GNU-stack)" \ ++ "-e 0 -z stack-size=0x123400" \ ++ "" \ ++ "" \ ++ {pr29072-b.s} \ ++ {} \ ++ "pr29072-b.exe"] \ ++ ] ++ } ++ ++ # Restore the normal pruning behaviour. ++ rename prune_warnings_extra "" ++ rename old_prune_warnings_extra prune_warnings_extra ++} ++ ++if [check_gc_sections_available] { ++ run_ld_link_tests [list \ ++ [list "__patchable_function_entries section 2" \ ++ "--gc-sections -e _start" \ ++ "" \ ++ "" \ ++ {pr25490-2.s} \ ++ [list [list "readelf" {-SW} $pr25490_2_exp]] \ ++ "pr25490-2.exe"] \ ++ [list "__patchable_function_entries section 3" \ ++ "--gc-sections -e _start" \ ++ "" \ ++ "" \ ++ {pr25490-3.s} \ ++ [list [list "readelf" {-SW} $pr25490_3_exp]] \ ++ "pr25490-3.exe"] \ ++ [list "__patchable_function_entries section 4" \ ++ "--gc-sections -e _start" \ ++ "" \ ++ "" \ ++ {pr25490-4.s} \ ++ [list [list "readelf" {-SW} $pr25490_4_exp]] \ ++ "pr25490-4.exe"] \ ++ [list "__patchable_function_entries section 5" \ ++ "--gc-sections -e _start" \ ++ "" \ ++ "" \ ++ {pr25490-5.s} \ ++ [list [list "readelf" {-SW} $pr25490_5_exp]] \ ++ "pr25490-5.exe"] \ ++ [list "__patchable_function_entries section 6" \ ++ "--gc-sections -e _start" \ ++ "" \ ++ "" \ ++ {pr25490-6.s} \ ++ [list [list "readelf" {-SW} $pr25490_6_exp]] \ ++ "pr25490-6.exe"] \ ++ ] ++} ++ ++set LDFLAGS $old_ldflags ++set ASFLAGS $old_asflags ++ ++# Check to see if the C compiler works ++if { ![check_compiler_available] } { ++ return ++} ++ ++if [check_gc_sections_available] { ++ run_cc_link_tests { ++ {"PR ld/13195" "-Wl,--gc-sections" "" ++ {pr13195.c} {} "pr13195"} ++ } ++} ++ ++set array_tests { ++ {"preinit array" "" "" ++ {preinit.c} "preinit" "preinit.out"} ++ {"init array" "" "" ++ {init.c} "init" "init.out"} ++ {"fini array" "" "" ++ {fini.c} "fini" "fini.out"} ++ {"init array mixed" "" "" ++ {init-mixed.c} "init-mixed" "init-mixed.out" "-I."} ++} ++set array_tests_pie { ++ {"PIE preinit array" "-pie" "" ++ {preinit.c} "preinit" "preinit.out" "-fPIE"} ++ {"PIE init array" "-pie" "" ++ {init.c} "init" "init.out" "-fPIE"} ++ {"PIE fini array" "-pie" "" ++ {fini.c} "fini" "fini.out" "-fPIE"} ++ {"PIE init array mixed" "-pie" "" ++ {init-mixed.c} "init-mixed" "init-mixed.out" "-I. -fPIE"} ++ {"PIE PR ld/14525" "-pie" "" ++ {pr14525.c} "pr14525" "pr14525.out" "-fPIE"} ++} ++set array_tests_static { ++ {"static preinit array" "-static" "" ++ {preinit.c} "preinit" "preinit.out"} ++ {"static init array" "-static" "" ++ {init.c} "init" "init.out"} ++ {"static fini array" "-static" "" ++ {fini.c} "fini" "fini.out"} ++ {"static init array mixed" "-static" "" ++ {init-mixed.c} "init-mixed" "init-mixed.out" "-I."} ++} ++ ++# NetBSD ELF systems do not currently support the .*_array sections. ++set xfails "*-*-netbsd*" ++run_ld_link_exec_tests $array_tests $xfails ++ ++if { [istarget *-*-linux*] ++ || [istarget *-*-nacl*] ++ || [istarget *-*-gnu*] } { ++ run_ld_link_exec_tests $array_tests_pie $xfails ++ ++ if { $STATIC_PIE_LDFLAGS != "" } then { ++ run_ld_link_exec_tests [list \ ++ [list \ ++ "Static PIE preinit array" \ ++ "$STATIC_PIE_LDFLAGS" \ ++ "" \ ++ {preinit.c} \ ++ "preinit-static-pie" \ ++ "preinit.out" \ ++ "-fPIE" \ ++ ] \ ++ [list \ ++ "Static PIE init array" \ ++ "$STATIC_PIE_LDFLAGS" \ ++ "" \ ++ {init.c} \ ++ "init-static-pie" \ ++ "init.out" \ ++ "-fPIE" \ ++ ] \ ++ [list \ ++ "Static PIE fini array" \ ++ "$STATIC_PIE_LDFLAGS" \ ++ "" \ ++ {fini.c} \ ++ "fini-static-pie" \ ++ "fini.out" \ ++ "-fPIE" \ ++ ] \ ++ [list \ ++ "Static PIE init array mixed" \ ++ "$STATIC_PIE_LDFLAGS" \ ++ "" \ ++ {init-mixed.c} \ ++ "init-mixed-static-pie" \ ++ "init-mixed.out" \ ++ "-I. -fPIE" \ ++ ] \ ++ [list \ ++ "Static PIE PR ld/14525" \ ++ "$STATIC_PIE_LDFLAGS" \ ++ "" \ ++ {pr14525.c} \ ++ "pr14525-static-pie" \ ++ "pr14525.out" \ ++ "-fPIE" \ ++ ] \ ++ ] ++ } ++ ++ run_ld_link_exec_tests [list \ ++ [list \ ++ "Run mbind2a" \ ++ "$NOPIE_LDFLAGS -Wl,-z,common-page-size=0x4000 -Wl,-z,noexecstack" \ ++ "" \ ++ { mbind2a.s mbind2b.c } \ ++ "mbind2a" \ ++ "pass.out" \ ++ "-O2 -I../bfd" \ ++ ] \ ++ [list \ ++ "Run mbind2b" \ ++ "-static -Wl,-z,common-page-size=0x4000 -Wl,-z,noexecstack" \ ++ "" \ ++ { mbind2a.s mbind2b.c } \ ++ "mbind2b" \ ++ "pass.out" \ ++ "-O2 -I../bfd" \ ++ ] \ ++ ] ++} ++ ++run_ld_link_exec_tests $array_tests_static $xfails ++ ++run_cc_link_tests [list \ ++ [list \ ++ "Build pr26391-1" \ ++ "-Wl,-z,unique-symbol" \ ++ "-fno-function-sections" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ {{nm "" pr26391.nd}} \ ++ "pr26391-1" \ ++ ] \ ++ [list \ ++ "Build pr26391-2" \ ++ "-Wl,-z,unique-symbol" \ ++ "-ffunction-sections" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ {{nm "" pr26391.nd}} \ ++ "pr26391-2" \ ++ ] \ ++ [list \ ++ "Build pr26391-3" \ ++ "-Wl,-z,unique-symbol,--emit-relocs" \ ++ "-fno-function-sections" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ {{nm "" pr26391.nd}} \ ++ "pr26391-3" \ ++ ] \ ++ [list \ ++ "Build pr26391-4" \ ++ "-Wl,-z,unique-symbol,--emit-relocs" \ ++ "-ffunction-sections" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ {{nm "" pr26391.nd}} \ ++ "pr26391-4" \ ++ ] \ ++ [list \ ++ "Build pr26391-5.o" \ ++ "-Wl,-z,unique-symbol -r -nostdlib -nostartfiles" \ ++ "-fno-function-sections" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ [list \ ++ [list "nm" "$dep_plug_opt" "pr26391.nd"] \ ++ [list "nm" "$dep_plug_opt" "pr26391.fd"] \ ++ ] \ ++ "pr26391-5.o" \ ++ ] \ ++ [list \ ++ "Build pr26391-6.o" \ ++ "-Wl,-z,unique-symbol -r -nostdlib -nostartfiles" \ ++ "-ffunction-sections" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ {{nm "" pr26391.nd}} \ ++ "pr26391-6.o" \ ++ ] \ ++] ++ ++run_ld_link_exec_tests [list \ ++ [list \ ++ "Run pr26391-1" \ ++ "-Wl,-z,unique-symbol" \ ++ "" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ "pr26391-1" \ ++ "pr26391.out" \ ++ "-fno-function-sections" \ ++ ] \ ++ [list \ ++ "Run pr26391-2" \ ++ "-Wl,-z,unique-symbol" \ ++ "" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ "pr26391-2" \ ++ "pr26391.out" \ ++ "-ffunction-sections" \ ++ ] \ ++ [list \ ++ "Run pr26391-3" \ ++ "-Wl,-z,unique-symbol,--emit-relocs" \ ++ "" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ "pr26391-3" \ ++ "pr26391.out" \ ++ "-fno-function-sections" \ ++ ] \ ++ [list \ ++ "Run pr26391-4" \ ++ "-Wl,-z,unique-symbol,--emit-relocs" \ ++ "" \ ++ {pr26391a.c pr26391b.c pr26391c.c pr26391d.c} \ ++ "pr26391-4" \ ++ "pr26391.out" \ ++ "-ffunction-sections" \ ++ ] \ ++ [list \ ++ "Run pr26391-5" \ ++ "-Wl,-z,unique-symbol" \ ++ "" \ ++ {dummy.c} \ ++ "pr26391-5" \ ++ "pr26391.out" \ ++ "" \ ++ "c" \ ++ "" \ ++ "tmpdir/pr26391-5.o" \ ++ ] \ ++ [list \ ++ "Run pr26391-6" \ ++ "-Wl,-z,unique-symbol" \ ++ "" \ ++ {dummy.c} \ ++ "pr26391-6" \ ++ "pr26391.out" \ ++ "" \ ++ "c" \ ++ "" \ ++ "tmpdir/pr26391-6.o" \ ++ ] \ ++] ++ ++set merge_exec_tests { ++ {"merge4" "" "" ++ {merge4a.c merge4b.s} "merge4" "merge4.out"} ++} ++run_ld_link_exec_tests $merge_exec_tests ++ ++catch "exec rm -f tmpdir/preinit tmpdir/init tmpdir/fini tmpdir/init-mixed" status +diff -rupN binutils.orig/ld/testsuite/ld-elf/header.d binutils-2.41/ld/testsuite/ld-elf/header.d +--- binutils.orig/ld/testsuite/ld-elf/header.d 2023-10-19 12:11:47.387940642 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/header.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,5 +1,5 @@ + # target: *-*-linux* *-*-gnu* *-*-vxworks arm*-*-uclinuxfdpiceabi +-# ld: -T header.t -z max-page-size=0x100 -z common-page-size=0x100 ++# ld: -T header.t -z max-page-size=0x100 -z common-page-size=0x100 --no-warn-rwx-segments + # objdump: -hpw + + #... +diff -rupN binutils.orig/ld/testsuite/ld-elf/loadaddr1.d binutils-2.41/ld/testsuite/ld-elf/loadaddr1.d +--- binutils.orig/ld/testsuite/ld-elf/loadaddr1.d 2023-10-19 12:11:47.388940643 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/loadaddr1.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,5 +1,5 @@ + #source: loadaddr.s +-#ld: -T loadaddr1.t -T loadaddr.t -z max-page-size=0x200000 -z noseparate-code ++#ld: -T loadaddr1.t -T loadaddr.t -z max-page-size=0x200000 -z noseparate-code --no-warn-rwx-segments + #readelf: -l --wide + #target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi + #xfail: h8300-*-* rx-*-linux* +diff -rupN binutils.orig/ld/testsuite/ld-elf/loadaddr2.d binutils-2.41/ld/testsuite/ld-elf/loadaddr2.d +--- binutils.orig/ld/testsuite/ld-elf/loadaddr2.d 2023-10-19 12:11:47.388940643 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/loadaddr2.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,5 +1,5 @@ + #source: loadaddr.s +-#ld: -T loadaddr2.t -T loadaddr.t -z max-page-size=0x200000 -z noseparate-code ++#ld: -T loadaddr2.t -T loadaddr.t -z max-page-size=0x200000 -z noseparate-code --no-warn-rwx-segments + #readelf: -l --wide + #target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi + #xfail: h8300-*-* rx-*-linux* +diff -rupN binutils.orig/ld/testsuite/ld-elf/maxpage4.d binutils-2.41/ld/testsuite/ld-elf/maxpage4.d +--- binutils.orig/ld/testsuite/ld-elf/maxpage4.d 2023-10-19 12:11:47.389940644 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/maxpage4.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,6 +1,6 @@ + #source: maxpage1.s + #as: --32 +-#ld: -z max-page-size=0x200000 -T maxpage4.t ++#ld: -z max-page-size=0x200000 -T maxpage4.t --no-warn-rwx-segments + #readelf: -l --wide + #target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +diff -rupN binutils.orig/ld/testsuite/ld-elf/nobits-1.d binutils-2.41/ld/testsuite/ld-elf/nobits-1.d +--- binutils.orig/ld/testsuite/ld-elf/nobits-1.d 2023-10-19 12:11:47.390940645 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/nobits-1.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,4 +1,4 @@ +-#ld: -Tnobits-1.t ++#ld: -Tnobits-1.t --no-warn-rwx-segments + #readelf: -l --wide + + #... +diff -rupN binutils.orig/ld/testsuite/ld-elf/note-1.d binutils-2.41/ld/testsuite/ld-elf/note-1.d +--- binutils.orig/ld/testsuite/ld-elf/note-1.d 2023-10-19 12:11:47.390940645 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/note-1.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,4 +1,4 @@ +-#ld: -Tnote-1.t ++#ld: -Tnote-1.t --no-warn-rwx-segments + #readelf: -l --wide + + #... +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan-10.d binutils-2.41/ld/testsuite/ld-elf/orphan-10.d +--- binutils.orig/ld/testsuite/ld-elf/orphan-10.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan-10.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,5 +1,5 @@ + #source: orphan-10.s +-#ld: -N -T orphan-9.ld ++#ld: -N -T orphan-9.ld --no-warn-rwx-segments + #objdump: -h + #xfail: [uses_genelf] + +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan-11.d binutils-2.41/ld/testsuite/ld-elf/orphan-11.d +--- binutils.orig/ld/testsuite/ld-elf/orphan-11.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan-11.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,5 +1,5 @@ + #source: orphan-11.s +-#ld: -T orphan-11.ld --orphan-handling=error ++#ld: -T orphan-11.ld --orphan-handling=error --no-warn-rwx-segments + #objdump: -wh + + #... +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan-12.d binutils-2.41/ld/testsuite/ld-elf/orphan-12.d +--- binutils.orig/ld/testsuite/ld-elf/orphan-12.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan-12.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,5 +1,5 @@ + #source: orphan-12.s +-#ld: -T orphan-11.ld --strip-debug --orphan-handling=error ++#ld: -T orphan-11.ld --strip-debug --orphan-handling=error --no-warn-rwx-segments + #objdump: -wh + + #... +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan-5.d binutils-2.41/ld/testsuite/ld-elf/orphan-5.d +--- binutils.orig/ld/testsuite/ld-elf/orphan-5.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan-5.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,4 +1,4 @@ + #name: Report warning for orphan sections +-#ld: --script orphan.ld --orphan-handling=warn ++#ld: --script orphan.ld --orphan-handling=warn --no-warn-rwx-segments + #source: orphan.s + #warning_output: orphan-5.l +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan-7.d binutils-2.41/ld/testsuite/ld-elf/orphan-7.d +--- binutils.orig/ld/testsuite/ld-elf/orphan-7.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan-7.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,4 +1,4 @@ + #name: Discard orphan sections +-#ld: --script orphan.ld --orphan-handling=discard ++#ld: --script orphan.ld --orphan-handling=discard --no-warn-rwx-segments + #source: orphan.s + #map: orphan-7.map +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan-8.d binutils-2.41/ld/testsuite/ld-elf/orphan-8.d +--- binutils.orig/ld/testsuite/ld-elf/orphan-8.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan-8.d 2023-10-19 12:11:56.517949627 +0100 +@@ -1,4 +1,4 @@ + #name: Place orphan sections +-#ld: --script orphan.ld --orphan-handling=place ++#ld: --script orphan.ld --orphan-handling=place --no-warn-rwx-segments + #source: orphan.s + #map: orphan-8.map +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan-9.d binutils-2.41/ld/testsuite/ld-elf/orphan-9.d +--- binutils.orig/ld/testsuite/ld-elf/orphan-9.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan-9.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #source: orphan-9.s +-#ld: -N -T orphan-9.ld ++#ld: -N -T orphan-9.ld --no-warn-rwx-segments + #objdump: -h + #xfail: [uses_genelf] + +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan-region.d binutils-2.41/ld/testsuite/ld-elf/orphan-region.d +--- binutils.orig/ld/testsuite/ld-elf/orphan-region.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan-region.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #source: orphan-region.s +-#ld: -T orphan-region.ld -N -z stack-size=0 ++#ld: -T orphan-region.ld -N -z stack-size=0 --no-warn-rwx-segments + #readelf: -S -l --wide + #xfail: [uses_genelf] hppa*64*-*-* spu-*-* *-*-nacl* + # if not using elf.em, you don't get fancy orphan handling +diff -rupN binutils.orig/ld/testsuite/ld-elf/orphan.d binutils-2.41/ld/testsuite/ld-elf/orphan.d +--- binutils.orig/ld/testsuite/ld-elf/orphan.d 2023-10-19 12:11:47.391940646 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/orphan.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #source: orphan.s +-#ld: -T orphan.ld ++#ld: -T orphan.ld --no-warn-rwx-segments + #readelf: -S --wide + #xfail: [uses_genelf] + # if not using elf.em, you don't get fancy orphan handling +diff -rupN binutils.orig/ld/testsuite/ld-elf/pr19539.d binutils-2.41/ld/testsuite/ld-elf/pr19539.d +--- binutils.orig/ld/testsuite/ld-elf/pr19539.d 2023-10-19 12:11:47.394940649 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/pr19539.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,6 +1,6 @@ + #source: start.s + #source: pr19539.s +-#ld: -pie -T pr19539.t --warn-textrel ++#ld: -pie -T pr19539.t --warn-textrel --no-warn-rwx-segments + #readelf : --dyn-syms --wide + #warning: .*: creating DT_TEXTREL in a PIE + #target: *-*-linux* *-*-gnu* *-*-solaris* arm*-*-uclinuxfdpiceabi +diff -rupN binutils.orig/ld/testsuite/ld-elf/pr26256-1a.d binutils-2.41/ld/testsuite/ld-elf/pr26256-1a.d +--- binutils.orig/ld/testsuite/ld-elf/pr26256-1a.d 2023-10-19 12:11:47.401940656 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/pr26256-1a.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #source: pr26256-1.s +-#ld: -e _start -T pr26256-1.t ++#ld: -e _start -T pr26256-1.t --no-warn-rwx-segments + #nm: -n + + #... +diff -rupN binutils.orig/ld/testsuite/ld-elf/pr26907.d binutils-2.41/ld/testsuite/ld-elf/pr26907.d +--- binutils.orig/ld/testsuite/ld-elf/pr26907.d 2023-10-19 12:11:47.402940657 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/pr26907.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,4 +1,4 @@ +-#ld: -T pr26907.ld ++#ld: -T pr26907.ld --no-warn-rwx-segments + #readelf: -lW + #xfail: dlx-*-* ft32-*-* h8300-*-* ip2k-*-* m32r*-*-elf* m32r*-*-rtems* + #xfail: moxie-*-* msp430-*-* mt-*-* pru*-*-* visium-*-* +diff -rupN binutils.orig/ld/testsuite/ld-elf/pr28597.d binutils-2.41/ld/testsuite/ld-elf/pr28597.d +--- binutils.orig/ld/testsuite/ld-elf/pr28597.d 2023-10-19 12:11:47.403940658 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/pr28597.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,3 +1,3 @@ +-#ld: -shared -T pr28597.t ++#ld: -shared -T pr28597.t --no-warn-rwx-segments + #error: .*: discarded output section: `.plt' + #target: i?86-*-* x86_64-*-* +diff -rupN binutils.orig/ld/testsuite/ld-elf/retain2.d binutils-2.41/ld/testsuite/ld-elf/retain2.d +--- binutils.orig/ld/testsuite/ld-elf/retain2.d 2023-10-19 12:11:47.405940660 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/retain2.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #name: SHF_GNU_RETAIN 2 (remove SHF_GNU_RETAIN sections by placing in /DISCARD/) + #source: retain1.s +-#ld: -e _start -Map=retain2.map --gc-sections --script=retain2.ld ++#ld: -e _start -Map=retain2.map --gc-sections --script=retain2.ld --no-warn-rwx-segments + #map: retain2.map + #notarget: ![supports_gnu_osabi] ![check_gc_sections_available] +diff -rupN binutils.orig/ld/testsuite/ld-elf/shared.exp binutils-2.41/ld/testsuite/ld-elf/shared.exp +--- binutils.orig/ld/testsuite/ld-elf/shared.exp 2023-10-19 12:11:47.408940663 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/shared.exp 2023-10-19 12:11:56.518949628 +0100 +@@ -259,13 +259,13 @@ if { [check_gc_sections_available] } { + "pr20828-v.so"] \ + [list \ + "PR ld/20828 forcibly exported symbol version without section GC" \ +- "$LFLAGS --no-dynamic-linker -e foo -E -T pr20828-v.ld" "" "" \ ++ "$LFLAGS --no-dynamic-linker -e foo -E -T pr20828-v.ld --no-error-rwx-segments" "" "" \ + {pr20828-v.s} \ + {{objdump -p pr20828-v.od}} \ + "pr20828-v-1"] \ + [list \ + "PR ld/20828 forcibly exported symbol version with section GC" \ +- "$LFLAGS --no-dynamic-linker -e foo --gc-sections -E -T pr20828-v.ld" "" "" \ ++ "$LFLAGS --no-dynamic-linker -e foo --gc-sections -E -T pr20828-v.ld --no-error-rwx-segments" "" "" \ + {pr20828-v.s} \ + {{objdump -p pr20828-v.od}} \ + "pr20828-v-2"]] +@@ -282,7 +282,7 @@ if { [check_gc_sections_available] } { + [list \ + "PR ld/21233 dynamic symbols with section GC\ + (auxiliary shared library)" \ +- "$LFLAGS -shared -T pr21233.ld" "" "$AFLAGS_PIC" \ ++ "$LFLAGS -shared -T pr21233.ld --no-error-rwx-segments" "" "$AFLAGS_PIC" \ + {pr21233-l.s} \ + {{readelf --dyn-syms pr21233-l.sd}} \ + "libpr21233.so"]] +@@ -290,7 +290,7 @@ if { [check_gc_sections_available] } { + run_ld_link_tests [list \ + [list \ + "PR ld/21233 dynamic symbols with section GC (--undefined)" \ +- "$LFLAGS --gc-sections -e foo --undefined=bar -T pr21233.ld" \ ++ "$LFLAGS --gc-sections -e foo --undefined=bar -T pr21233.ld --no-error-rwx-segments" \ + "tmpdir/libpr21233.so" "" \ + {pr21233.s} \ + {{readelf --dyn-syms pr21233.sd}} \ +@@ -300,7 +300,7 @@ if { [check_gc_sections_available] } { + [list \ + "PR ld/21233 dynamic symbols with section GC (--require-defined)" \ + "$LFLAGS --gc-sections -e foo --require-defined=bar\ +- -T pr21233.ld" \ ++ -T pr21233.ld --no-error-rwx-segments" \ + "tmpdir/libpr21233.so" "" \ + {pr21233.s} \ + {{readelf --dyn-syms pr21233.sd}} \ +@@ -309,7 +309,7 @@ if { [check_gc_sections_available] } { + run_ld_link_tests [list \ + [list \ + "PR ld/21233 dynamic symbols with section GC (EXTERN)" \ +- "$LFLAGS --gc-sections -e foo -T pr21233-e.ld" \ ++ "$LFLAGS --gc-sections -e foo -T pr21233-e.ld --no-error-rwx-segments" \ + "tmpdir/libpr21233.so" "" \ + {pr21233.s} \ + {{readelf --dyn-syms pr21233.sd}} \ +diff -rupN binutils.orig/ld/testsuite/ld-elf/size-1.d binutils-2.41/ld/testsuite/ld-elf/size-1.d +--- binutils.orig/ld/testsuite/ld-elf/size-1.d 2023-10-19 12:11:47.406940661 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/size-1.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #source: size-1.s +-#ld: -T size-1.t ++#ld: -T size-1.t --no-warn-rwx-segments + #objdump: -s + # v850 .tdata/.tbss are not TLS sections + #xfail: v850*-*-* +diff -rupN binutils.orig/ld/testsuite/ld-elf/textaddr7.d binutils-2.41/ld/testsuite/ld-elf/textaddr7.d +--- binutils.orig/ld/testsuite/ld-elf/textaddr7.d 2023-10-19 12:11:47.407940662 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/textaddr7.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #source: maxpage1.s +-#ld: -n -z max-page-size=0x200000 -Ttext-segment 0x10000 ++#ld: -n -z max-page-size=0x200000 -Ttext-segment 0x10000 --no-warn-rwx-segments + #readelf: -l --wide + #target: *-*-linux-gnu *-*-gnu* arm*-*-uclinuxfdpiceabi + +diff -rupN binutils.orig/ld/testsuite/ld-elf/warn1.d binutils-2.41/ld/testsuite/ld-elf/warn1.d +--- binutils.orig/ld/testsuite/ld-elf/warn1.d 2023-10-19 12:11:47.408940663 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/warn1.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,7 +1,7 @@ + #source: start.s + #source: symbol1ref.s + #source: symbol1w.s +-#ld: -T group.ld ++#ld: -T group.ld --no-warn-rwx-segments + #warning: ^[^\n]*\): warning: witty one-liner$ + #readelf: -s + #xfail: [is_generic] +diff -rupN binutils.orig/ld/testsuite/ld-elf/warn2.d binutils-2.41/ld/testsuite/ld-elf/warn2.d +--- binutils.orig/ld/testsuite/ld-elf/warn2.d 2023-10-19 12:11:47.408940663 +0100 ++++ binutils-2.41/ld/testsuite/ld-elf/warn2.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,7 +1,7 @@ + #source: start.s + #source: symbol2ref.s + #source: symbol2w.s +-#ld: -T group.ld ++#ld: -T group.ld --no-warn-rwx-segments + #warning: ^[^\n]*\.[obj]+: warning: function 'Foo' used$ + #readelf: -s + # if not using elf.em, you don't get fancy section handling +diff -rupN binutils.orig/ld/testsuite/ld-i386/discarded1.d binutils-2.41/ld/testsuite/ld-i386/discarded1.d +--- binutils.orig/ld/testsuite/ld-i386/discarded1.d 2023-10-19 12:11:47.420940674 +0100 ++++ binutils-2.41/ld/testsuite/ld-i386/discarded1.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,3 +1,3 @@ + #as: --32 +-#ld: -melf_i386 -T discarded1.t ++#ld: -melf_i386 -T discarded1.t --no-error-rwx-segments + #error: .*discarded output section: `.got.plt' +diff -rupN binutils.orig/ld/testsuite/ld-i386/pr19175.d binutils-2.41/ld/testsuite/ld-i386/pr19175.d +--- binutils.orig/ld/testsuite/ld-i386/pr19175.d 2023-10-19 12:11:47.427940681 +0100 ++++ binutils-2.41/ld/testsuite/ld-i386/pr19175.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,6 +1,6 @@ + #source: pr19175.s + #as: --32 -mrelax-relocations=yes +-#ld: -Bsymbolic -shared -melf_i386 -T pr19175.t ++#ld: -Bsymbolic -shared -melf_i386 -T pr19175.t --no-error-rwx-segments + #objdump: -dw + + .*: +file format .* +diff -rupN binutils.orig/ld/testsuite/ld-i386/pr19539.d binutils-2.41/ld/testsuite/ld-i386/pr19539.d +--- binutils.orig/ld/testsuite/ld-i386/pr19539.d 2023-10-19 12:11:47.427940681 +0100 ++++ binutils-2.41/ld/testsuite/ld-i386/pr19539.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #as: --32 +-#ld: -pie -m elf_i386 -T pr19539.t -z notext ++#ld: -pie -m elf_i386 -T pr19539.t -z notext --no-error-rwx-segments + #readelf: -r --wide + + Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 1 entry: +diff -rupN binutils.orig/ld/testsuite/ld-i386/pr23189.d binutils-2.41/ld/testsuite/ld-i386/pr23189.d +--- binutils.orig/ld/testsuite/ld-i386/pr23189.d 2023-10-19 12:11:47.430940684 +0100 ++++ binutils-2.41/ld/testsuite/ld-i386/pr23189.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #as: --32 -mrelax-relocations=yes +-#ld: -shared -melf_i386 -T pr23189.t ++#ld: -shared -melf_i386 -T pr23189.t --no-error-rwx-segments + #readelf: -r --wide + + There are no relocations in this file. +diff -rupN binutils.orig/ld/testsuite/ld-plugin/lto-3r.d binutils-2.41/ld/testsuite/ld-plugin/lto-3r.d +--- binutils.orig/ld/testsuite/ld-plugin/lto-3r.d 2023-10-19 12:11:47.511940764 +0100 ++++ binutils-2.41/ld/testsuite/ld-plugin/lto-3r.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,4 +1,4 @@ +-#ld: -r tmpdir/lto-3b.o ++#ld: -r tmpdir/lto-3b.o --no-error-execstack + #source: dummy.s + #nm: -p + +diff -rupN binutils.orig/ld/testsuite/ld-plugin/lto-5r.d binutils-2.41/ld/testsuite/ld-plugin/lto-5r.d +--- binutils.orig/ld/testsuite/ld-plugin/lto-5r.d 2023-10-19 12:11:47.511940764 +0100 ++++ binutils-2.41/ld/testsuite/ld-plugin/lto-5r.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,4 +1,4 @@ +-#ld: -r tmpdir/lto-5a.o tmpdir/lto-5b.o ++#ld: -r tmpdir/lto-5a.o tmpdir/lto-5b.o --no-error-execstack + #source: dummy.s + #nm: -p + +diff -rupN binutils.orig/ld/testsuite/ld-plugin/lto.exp binutils-2.41/ld/testsuite/ld-plugin/lto.exp +--- binutils.orig/ld/testsuite/ld-plugin/lto.exp 2023-10-19 12:11:47.517940770 +0100 ++++ binutils-2.41/ld/testsuite/ld-plugin/lto.exp 2023-10-19 12:11:56.518949628 +0100 +@@ -127,7 +127,7 @@ set lto_link_tests [list \ + "" "-flto -O2 $lto_fat $NOSANITIZE_CFLAGS" \ + {pr12758b.c} {} "libpr12758.a"] \ + [list "PR ld/12758" \ +- "$NOPIE_LDFLAGS $NOSANITIZE_CFLAGS -O2 -Wl,-e,foo -nostdlib -flto -fuse-linker-plugin tmpdir/pr12758a.o -Wl,--start-group tmpdir/libpr12758.a -Wl,--end-group" \ ++ "$NOPIE_LDFLAGS $NOSANITIZE_CFLAGS -O2 -Wl,-e,foo -nostdlib -flto -fuse-linker-plugin tmpdir/pr12758a.o -Wl,--start-group tmpdir/libpr12758.a -Wl,--end-group -Wl,--no-error-execstack" \ + "$NOSANITIZE_CFLAGS" \ + {dummy.c} {} "pr12758.exe"] \ + [list "Build libpr13183.a" \ +@@ -919,7 +919,7 @@ run_cc_link_tests $lto_link_symbol_tests + + run_ld_link_tests [list \ + [list "PR ld/19317 (2)" \ +- "-r tmpdir/pr19317.o" "" "" \ ++ "-r tmpdir/pr19317.o --no-error-execstack" "" "" \ + {dummy.s} {} "pr19317-r.o"] \ + ] + +diff -rupN binutils.orig/ld/testsuite/ld-powerpc/ppc476-shared.d binutils-2.41/ld/testsuite/ld-powerpc/ppc476-shared.d +--- binutils.orig/ld/testsuite/ld-powerpc/ppc476-shared.d 2023-10-19 12:11:47.525940778 +0100 ++++ binutils-2.41/ld/testsuite/ld-powerpc/ppc476-shared.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,6 +1,6 @@ + #source: ppc476-shared.s + #as: -a32 +-#ld: -melf32ppc -q -shared -z common-page-size=0x10000 -z notext --ppc476-workaround -T ppc476-shared.lnk ++#ld: -melf32ppc -q -shared -z common-page-size=0x10000 -z notext --ppc476-workaround -T ppc476-shared.lnk --no-error-rwx-segments + #objdump: -dr + #target: powerpc*-*-* + +diff -rupN binutils.orig/ld/testsuite/ld-powerpc/ppc476-shared2.d binutils-2.41/ld/testsuite/ld-powerpc/ppc476-shared2.d +--- binutils.orig/ld/testsuite/ld-powerpc/ppc476-shared2.d 2023-10-19 12:11:47.525940778 +0100 ++++ binutils-2.41/ld/testsuite/ld-powerpc/ppc476-shared2.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,6 +1,6 @@ + #source: ppc476-shared.s + #as: -a32 +-#ld: -melf32ppc -shared -z common-page-size=0x10000 -z notext --ppc476-workaround -T ppc476-shared.lnk ++#ld: -melf32ppc -shared -z common-page-size=0x10000 -z notext --ppc476-workaround -T ppc476-shared.lnk --no-error-rwx-segments + #objdump: -R + #target: powerpc*-*-* + +diff -rupN binutils.orig/ld/testsuite/ld-powerpc/pr28827-2.d binutils-2.41/ld/testsuite/ld-powerpc/pr28827-2.d +--- binutils.orig/ld/testsuite/ld-powerpc/pr28827-2.d 2023-10-19 12:11:47.525940778 +0100 ++++ binutils-2.41/ld/testsuite/ld-powerpc/pr28827-2.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,5 +1,5 @@ + #as: -a64 +-#ld: -melf64ppc --plt-align=0 -T pr28827-2.lnk ++#ld: -melf64ppc --plt-align=0 -T pr28827-2.lnk --no-error-rwx-segments + #objdump: -dr + + .*: file format .* +diff -rupN binutils.orig/ld/testsuite/ld-s390/s390.exp binutils-2.41/ld/testsuite/ld-s390/s390.exp +--- binutils.orig/ld/testsuite/ld-s390/s390.exp 2023-10-19 12:11:47.541940793 +0100 ++++ binutils-2.41/ld/testsuite/ld-s390/s390.exp 2023-10-19 12:11:56.518949628 +0100 +@@ -83,7 +83,7 @@ set s390xtests { + {{objdump -dzrj.text gotreloc_64-relro-1.dd}} + "gotreloc_64-1"} + {"PLT: offset test" +- "-shared -m elf64_s390 -dT pltoffset-1.ld" "" ++ "-shared -m elf64_s390 -dT pltoffset-1.ld --no-error-rwx-segments" "" + "-m64" {pltoffset-1.s} + {{objdump "-dzrj.text --stop-address=16" pltoffset-1.dd}} + "pltoffset-1"} +diff -rupN binutils.orig/ld/testsuite/ld-s390/s390.exp.orig binutils-2.41/ld/testsuite/ld-s390/s390.exp.orig +--- binutils.orig/ld/testsuite/ld-s390/s390.exp.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-s390/s390.exp.orig 2023-10-19 12:11:39.486932861 +0100 +@@ -0,0 +1,106 @@ ++# Expect script for ld-s390 tests ++# Copyright (C) 2003-2023 Free Software Foundation, Inc. ++# ++# This file is part of the GNU Binutils. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++# MA 02110-1301, USA. ++# ++ ++# Test s390 linking; all types of relocs. This tests the assembler and ++# tools like objdump as well as the linker. ++ ++if { !([istarget "s390-*-*"] || [istarget "s390x-*-*"]) } { ++ return ++} ++ ++# List contains test-items with 3 items followed by 2 lists: ++# 0:name 1:ld early options 2:ld late options 3:assembler options ++# 4:filenames of assembler files 5: action and options. 6: name of output file ++ ++# Actions: ++# objdump: Apply objdump options on result. Compare with regex (last arg). ++# nm: Apply nm options on result. Compare with regex (last arg). ++# readelf: Apply readelf options on result. Compare with regex (last arg). ++ ++return ++ ++set s390tests { ++ {"TLS -fpic -shared transitions" "-shared -melf_s390 --hash-style=sysv" "" ++ "-m31" {tlspic1.s tlspic2.s} ++ {{readelf -Ssrl tlspic.rd} {objdump -dzrj.text tlspic.dd} ++ {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}} ++ "libtlspic.so"} ++ {"Helper shared library" "-shared -melf_s390" "" ++ "-m31" {tlslib.s} {} "libtlslib.so"} ++ {"TLS -fpic and -fno-pic exec transitions" ++ "-melf_s390 tmpdir/libtlslib.so --hash-style=sysv" "" ++ "-m31" {tlsbinpic.s tlsbin.s} ++ {{readelf -Ssrl tlsbin.rd} {objdump -dzrj.text tlsbin.dd} ++ {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}} ++ "tlsbin"} ++ {"GOT: symbol address load from got to larl" ++ "-shared -melf_s390 --hash-style=sysv --version-script=gotreloc-1.ver" "" ++ "-m31" {gotreloc-1.s} ++ {{objdump -dzrj.text gotreloc_31-1.dd}} ++ "gotreloc_31-1"} ++} ++ ++set s390xtests { ++ {"TLS -fpic -shared transitions" "-shared -melf64_s390 --hash-style=sysv" "" ++ "-m64 -Aesame" {tlspic1_64.s tlspic2_64.s} ++ {{readelf -WSsrl tlspic_64.rd} {objdump -dzrj.text tlspic_64.dd} ++ {objdump -sj.got tlspic_64.sd} {objdump -sj.tdata tlspic_64.td}} ++ "libtlspic_64.so"} ++ {"Helper shared library" "-shared -melf64_s390" "" ++ "-m64 -Aesame" {tlslib_64.s} {} "libtlslib_64.so"} ++ {"TLS -fpic and -fno-pic exec transitions" ++ "-melf64_s390 tmpdir/libtlslib_64.so --hash-style=sysv" "" ++ "-m64 -Aesame" {tlsbinpic_64.s tlsbin_64.s} ++ {{readelf -WSsrl tlsbin_64.rd} {objdump -dzrj.text tlsbin_64.dd} ++ {objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}} ++ "tlsbin_64"} ++ {"GOT: norelro symbol address load from got to larl" ++ "-shared -melf64_s390 -z norelro --hash-style=sysv --version-script=gotreloc-1.ver" "" ++ "-m64" {gotreloc-1.s} ++ {{objdump -dzrj.text gotreloc_64-norelro-1.dd}} ++ "gotreloc_64-1"} ++ {"GOT: relro symbol address load from got to larl" ++ "-shared -melf64_s390 -z relro --hash-style=sysv --version-script=gotreloc-1.ver" "" ++ "-m64" {gotreloc-1.s} ++ {{objdump -dzrj.text gotreloc_64-relro-1.dd}} ++ "gotreloc_64-1"} ++ {"PLT: offset test" ++ "-shared -m elf64_s390 -dT pltoffset-1.ld" "" ++ "-m64" {pltoffset-1.s} ++ {{objdump "-dzrj.text --stop-address=16" pltoffset-1.dd}} ++ "pltoffset-1"} ++} ++ ++if [istarget "s390-*-*"] { ++ run_ld_link_tests $s390tests ++} ++ ++if [istarget "s390x-*-*"] { ++ run_ld_link_tests $s390tests ++ run_ld_link_tests $s390xtests ++} ++ ++set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] ++foreach t $test_list { ++ # We need to strip the ".d", but can leave the dirname. ++ verbose [file rootname $t] ++ run_dump_test [file rootname $t] ++} +diff -rupN binutils.orig/ld/testsuite/ld-scripts/align2a.d binutils-2.41/ld/testsuite/ld-scripts/align2a.d +--- binutils.orig/ld/testsuite/ld-scripts/align2a.d 2023-10-19 12:11:47.542940794 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/align2a.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,4 +1,4 @@ +-# ld: --defsym data_align=16 -T align2.t ++# ld: --defsym data_align=16 -T align2.t --no-error-rwx-segments + # objdump: --section-headers + + [^:]+: +file format.* +diff -rupN binutils.orig/ld/testsuite/ld-scripts/align2b.d binutils-2.41/ld/testsuite/ld-scripts/align2b.d +--- binutils.orig/ld/testsuite/ld-scripts/align2b.d 2023-10-19 12:11:47.542940794 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/align2b.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,4 +1,4 @@ +-# ld: --defsym data_align=32 -T align2.t ++# ld: --defsym data_align=32 -T align2.t --no-error-rwx-segments + # objdump: --section-headers + + [^:]+: +file +format.* +diff -rupN binutils.orig/ld/testsuite/ld-scripts/align5.d binutils-2.41/ld/testsuite/ld-scripts/align5.d +--- binutils.orig/ld/testsuite/ld-scripts/align5.d 2023-10-19 12:11:47.542940794 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/align5.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,7 +1,7 @@ + # source: align2a.s +-# ld: -T align5.t ++# ld: -T align5.t --no-error-rwx-segments + # nm: -n + + #... + .*foo +-#... +\ No newline at end of file ++#... +diff -rupN binutils.orig/ld/testsuite/ld-scripts/alignof.exp binutils-2.41/ld/testsuite/ld-scripts/alignof.exp +--- binutils.orig/ld/testsuite/ld-scripts/alignof.exp 2023-10-19 12:11:47.542940794 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/alignof.exp 2023-10-19 12:11:56.518949628 +0100 +@@ -39,7 +39,7 @@ if { [is_pecoff_format] } { + } + + if ![ld_link $ld tmpdir/alignof "-T $srcdir/$subdir/alignof.t \ +- $IMAGE_BASE tmpdir/alignof.o"] { ++ $IMAGE_BASE tmpdir/alignof.o --no-error-rwx-segments"] { + fail $testname + return + } +diff -rupN binutils.orig/ld/testsuite/ld-scripts/crossref.exp binutils-2.41/ld/testsuite/ld-scripts/crossref.exp +--- binutils.orig/ld/testsuite/ld-scripts/crossref.exp 2023-10-19 12:11:47.551940803 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/crossref.exp 2023-10-19 12:11:56.518949628 +0100 +@@ -80,7 +80,7 @@ if [is_pecoff_format] { + append flags " --image-base 0" + } + +-set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o"] ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o --no-error-rwx-segments"] + + set exec_output [prune_warnings $exec_output] + +@@ -105,7 +105,7 @@ if { ![ld_compile "$CC_FOR_TARGET $NOSAN + return + } + +-set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o"] ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o --no-error-rwx-segments"] + set exec_output [prune_warnings $exec_output] + + regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output +@@ -139,7 +139,7 @@ if ![ld_relocate $ld tmpdir/cross3-parti + return + } + +-set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross3 -T $srcdir/$subdir/cross3.t tmpdir/cross3-partial.o tmpdir/cross2.o"] ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross3 -T $srcdir/$subdir/cross3.t tmpdir/cross3-partial.o tmpdir/cross2.o --no-error-rwx-segments"] + + set exec_output [prune_warnings $exec_output] + +@@ -152,7 +152,7 @@ if [string match "" $exec_output] then { + fail $test3 + } + +-set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross4 -T $srcdir/$subdir/cross4.t tmpdir/cross4.o"] ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross4 -T $srcdir/$subdir/cross4.t tmpdir/cross4.o --no-error-rwx-segments"] + set exec_output [prune_warnings $exec_output] + + regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output +@@ -164,7 +164,7 @@ if [string match "" $exec_output] then { + fail $test4 + } + +-set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross5 -T $srcdir/$subdir/cross5.t tmpdir/cross4.o"] ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross5 -T $srcdir/$subdir/cross5.t tmpdir/cross4.o --no-error-rwx-segments"] + set exec_output [prune_warnings $exec_output] + + regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output +@@ -180,7 +180,7 @@ if [string match "" $exec_output] then { + } + } + +-set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross6 -T $srcdir/$subdir/cross6.t tmpdir/cross3.o"] ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross6 -T $srcdir/$subdir/cross6.t tmpdir/cross3.o --no-error-rwx-segments"] + set exec_output [prune_warnings $exec_output] + + regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output +@@ -192,7 +192,7 @@ if [string match "" $exec_output] then { + fail $test6 + } + +-set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross7 -T $srcdir/$subdir/cross7.t tmpdir/cross3.o"] ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross7 -T $srcdir/$subdir/cross7.t tmpdir/cross3.o --no-error-rwx-segments"] + set exec_output [prune_warnings $exec_output] + + regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output +diff -rupN binutils.orig/ld/testsuite/ld-scripts/crossref.exp.orig binutils-2.41/ld/testsuite/ld-scripts/crossref.exp.orig +--- binutils.orig/ld/testsuite/ld-scripts/crossref.exp.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/crossref.exp.orig 2023-10-19 12:11:39.486932861 +0100 +@@ -0,0 +1,211 @@ ++# Test NOCROSSREFS in a linker script. ++# By Ian Lance Taylor, Cygnus Support. ++# Copyright (C) 2000-2023 Free Software Foundation, Inc. ++# ++# This file is part of the GNU Binutils. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++# MA 02110-1301, USA. ++ ++set test1 "NOCROSSREFS 1" ++set test2 "NOCROSSREFS 2" ++set test3 "NOCROSSREFS 3" ++set test4 "NOCROSSREFS_TO 1" ++set test5 "NOCROSSREFS_TO 2" ++set test6 "NOCROSSREFS_TO 3" ++set test7 "NOCROSSREFS_TO 4" ++ ++if { ![check_compiler_available] } { ++ untested $test1 ++ untested $test2 ++ untested $test3 ++ untested $test4 ++ untested $test5 ++ untested $test6 ++ untested $test7 ++ return ++} ++ ++# Pass -fplt to CC since -fno-plt doesn't work with NOCROSSREFS tests. ++# Also add $NOPIE_CFLAGS since PIE doesn't work NOCROSSREFS tests. ++set old_CFLAGS "$CFLAGS_FOR_TARGET" ++append CFLAGS_FOR_TARGET " $PLT_CFLAGS $NOPIE_CFLAGS" ++ ++# Xtensa targets currently default to putting literal values in a separate ++# section and that requires linker script support, so put literals in text. ++if [istarget xtensa*-*-*] { ++ append CFLAGS_FOR_TARGET " -mtext-section-literals" ++} ++ ++# Prevent the use of the MeP's small data area which references a symbol ++# called __sdabase which will not be defined by our test linker scripts. ++if [istarget mep*-*-elf] { ++ append CFLAGS_FOR_TARGET " -mtiny=0" ++} ++ ++# The .dsbt section and __c6xabi_DSBT_BASE are not defined in our test ++# linker scripts. ++if [istarget tic6x*-*-*] { ++ append CFLAGS_FOR_TARGET " -mno-dsbt -msdata=none" ++} ++ ++if { ![ld_compile "$CC_FOR_TARGET $NOSANITIZE_CFLAGS $NOLTO_CFLAGS" "$srcdir/$subdir/cross1.c" tmpdir/cross1.o] \ ++ || ![ld_compile "$CC_FOR_TARGET $NOSANITIZE_CFLAGS $NOLTO_CFLAGS" "$srcdir/$subdir/cross2.c" tmpdir/cross2.o] } { ++ unsupported $test1 ++ unsupported $test2 ++ set CFLAGS_FOR_TARGET "$old_CFLAGS" ++ return ++} ++ ++set flags [big_or_little_endian] ++ ++# arc-elf32 requires the symbol __SDATA_BEGIN__ to always be present. ++if [istarget arc*-*-elf32] { ++ append flags " --defsym __SDATA_BEGIN__=0" ++} ++ ++if [is_pecoff_format] { ++ append flags " --image-base 0" ++} ++ ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o"] ++ ++set exec_output [prune_warnings $exec_output] ++ ++regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output ++ ++if [string match "" $exec_output] then { ++ fail $test1 ++} else { ++ verbose -log "$exec_output" ++ if [regexp "prohibited cross reference from .* to `.*foo' in" $exec_output] { ++ pass $test1 ++ } else { ++ fail $test1 ++ } ++} ++ ++# Check cross references within a single object. ++ ++if { ![ld_compile "$CC_FOR_TARGET $NOSANITIZE_CFLAGS $NOLTO_CFLAGS" "$srcdir/$subdir/cross3.c" tmpdir/cross3.o] } { ++ unsupported $test2 ++ set CFLAGS_FOR_TARGET "$old_CFLAGS" ++ return ++} ++ ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o"] ++set exec_output [prune_warnings $exec_output] ++ ++regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output ++ ++if [string match "" $exec_output] then { ++ fail $test2 ++} else { ++ verbose -log "$exec_output" ++ if [regexp "prohibited cross reference from .* to `.*' in" $exec_output] { ++ pass $test2 ++ } else { ++ fail $test2 ++ } ++} ++ ++if { [istarget "i686-*-*"] } { ++ return ++} ++ ++# Check cross references for ld -r ++ ++if { ![ld_compile "$CC_FOR_TARGET $NOSANITIZE_CFLAGS $NOLTO_CFLAGS" "$srcdir/$subdir/cross4.c" tmpdir/cross4.o] } { ++ unsupported $test3 ++ set CFLAGS_FOR_TARGET "$old_CFLAGS" ++ return ++} ++ ++if ![ld_relocate $ld tmpdir/cross3-partial.o "tmpdir/cross1.o tmpdir/cross4.o"] { ++ fail $test3 ++ set CFLAGS_FOR_TARGET "$old_CFLAGS" ++ return ++} ++ ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross3 -T $srcdir/$subdir/cross3.t tmpdir/cross3-partial.o tmpdir/cross2.o"] ++ ++set exec_output [prune_warnings $exec_output] ++ ++regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output ++ ++if [string match "" $exec_output] then { ++ pass $test3 ++} else { ++ verbose -log "$exec_output" ++ fail $test3 ++} ++ ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross4 -T $srcdir/$subdir/cross4.t tmpdir/cross4.o"] ++set exec_output [prune_warnings $exec_output] ++ ++regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output ++ ++if [string match "" $exec_output] then { ++ pass $test4 ++} else { ++ verbose -log "$exec_output" ++ fail $test4 ++} ++ ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross5 -T $srcdir/$subdir/cross5.t tmpdir/cross4.o"] ++set exec_output [prune_warnings $exec_output] ++ ++regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output ++ ++if [string match "" $exec_output] then { ++ fail $test5 ++} else { ++ verbose -log "$exec_output" ++ if [regexp "prohibited cross reference from .* to `.*' in" $exec_output] { ++ pass $test5 ++ } else { ++ fail $test5 ++ } ++} ++ ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross6 -T $srcdir/$subdir/cross6.t tmpdir/cross3.o"] ++set exec_output [prune_warnings $exec_output] ++ ++regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output ++ ++if [string match "" $exec_output] then { ++ pass $test6 ++} else { ++ verbose -log "$exec_output" ++ fail $test6 ++} ++ ++set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross7 -T $srcdir/$subdir/cross7.t tmpdir/cross3.o"] ++set exec_output [prune_warnings $exec_output] ++ ++regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output ++ ++if [string match "" $exec_output] then { ++ fail $test7 ++} else { ++ verbose -log "$exec_output" ++ if [regexp "prohibited cross reference from .* to `.*' in" $exec_output] { ++ pass $test7 ++ } else { ++ fail $test7 ++ } ++} ++ ++set CFLAGS_FOR_TARGET "$old_CFLAGS" +diff -rupN binutils.orig/ld/testsuite/ld-scripts/defined2.d binutils-2.41/ld/testsuite/ld-scripts/defined2.d +--- binutils.orig/ld/testsuite/ld-scripts/defined2.d 2023-10-19 12:11:47.543940795 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/defined2.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,4 +1,4 @@ +-#ld: -Tdefined2.t ++#ld: -Tdefined2.t --no-error-rwx-segments + #nm: -B + #source: phdrs.s + +diff -rupN binutils.orig/ld/testsuite/ld-scripts/defined3.d binutils-2.41/ld/testsuite/ld-scripts/defined3.d +--- binutils.orig/ld/testsuite/ld-scripts/defined3.d 2023-10-19 12:11:47.543940795 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/defined3.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,4 +1,4 @@ +-#ld: -Tdefined3.t ++#ld: -Tdefined3.t --no-error-rwx-segments + #nm: -B + #source: phdrs.s + #source: defined.s +diff -rupN binutils.orig/ld/testsuite/ld-scripts/defined5.d binutils-2.41/ld/testsuite/ld-scripts/defined5.d +--- binutils.orig/ld/testsuite/ld-scripts/defined5.d 2023-10-19 12:11:47.543940795 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/defined5.d 2023-10-19 12:11:56.518949628 +0100 +@@ -1,4 +1,4 @@ +-#ld: -Tdefined5.t ++#ld: -Tdefined5.t --no-error-rwx-segments + #warning: .*multiple definition of `defined'.* + #nm: -B + +diff -rupN binutils.orig/ld/testsuite/ld-scripts/pr14962.d binutils-2.41/ld/testsuite/ld-scripts/pr14962.d +--- binutils.orig/ld/testsuite/ld-scripts/pr14962.d 2023-10-19 12:11:47.546940798 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/pr14962.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,4 +1,4 @@ +-#ld: -Ttext=0x1000 -Tdata=0x2000 -T pr14962.t ++#ld: -Ttext=0x1000 -Tdata=0x2000 -T pr14962.t --no-error-rwx-segments + #source: pr14962a.s + #source: pr14962b.s + #nm: -n +diff -rupN binutils.orig/ld/testsuite/ld-scripts/pr18963.d binutils-2.41/ld/testsuite/ld-scripts/pr18963.d +--- binutils.orig/ld/testsuite/ld-scripts/pr18963.d 2023-10-19 12:11:47.546940798 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/pr18963.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,5 +1,5 @@ + # source: data.s +-# ld: -T pr18963.t ++# ld: -T pr18963.t --no-error-rwx-segments + # nm: -B -n + # notarget: *-*-vms + # Skip for VMS based targets as the linker automatically adds extra libraries that may not be present in a cross build. +diff -rupN binutils.orig/ld/testsuite/ld-scripts/pr20302.d binutils-2.41/ld/testsuite/ld-scripts/pr20302.d +--- binutils.orig/ld/testsuite/ld-scripts/pr20302.d 2023-10-19 12:11:47.546940798 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/pr20302.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,4 +1,4 @@ +-#ld: -Tdata=0x1000 -Tdata=0x2000 -Tcross2.t ++#ld: -Tdata=0x1000 -Tdata=0x2000 -Tcross2.t --no-error-rwx-segments + #source: align2a.s + #objdump: -h + #notarget: *-*-*aout *-*-netbsd *-*-vms ns32k-*-* rx-*-* +diff -rupN binutils.orig/ld/testsuite/ld-scripts/print-memory-usage.exp binutils-2.41/ld/testsuite/ld-scripts/print-memory-usage.exp +--- binutils.orig/ld/testsuite/ld-scripts/print-memory-usage.exp 2023-10-19 12:11:47.547940799 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/print-memory-usage.exp 2023-10-19 12:11:56.519949629 +0100 +@@ -51,7 +51,7 @@ run_ld_link_tests { + + { + "print-memory-usage-2" +- "-T print-memory-usage-2.t --print-memory-usage" ++ "-T print-memory-usage-2.t --print-memory-usage --no-error-rwx-segments" + "" + "" + { "print-memory-usage-1.s" } +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-at1.d binutils-2.41/ld/testsuite/ld-scripts/rgn-at1.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-at1.d 2023-10-19 12:11:47.548940800 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-at1.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + # name: rgn-at1 + # source: rgn-at.s +-# ld: -T rgn-at1.t ++# ld: -T rgn-at1.t --no-error-rwx-segments + # objdump: -w -h + # xfail: rx-*-* + # FAILS on the RX because the linker has to set LMA == VMA for the +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-at10.d binutils-2.41/ld/testsuite/ld-scripts/rgn-at10.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-at10.d 2023-10-19 12:11:47.548940800 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-at10.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,5 +1,5 @@ + #source: rgn-at10.s +-#ld: -T rgn-at10.t ++#ld: -T rgn-at10.t --no-error-rwx-segments + #objdump: -h --wide + #xfail: hppa*64*-*-hpux* v850*-*-* + # Test that lma is adjusted in case the section start vma is aligned and +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-at4.d binutils-2.41/ld/testsuite/ld-scripts/rgn-at4.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-at4.d 2023-10-19 12:11:47.548940800 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-at4.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + # name: rgn-at4 + # source: rgn-at.s +-# ld: -T rgn-at4.t ++# ld: -T rgn-at4.t --no-error-rwx-segments + # objdump: -w -h + # xfail: rx-*-* + # FAILS on the RX because the linker has to set LMA == VMA for the +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-at6.d binutils-2.41/ld/testsuite/ld-scripts/rgn-at6.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-at6.d 2023-10-19 12:11:47.548940800 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-at6.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,5 +1,5 @@ + #source: rgn-at6.s +-#ld: -T rgn-at6.t ++#ld: -T rgn-at6.t --no-error-rwx-segments + #objdump: -h --wide + # Test that lma is aligned as for vma when lma_region==region. + +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-at8.d binutils-2.41/ld/testsuite/ld-scripts/rgn-at8.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-at8.d 2023-10-19 12:11:47.548940800 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-at8.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,5 +1,5 @@ + #source: rgn-at6.s +-#ld: -T rgn-at8.t ++#ld: -T rgn-at8.t --no-error-rwx-segments + #objdump: -h --wide + # Test that lma is aligned when lma_region!=region and requested by script. + +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-at9.d binutils-2.41/ld/testsuite/ld-scripts/rgn-at9.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-at9.d 2023-10-19 12:11:47.548940800 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-at9.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,5 +1,5 @@ + #source: rgn-at6.s +-#ld: -T rgn-at9.t ++#ld: -T rgn-at9.t --no-error-rwx-segments + #objdump: -h --wide + #xfail: rx-*-* + # Test that lma is adjusted in case the section start vma is aligned and +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-over1.d binutils-2.41/ld/testsuite/ld-scripts/rgn-over1.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-over1.d 2023-10-19 12:11:47.549940801 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-over1.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + # name: rgn-over1 + # source: rgn-over.s +-# ld: -T rgn-over1.t -Map tmpdir/rgn-over1.map ++# ld: -T rgn-over1.t -Map tmpdir/rgn-over1.map --no-error-rwx-segments + # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \`.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\Z + + #... +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-over2.d binutils-2.41/ld/testsuite/ld-scripts/rgn-over2.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-over2.d 2023-10-19 12:11:47.549940801 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-over2.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + # name: rgn-over2 + # source: rgn-over.s +-# ld: -T rgn-over2.t -Map tmpdir/rgn-over2.map ++# ld: -T rgn-over2.t -Map tmpdir/rgn-over2.map --no-error-rwx-segments + # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.data' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\Z + + #... +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-over4.d binutils-2.41/ld/testsuite/ld-scripts/rgn-over4.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-over4.d 2023-10-19 12:11:47.549940801 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-over4.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + # name: rgn-over4 + # source: rgn-over.s +-# ld: -T rgn-over4.t -Map tmpdir/rgn-over4.map ++# ld: -T rgn-over4.t -Map tmpdir/rgn-over4.map --no-error-rwx-segments + # error: \A[^ \n]*?ld[^:\n]*?: [^:\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\Z + + #... +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-over5.d binutils-2.41/ld/testsuite/ld-scripts/rgn-over5.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-over5.d 2023-10-19 12:11:47.549940801 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-over5.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + # name: rgn-over5 + # source: rgn-over.s +-# ld: -T rgn-over5.t -Map tmpdir/rgn-over5.map ++# ld: -T rgn-over5.t -Map tmpdir/rgn-over5.map --no-error-rwx-segments + # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `v1'\n[^ \n]*?ld[^:\n]*?: region `v1' overflowed by 16 bytes\Z + + #... +diff -rupN binutils.orig/ld/testsuite/ld-scripts/rgn-over6.d binutils-2.41/ld/testsuite/ld-scripts/rgn-over6.d +--- binutils.orig/ld/testsuite/ld-scripts/rgn-over6.d 2023-10-19 12:11:47.549940801 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/rgn-over6.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + # name: rgn-over6 + # source: rgn-over.s +-# ld: -T rgn-over6.t -Map tmpdir/rgn-over6.map ++# ld: -T rgn-over6.t -Map tmpdir/rgn-over6.map --no-error-rwx-segments + # error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `v1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\n[^ \n]*?ld[^:\n]*?: region `v1' overflowed by 16 bytes\Z + + #... +diff -rupN binutils.orig/ld/testsuite/ld-scripts/script.exp binutils-2.41/ld/testsuite/ld-scripts/script.exp +--- binutils.orig/ld/testsuite/ld-scripts/script.exp 2023-10-19 12:11:47.549940801 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/script.exp 2023-10-19 12:11:56.519949629 +0100 +@@ -190,7 +190,7 @@ if { [is_pecoff_format] } then { + } + set flags $LDFLAGS + +-if ![ld_link $ld tmpdir/script "$flags -T $srcdir/$subdir/script.t tmpdir/script.o"] { ++if ![ld_link $ld tmpdir/script "$flags -T $srcdir/$subdir/script.t tmpdir/script.o --no-error-rwx-segments"] { + fail $testname + } else { + check_script +@@ -198,7 +198,7 @@ if ![ld_link $ld tmpdir/script "$flags - + + set testname "MRI script" + +-if ![ld_link $ld tmpdir/script "$flags -c $srcdir/$subdir/scriptm.t"] { ++if ![ld_link $ld tmpdir/script "$flags -c $srcdir/$subdir/scriptm.t --no-error-rwx-segments"] { + fail $testname + } else { + check_script +diff -rupN binutils.orig/ld/testsuite/ld-scripts/sizeof.exp binutils-2.41/ld/testsuite/ld-scripts/sizeof.exp +--- binutils.orig/ld/testsuite/ld-scripts/sizeof.exp 2023-10-19 12:11:47.550940802 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/sizeof.exp 2023-10-19 12:11:56.519949629 +0100 +@@ -34,7 +34,7 @@ if { [is_pecoff_format] } { + } + + if ![ld_link $ld tmpdir/sizeof "$LDFLAGS -T $srcdir/$subdir/sizeof.t \ +- $IMAGE_BASE tmpdir/sizeof.o"] { ++ $IMAGE_BASE tmpdir/sizeof.o --no-error-rwx-segments"] { + fail $testname + return + } +diff -rupN binutils.orig/ld/testsuite/ld-scripts/sort-file.d binutils-2.41/ld/testsuite/ld-scripts/sort-file.d +--- binutils.orig/ld/testsuite/ld-scripts/sort-file.d 2023-10-19 12:11:47.550940802 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/sort-file.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + #source: sort-file2.s + #source: sort-file1.s +-#ld: -T sort-file.t ++#ld: -T sort-file.t --no-error-rwx-segments + #nm: -n + + # Check that SORT_BY_NAME on filenames works +diff -rupN binutils.orig/ld/testsuite/ld-x86-64/discarded1.d binutils-2.41/ld/testsuite/ld-x86-64/discarded1.d +--- binutils.orig/ld/testsuite/ld-x86-64/discarded1.d 2023-10-19 12:11:47.577940829 +0100 ++++ binutils-2.41/ld/testsuite/ld-x86-64/discarded1.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,3 +1,3 @@ + #as: --64 +-#ld: -melf_x86_64 -T discarded1.t ++#ld: -melf_x86_64 -T discarded1.t --no-error-rwx-segments + #error: .*discarded output section: `.got.plt' +diff -rupN binutils.orig/ld/testsuite/ld-x86-64/pr19175.d binutils-2.41/ld/testsuite/ld-x86-64/pr19175.d +--- binutils.orig/ld/testsuite/ld-x86-64/pr19175.d 2023-10-19 12:11:47.585940837 +0100 ++++ binutils-2.41/ld/testsuite/ld-x86-64/pr19175.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + #source: pr19175.s + #as: --64 +-#ld: -Bsymbolic -shared -melf_x86_64 -T pr19175.t ++#ld: -Bsymbolic -shared -melf_x86_64 -T pr19175.t --no-error-rwx-segments + #objdump: -dw + + .*: +file format .* +diff -rupN binutils.orig/ld/testsuite/ld-x86-64/pr19539a.d binutils-2.41/ld/testsuite/ld-x86-64/pr19539a.d +--- binutils.orig/ld/testsuite/ld-x86-64/pr19539a.d 2023-10-19 12:11:47.585940837 +0100 ++++ binutils-2.41/ld/testsuite/ld-x86-64/pr19539a.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + #source: pr19539.s + #as: --64 +-#ld: -pie -m elf_x86_64 -T pr19539.t -z notext ++#ld: -pie -m elf_x86_64 -T pr19539.t -z notext --no-error-rwx-segments + #readelf: -r --wide + + Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entry: +diff -rupN binutils.orig/ld/testsuite/ld-x86-64/pr19539b.d binutils-2.41/ld/testsuite/ld-x86-64/pr19539b.d +--- binutils.orig/ld/testsuite/ld-x86-64/pr19539b.d 2023-10-19 12:11:47.585940837 +0100 ++++ binutils-2.41/ld/testsuite/ld-x86-64/pr19539b.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,6 +1,6 @@ + #source: pr19539.s + #as: --x32 +-#ld: -pie -m elf32_x86_64 -T pr19539.t -z notext ++#ld: -pie -m elf32_x86_64 -T pr19539.t -z notext --no-error-rwx-segments + #readelf: -r --wide + + Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entry: +diff -rupN binutils.orig/ld/testsuite/ld-x86-64/pr23189.d binutils-2.41/ld/testsuite/ld-x86-64/pr23189.d +--- binutils.orig/ld/testsuite/ld-x86-64/pr23189.d 2023-10-19 12:11:47.590940842 +0100 ++++ binutils-2.41/ld/testsuite/ld-x86-64/pr23189.d 2023-10-19 12:11:56.519949629 +0100 +@@ -1,5 +1,5 @@ + #as: --64 -mrelax-relocations=yes +-#ld: -shared -melf_x86_64 -T pr23189.t ++#ld: -shared -melf_x86_64 -T pr23189.t --no-error-rwx-segments + #readelf: -r --wide + + There are no relocations in this file. diff --git a/binutils.spec b/binutils.spec index b75c4c0..472338a 100644 --- a/binutils.spec +++ b/binutils.spec @@ -2,7 +2,7 @@ Summary: A GNU collection of binary utilities Name: binutils%{?_with_debug:-debug} Version: 2.41 -Release: 7%{?dist} +Release: 8%{?dist} License: GPL-3.0-or-later AND (GPL-3.0-or-later WITH Bison-exception-2.2) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND BSD-3-Clause AND GFDL-1.3-or-later AND GPL-2.0-or-later LGPL-2.1-or-later AND LGPL-2.0-or-later URL: https://sourceware.org/binutils @@ -35,7 +35,11 @@ URL: https://sourceware.org/binutils %define warn_for_executable_stacks 1 # Generate a warning when linking creates a segment with read, write and execute permissions -%define warn_for_rwx_segments 0 +%define warn_for_rwx_segments 1 + +# Turn the above warnings into errors. Only effective if the warnings are enabled. +%define error_for_executable_stacks 0 +%define error_for_rwx_segments 0 # Enable support for GCC LTO compilation. # Disable if it is necessary to work around bugs in LTO. @@ -261,6 +265,11 @@ Patch18: binutils-gold-powerpc.patch # Lifetime: Fixed in 2.42 Patch19: binutils-handle-corrupt-version-info.patch +# Purpose: Add options to turn the bfd linker's warnings about executable +# stacks and rwx segments into errors. +# Lifetime: Fixed in 2.42 +Patch20: binutils-execstack-error.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -593,12 +602,18 @@ compute_global_configuration() %if %{warn_for_executable_stacks} CARGS="$CARGS --enable-warn-execstack=yes" CARGS="$CARGS --enable-default-execstack=no" +%if %{error_for_executable_stacks} + CARGS="$CARGS --enable-error-execstack=yes" +%endif %else CARGS="$CARGS --enable-warn-execstack=no" %endif %if %{warn_for_rwx_segments} CARGS="$CARGS --enable-warn-rwx-segments=yes" +%if %{error_for_rwx_segments} + CARGS="$CARGS --enable-error-rwx-segments=yes" +%endif %else CARGS="$CARGS --enable-warn-rwx-segments=no" %endif @@ -1260,6 +1275,10 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Thu Oct 19 2023 Nick Clifton - 2.41-8 +- Add ability to turn execstack warnings into errors. +- Enable warnings for rsx segments. + * Fri Oct 13 2023 Nick Clifton - 2.41-7 - Fix a potential NULL pointer derefence when parsing corrupt ELF symbol version information. (#2243769)