elf32.em revision 68778
160525Sobrien# $FreeBSD: head/contrib/binutils/ld/emultempl/elf32.em 68778 2000-11-15 21:26:21Z obrien $ 233965Sjdp# This shell script emits a C file. -*- C -*- 333965Sjdp# It does some substitutions. 433965Sjdp# This file is now misnamed, because it supports both 32 bit and 64 bit 533965Sjdp# ELF emulations. 633965Sjdptest -z "${ELFSIZE}" && ELFSIZE=32 733965Sjdpcat >e${EMULATION_NAME}.c <<EOF 833965Sjdp/* This file is is generated by a shell script. DO NOT EDIT! */ 933965Sjdp 1033965Sjdp/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME} 1168778Sobrien Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000 1260525Sobrien Free Software Foundation, Inc. 1333965Sjdp Written by Steve Chamberlain <sac@cygnus.com> 1433965Sjdp ELF support by Ian Lance Taylor <ian@cygnus.com> 1533965Sjdp 1633965SjdpThis file is part of GLD, the Gnu Linker. 1733965Sjdp 1833965SjdpThis program is free software; you can redistribute it and/or modify 1933965Sjdpit under the terms of the GNU General Public License as published by 2033965Sjdpthe Free Software Foundation; either version 2 of the License, or 2133965Sjdp(at your option) any later version. 2233965Sjdp 2333965SjdpThis program is distributed in the hope that it will be useful, 2433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 2533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2633965SjdpGNU General Public License for more details. 2733965Sjdp 2833965SjdpYou should have received a copy of the GNU General Public License 2933965Sjdpalong with this program; if not, write to the Free Software 3033965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 3133965Sjdp 3233965Sjdp#define TARGET_IS_${EMULATION_NAME} 3333965Sjdp 3433965Sjdp#include "bfd.h" 3533965Sjdp#include "sysdep.h" 3633965Sjdp 3733965Sjdp#include <ctype.h> 3833965Sjdp 3933965Sjdp#include "bfdlink.h" 4033965Sjdp 4133965Sjdp#include "ld.h" 4233965Sjdp#include "ldmain.h" 4333965Sjdp#include "ldemul.h" 4433965Sjdp#include "ldfile.h" 4533965Sjdp#include "ldmisc.h" 4633965Sjdp#include "ldexp.h" 4733965Sjdp#include "ldlang.h" 4833965Sjdp#include "ldgram.h" 4933965Sjdp 5033965Sjdpstatic void gld${EMULATION_NAME}_before_parse PARAMS ((void)); 5133965Sjdpstatic boolean gld${EMULATION_NAME}_open_dynamic_archive 5233965Sjdp PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); 5333965Sjdpstatic void gld${EMULATION_NAME}_after_open PARAMS ((void)); 5433965Sjdpstatic void gld${EMULATION_NAME}_check_needed 5533965Sjdp PARAMS ((lang_input_statement_type *)); 5633965Sjdpstatic void gld${EMULATION_NAME}_stat_needed 5733965Sjdp PARAMS ((lang_input_statement_type *)); 5833965Sjdpstatic boolean gld${EMULATION_NAME}_search_needed 5938889Sjdp PARAMS ((const char *, const char *, int)); 6038889Sjdpstatic boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, int)); 6138889Sjdpstatic void gld${EMULATION_NAME}_vercheck 6238889Sjdp PARAMS ((lang_input_statement_type *)); 6333965Sjdpstatic void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); 6433965Sjdpstatic void gld${EMULATION_NAME}_find_statement_assignment 6533965Sjdp PARAMS ((lang_statement_union_type *)); 6633965Sjdpstatic void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); 6768778Sobrienstatic lang_output_section_statement_type *output_rel_find PARAMS ((void)); 6833965Sjdpstatic boolean gld${EMULATION_NAME}_place_orphan 6933965Sjdp PARAMS ((lang_input_statement_type *, asection *)); 7033965Sjdpstatic char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); 7133965Sjdp 7233965Sjdpstatic void 7333965Sjdpgld${EMULATION_NAME}_before_parse() 7433965Sjdp{ 7533965Sjdp ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; 7633965Sjdp config.dynamic_link = ${DYNAMIC_LINK-true}; 7760525Sobrien config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`; 7833965Sjdp} 7933965Sjdp 8033965Sjdp/* Try to open a dynamic archive. This is where we know that ELF 8160525Sobrien dynamic libraries have an extension of .so (or .sl on oddball systems 8260525Sobrien like hpux). */ 8333965Sjdp 8433965Sjdpstatic boolean 8533965Sjdpgld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) 8633965Sjdp const char *arch; 8733965Sjdp search_dirs_type *search; 8833965Sjdp lang_input_statement_type *entry; 8933965Sjdp{ 9033965Sjdp const char *filename; 9133965Sjdp char *string; 9233965Sjdp 9333965Sjdp if (! entry->is_archive) 9433965Sjdp return false; 9533965Sjdp 9633965Sjdp filename = entry->filename; 9733965Sjdp 9860525Sobrien /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION 9960525Sobrien is defined, but it does not seem worth the headache to optimize 10060525Sobrien away those two bytes of space. */ 10133965Sjdp string = (char *) xmalloc (strlen (search->name) 10233965Sjdp + strlen (filename) 10333965Sjdp + strlen (arch) 10460525Sobrien#ifdef EXTRA_SHLIB_EXTENSION 10560525Sobrien + strlen (EXTRA_SHLIB_EXTENSION) 10660525Sobrien#endif 10733965Sjdp + sizeof "/lib.so"); 10833965Sjdp 10933965Sjdp sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); 11033965Sjdp 11160525Sobrien#ifdef EXTRA_SHLIB_EXTENSION 11260525Sobrien /* Try the .so extension first. If that fails build a new filename 11360525Sobrien using EXTRA_SHLIB_EXTENSION. */ 11433965Sjdp if (! ldfile_try_open_bfd (string, entry)) 11560525Sobrien sprintf (string, "%s/lib%s%s%s", search->name, 11660525Sobrien filename, arch, EXTRA_SHLIB_EXTENSION); 11760525Sobrien#endif 11860525Sobrien 11960525Sobrien if (! ldfile_try_open_bfd (string, entry)) 12033965Sjdp { 12133965Sjdp free (string); 12233965Sjdp return false; 12333965Sjdp } 12433965Sjdp 12533965Sjdp entry->filename = string; 12633965Sjdp 12733965Sjdp /* We have found a dynamic object to include in the link. The ELF 12833965Sjdp backend linker will create a DT_NEEDED entry in the .dynamic 12933965Sjdp section naming this file. If this file includes a DT_SONAME 13033965Sjdp entry, it will be used. Otherwise, the ELF linker will just use 13133965Sjdp the name of the file. For an archive found by searching, like 13233965Sjdp this one, the DT_NEEDED entry should consist of just the name of 13333965Sjdp the file, without the path information used to find it. Note 13433965Sjdp that we only need to do this if we have a dynamic object; an 13533965Sjdp archive will never be referenced by a DT_NEEDED entry. 13633965Sjdp 13733965Sjdp FIXME: This approach--using bfd_elf_set_dt_needed_name--is not 13833965Sjdp very pretty. I haven't been able to think of anything that is 13933965Sjdp pretty, though. */ 14033965Sjdp if (bfd_check_format (entry->the_bfd, bfd_object) 14133965Sjdp && (entry->the_bfd->flags & DYNAMIC) != 0) 14233965Sjdp { 14333965Sjdp char *needed_name; 14433965Sjdp 14533965Sjdp ASSERT (entry->is_archive && entry->search_dirs_flag); 14660525Sobrien 14760525Sobrien /* Rather than duplicating the logic above. Just use the 14860525Sobrien filename we recorded earlier. 14960525Sobrien 15060525Sobrien First strip off everything before the last '/'. */ 15160525Sobrien filename = strrchr (entry->filename, '/'); 15260525Sobrien filename++; 15360525Sobrien 15460525Sobrien needed_name = (char *) xmalloc (strlen (filename) + 1); 15560525Sobrien strcpy (needed_name, filename); 15633965Sjdp bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name); 15733965Sjdp } 15833965Sjdp 15933965Sjdp return true; 16033965Sjdp} 16133965Sjdp 16233965SjdpEOF 16333965Sjdpif [ "x${host}" = "x${target}" ] ; then 16460525Sobrien case " ${EMULATION_LIBPATH} " in 16560525Sobrien *" ${EMULATION_NAME} "*) 16642372Speter case ${target} in 16742372Speter *-*-freebsd*) 16842372Speter cat >>e${EMULATION_NAME}.c <<EOF 16942372Speter/* 17042372Speter * Read the system search path the FreeBSD way rather than like Linux. 17142372Speter */ 17242372Speter#include <elf.h> 17333965Sjdp 17442372Speterstatic boolean gld${EMULATION_NAME}_check_ld_elf_hints 17542372Speter PARAMS ((const char *, int)); 17642372Speter 17742372Speterstatic boolean 17842372Spetergld${EMULATION_NAME}_check_ld_elf_hints (name, force) 17942372Speter const char *name; 18042372Speter int force; 18142372Speter{ 18242372Speter static boolean initialized; 18342372Speter static char *ld_elf_hints; 18442372Speter 18542372Speter if (! initialized) 18642372Speter { 18742372Speter FILE *f; 18842372Speter 18942372Speter f = fopen (_PATH_ELF_HINTS, FOPEN_RB); 19042372Speter if (f != NULL) 19142372Speter { 19242372Speter struct elfhints_hdr hdr; 19342372Speter 19442372Speter if (fread(&hdr, 1, sizeof(hdr), f) == sizeof(hdr) && 19542372Speter hdr.magic == ELFHINTS_MAGIC && 19642372Speter hdr.version == 1) 19742372Speter { 19842372Speter if (fseek(f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1) 19942372Speter { 20042372Speter char *b; 20142372Speter 20242372Speter b = (char *) xmalloc (hdr.dirlistlen + 1); 20342372Speter if (fread(b, 1, hdr.dirlistlen + 1, f) != 20442372Speter hdr.dirlistlen + 1) 20542372Speter { 20642372Speter free(b); 20742372Speter } 20842372Speter else 20942372Speter { 21042372Speter ld_elf_hints = b; 21142372Speter } 21242372Speter } 21342372Speter } 21442372Speter fclose (f); 21542372Speter } 21642372Speter 21742372Speter initialized = true; 21842372Speter } 21942372Speter 22042372Speter if (ld_elf_hints == NULL) 22142372Speter return false; 22242372Speter 22342372Speter return gld${EMULATION_NAME}_search_needed (ld_elf_hints, name, force); 22442372Speter} 22542372SpeterEOF 22642372Speter ;; 22760525Sobrien 22860525Sobrien *linux*|*Linux*|*LINUX*) 22942372Speter cat >>e${EMULATION_NAME}.c <<EOF 23060525Sobrien 23133965Sjdp/* For a native linker, check the file /etc/ld.so.conf for directories 23233965Sjdp in which we may find shared libraries. /etc/ld.so.conf is really 23360525Sobrien only meaningful on Linux. */ 23433965Sjdp 23538889Sjdpstatic boolean gld${EMULATION_NAME}_check_ld_so_conf 23638889Sjdp PARAMS ((const char *, int)); 23733965Sjdp 23833965Sjdpstatic boolean 23938889Sjdpgld${EMULATION_NAME}_check_ld_so_conf (name, force) 24033965Sjdp const char *name; 24138889Sjdp int force; 24233965Sjdp{ 24333965Sjdp static boolean initialized; 24433965Sjdp static char *ld_so_conf; 24533965Sjdp 24633965Sjdp if (! initialized) 24733965Sjdp { 24833965Sjdp FILE *f; 24933965Sjdp 25033965Sjdp f = fopen ("/etc/ld.so.conf", FOPEN_RT); 25133965Sjdp if (f != NULL) 25233965Sjdp { 25333965Sjdp char *b; 25433965Sjdp size_t len, alloc; 25533965Sjdp int c; 25633965Sjdp 25733965Sjdp len = 0; 25833965Sjdp alloc = 100; 25933965Sjdp b = (char *) xmalloc (alloc); 26033965Sjdp 26133965Sjdp while ((c = getc (f)) != EOF) 26233965Sjdp { 26333965Sjdp if (len + 1 >= alloc) 26433965Sjdp { 26533965Sjdp alloc *= 2; 26633965Sjdp b = (char *) xrealloc (b, alloc); 26733965Sjdp } 26833965Sjdp if (c != ':' 26933965Sjdp && c != ' ' 27033965Sjdp && c != '\t' 27133965Sjdp && c != '\n' 27233965Sjdp && c != ',') 27333965Sjdp { 27433965Sjdp b[len] = c; 27533965Sjdp ++len; 27633965Sjdp } 27733965Sjdp else 27833965Sjdp { 27933965Sjdp if (len > 0 && b[len - 1] != ':') 28033965Sjdp { 28133965Sjdp b[len] = ':'; 28233965Sjdp ++len; 28333965Sjdp } 28433965Sjdp } 28533965Sjdp } 28633965Sjdp 28733965Sjdp if (len > 0 && b[len - 1] == ':') 28833965Sjdp --len; 28933965Sjdp 29033965Sjdp if (len > 0) 29133965Sjdp b[len] = '\0'; 29233965Sjdp else 29333965Sjdp { 29433965Sjdp free (b); 29533965Sjdp b = NULL; 29633965Sjdp } 29733965Sjdp 29833965Sjdp fclose (f); 29933965Sjdp 30033965Sjdp ld_so_conf = b; 30133965Sjdp } 30233965Sjdp 30333965Sjdp initialized = true; 30433965Sjdp } 30533965Sjdp 30633965Sjdp if (ld_so_conf == NULL) 30733965Sjdp return false; 30833965Sjdp 30938889Sjdp return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force); 31033965Sjdp} 31160525Sobrien 31233965SjdpEOF 31360525Sobrien ;; 31442372Speter esac 31560525Sobrien esac 31633965Sjdpfi 31733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 31833965Sjdp 31933965Sjdp/* These variables are required to pass information back and forth 32038889Sjdp between after_open and check_needed and stat_needed and vercheck. */ 32133965Sjdp 32233965Sjdpstatic struct bfd_link_needed_list *global_needed; 32333965Sjdpstatic struct stat global_stat; 32433965Sjdpstatic boolean global_found; 32538889Sjdpstatic struct bfd_link_needed_list *global_vercheck_needed; 32638889Sjdpstatic boolean global_vercheck_failed; 32733965Sjdp 32833965Sjdp/* This is called after all the input files have been opened. */ 32933965Sjdp 33033965Sjdpstatic void 33133965Sjdpgld${EMULATION_NAME}_after_open () 33233965Sjdp{ 33333965Sjdp struct bfd_link_needed_list *needed, *l; 33433965Sjdp 33533965Sjdp /* We only need to worry about this when doing a final link. */ 33633965Sjdp if (link_info.relocateable || link_info.shared) 33733965Sjdp return; 33833965Sjdp 33933965Sjdp /* Get the list of files which appear in DT_NEEDED entries in 34033965Sjdp dynamic objects included in the link (often there will be none). 34133965Sjdp For each such file, we want to track down the corresponding 34233965Sjdp library, and include the symbol table in the link. This is what 34333965Sjdp the runtime dynamic linker will do. Tracking the files down here 34433965Sjdp permits one dynamic object to include another without requiring 34533965Sjdp special action by the person doing the link. Note that the 34633965Sjdp needed list can actually grow while we are stepping through this 34733965Sjdp loop. */ 34833965Sjdp needed = bfd_elf_get_needed_list (output_bfd, &link_info); 34933965Sjdp for (l = needed; l != NULL; l = l->next) 35033965Sjdp { 35133965Sjdp struct bfd_link_needed_list *ll; 35238889Sjdp int force; 35333965Sjdp 35433965Sjdp /* If we've already seen this file, skip it. */ 35533965Sjdp for (ll = needed; ll != l; ll = ll->next) 35633965Sjdp if (strcmp (ll->name, l->name) == 0) 35733965Sjdp break; 35833965Sjdp if (ll != l) 35933965Sjdp continue; 36033965Sjdp 36133965Sjdp /* See if this file was included in the link explicitly. */ 36233965Sjdp global_needed = l; 36333965Sjdp global_found = false; 36433965Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); 36533965Sjdp if (global_found) 36633965Sjdp continue; 36733965Sjdp 36833965Sjdp /* We need to find this file and include the symbol table. We 36933965Sjdp want to search for the file in the same way that the dynamic 37033965Sjdp linker will search. That means that we want to use 37133965Sjdp rpath_link, rpath, then the environment variable 37233965Sjdp LD_LIBRARY_PATH (native only), then the linker script 37338889Sjdp LIB_SEARCH_DIRS. We do not search using the -L arguments. 37438889Sjdp 37538889Sjdp We search twice. The first time, we skip objects which may 37638889Sjdp introduce version mismatches. The second time, we force 37738889Sjdp their use. See gld${EMULATION_NAME}_vercheck comment. */ 37838889Sjdp for (force = 0; force < 2; force++) 37933965Sjdp { 38038889Sjdp const char *lib_path; 38138889Sjdp size_t len; 38238889Sjdp search_dirs_type *search; 38338889Sjdp 38438889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, 38538889Sjdp l->name, force)) 38638889Sjdp break; 38738889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath, 38838889Sjdp l->name, force)) 38938889Sjdp break; 39038889Sjdp if (command_line.rpath_link == NULL 39138889Sjdp && command_line.rpath == NULL) 39238889Sjdp { 39338889Sjdp lib_path = (const char *) getenv ("LD_RUN_PATH"); 39438889Sjdp if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, 39538889Sjdp force)) 39638889Sjdp break; 39738889Sjdp } 39833965SjdpEOF 39933965Sjdpif [ "x${host}" = "x${target}" ] ; then 40060525Sobrien case " ${EMULATION_LIBPATH} " in 40160525Sobrien *" ${EMULATION_NAME} "*) 40233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 40338889Sjdp lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); 40438889Sjdp if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force)) 40538889Sjdp break; 40633965SjdpEOF 40760525Sobrien ;; 40860525Sobrien esac 40933965Sjdpfi 41033965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 41138889Sjdp len = strlen (l->name); 41238889Sjdp for (search = search_head; search != NULL; search = search->next) 41338889Sjdp { 41438889Sjdp char *filename; 41533965Sjdp 41638889Sjdp if (search->cmdline) 41738889Sjdp continue; 41838889Sjdp filename = (char *) xmalloc (strlen (search->name) + len + 2); 41938889Sjdp sprintf (filename, "%s/%s", search->name, l->name); 42038889Sjdp if (gld${EMULATION_NAME}_try_needed (filename, force)) 42138889Sjdp break; 42238889Sjdp free (filename); 42338889Sjdp } 42438889Sjdp if (search != NULL) 42533965Sjdp break; 42633965SjdpEOF 42733965Sjdpif [ "x${host}" = "x${target}" ] ; then 42860525Sobrien case " ${EMULATION_LIBPATH} " in 42960525Sobrien *" ${EMULATION_NAME} "*) 43042372Speter case ${target} in 43142372Speter *-*-freebsd*) 43242372Speter cat >>e${EMULATION_NAME}.c <<EOF 43342372Speter if (gld${EMULATION_NAME}_check_ld_elf_hints (l->name, force)) 43442372Speter break; 43542372SpeterEOF 43642372Speter ;; 43760525Sobrien *linux*|*Linux*|*LINUX*) 43842372Speter cat >>e${EMULATION_NAME}.c <<EOF 43938889Sjdp if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force)) 44038889Sjdp break; 44133965SjdpEOF 44242372Speter ;; 44342372Speter esac 44460525Sobrien ;; 44560525Sobrien esac 44633965Sjdpfi 44733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 44838889Sjdp } 44933965Sjdp 45038889Sjdp if (force < 2) 45138889Sjdp continue; 45238889Sjdp 45368778Sobrien einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n", 45433965Sjdp l->name, l->by); 45533965Sjdp } 45633965Sjdp} 45733965Sjdp 45833965Sjdp/* Search for a needed file in a path. */ 45933965Sjdp 46033965Sjdpstatic boolean 46138889Sjdpgld${EMULATION_NAME}_search_needed (path, name, force) 46233965Sjdp const char *path; 46333965Sjdp const char *name; 46438889Sjdp int force; 46533965Sjdp{ 46633965Sjdp const char *s; 46733965Sjdp size_t len; 46833965Sjdp 46933965Sjdp if (path == NULL || *path == '\0') 47033965Sjdp return false; 47133965Sjdp len = strlen (name); 47233965Sjdp while (1) 47333965Sjdp { 47433965Sjdp char *filename, *sset; 47533965Sjdp 47633965Sjdp s = strchr (path, ':'); 47733965Sjdp if (s == NULL) 47833965Sjdp s = path + strlen (path); 47933965Sjdp 48033965Sjdp filename = (char *) xmalloc (s - path + len + 2); 48133965Sjdp if (s == path) 48233965Sjdp sset = filename; 48333965Sjdp else 48433965Sjdp { 48533965Sjdp memcpy (filename, path, s - path); 48633965Sjdp filename[s - path] = '/'; 48733965Sjdp sset = filename + (s - path) + 1; 48833965Sjdp } 48933965Sjdp strcpy (sset, name); 49033965Sjdp 49138889Sjdp if (gld${EMULATION_NAME}_try_needed (filename, force)) 49233965Sjdp return true; 49333965Sjdp 49433965Sjdp free (filename); 49533965Sjdp 49633965Sjdp if (*s == '\0') 49733965Sjdp break; 49833965Sjdp path = s + 1; 49933965Sjdp } 50033965Sjdp 50133965Sjdp return false; 50233965Sjdp} 50333965Sjdp 50433965Sjdp/* This function is called for each possible name for a dynamic object 50538889Sjdp named by a DT_NEEDED entry. The FORCE parameter indicates whether 50638889Sjdp to skip the check for a conflicting version. */ 50733965Sjdp 50833965Sjdpstatic boolean 50938889Sjdpgld${EMULATION_NAME}_try_needed (name, force) 51033965Sjdp const char *name; 51138889Sjdp int force; 51233965Sjdp{ 51333965Sjdp bfd *abfd; 51433965Sjdp 51533965Sjdp abfd = bfd_openr (name, bfd_get_target (output_bfd)); 51633965Sjdp if (abfd == NULL) 51733965Sjdp return false; 51833965Sjdp if (! bfd_check_format (abfd, bfd_object)) 51933965Sjdp { 52033965Sjdp (void) bfd_close (abfd); 52133965Sjdp return false; 52233965Sjdp } 52333965Sjdp if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) 52433965Sjdp { 52533965Sjdp (void) bfd_close (abfd); 52633965Sjdp return false; 52733965Sjdp } 52833965Sjdp 52938889Sjdp /* Check whether this object would include any conflicting library 53038889Sjdp versions. If FORCE is set, then we skip this check; we use this 53138889Sjdp the second time around, if we couldn't find any compatible 53238889Sjdp instance of the shared library. */ 53338889Sjdp 53438889Sjdp if (! force) 53538889Sjdp { 53638889Sjdp struct bfd_link_needed_list *needed; 53738889Sjdp 53838889Sjdp if (! bfd_elf_get_bfd_needed_list (abfd, &needed)) 53938889Sjdp einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd); 54038889Sjdp 54138889Sjdp if (needed != NULL) 54238889Sjdp { 54338889Sjdp global_vercheck_needed = needed; 54438889Sjdp global_vercheck_failed = false; 54538889Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_vercheck); 54638889Sjdp if (global_vercheck_failed) 54738889Sjdp { 54838889Sjdp (void) bfd_close (abfd); 54938889Sjdp /* Return false to force the caller to move on to try 55038889Sjdp another file on the search path. */ 55138889Sjdp return false; 55238889Sjdp } 55338889Sjdp 55438889Sjdp /* But wait! It gets much worse. On Linux, if a shared 55538889Sjdp library does not use libc at all, we are supposed to skip 55638889Sjdp it the first time around in case we encounter a shared 55738889Sjdp library later on with the same name which does use the 55838889Sjdp version of libc that we want. This is much too horrible 55938889Sjdp to use on any system other than Linux. */ 56038889Sjdp 56138889SjdpEOF 56238889Sjdpcase ${target} in 56338889Sjdp *-*-linux-gnu*) 56438889Sjdp cat >>e${EMULATION_NAME}.c <<EOF 56538889Sjdp { 56638889Sjdp struct bfd_link_needed_list *l; 56738889Sjdp 56838889Sjdp for (l = needed; l != NULL; l = l->next) 56938889Sjdp if (strncmp (l->name, "libc.so", 7) == 0) 57038889Sjdp break; 57138889Sjdp if (l == NULL) 57238889Sjdp { 57338889Sjdp (void) bfd_close (abfd); 57438889Sjdp return false; 57538889Sjdp } 57638889Sjdp } 57738889Sjdp 57838889SjdpEOF 57938889Sjdp ;; 58038889Sjdpesac 58138889Sjdpcat >>e${EMULATION_NAME}.c <<EOF 58238889Sjdp } 58338889Sjdp } 58438889Sjdp 58533965Sjdp /* We've found a dynamic object matching the DT_NEEDED entry. */ 58633965Sjdp 58733965Sjdp /* We have already checked that there is no other input file of the 58833965Sjdp same name. We must now check again that we are not including the 58933965Sjdp same file twice. We need to do this because on many systems 59033965Sjdp libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will 59133965Sjdp reference libc.so.1. If we have already included libc.so, we 59233965Sjdp don't want to include libc.so.1 if they are the same file, and we 59333965Sjdp can only check that using stat. */ 59433965Sjdp 59533965Sjdp if (bfd_stat (abfd, &global_stat) != 0) 59633965Sjdp einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd); 59733965Sjdp global_found = false; 59833965Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed); 59933965Sjdp if (global_found) 60033965Sjdp { 60133965Sjdp /* Return true to indicate that we found the file, even though 60233965Sjdp we aren't going to do anything with it. */ 60333965Sjdp return true; 60433965Sjdp } 60533965Sjdp 60633965Sjdp /* Tell the ELF backend that don't want the output file to have a 60733965Sjdp DT_NEEDED entry for this file. */ 60833965Sjdp bfd_elf_set_dt_needed_name (abfd, ""); 60933965Sjdp 61033965Sjdp /* Add this file into the symbol table. */ 61133965Sjdp if (! bfd_link_add_symbols (abfd, &link_info)) 61233965Sjdp einfo ("%F%B: could not read symbols: %E\n", abfd); 61333965Sjdp 61433965Sjdp return true; 61533965Sjdp} 61633965Sjdp 61733965Sjdp/* See if an input file matches a DT_NEEDED entry by name. */ 61833965Sjdp 61933965Sjdpstatic void 62033965Sjdpgld${EMULATION_NAME}_check_needed (s) 62133965Sjdp lang_input_statement_type *s; 62233965Sjdp{ 62333965Sjdp if (global_found) 62433965Sjdp return; 62533965Sjdp 62633965Sjdp if (s->filename != NULL 62733965Sjdp && strcmp (s->filename, global_needed->name) == 0) 62833965Sjdp { 62933965Sjdp global_found = true; 63033965Sjdp return; 63133965Sjdp } 63233965Sjdp 63333965Sjdp if (s->the_bfd != NULL) 63433965Sjdp { 63533965Sjdp const char *soname; 63633965Sjdp 63733965Sjdp soname = bfd_elf_get_dt_soname (s->the_bfd); 63833965Sjdp if (soname != NULL 63933965Sjdp && strcmp (soname, global_needed->name) == 0) 64033965Sjdp { 64133965Sjdp global_found = true; 64233965Sjdp return; 64333965Sjdp } 64433965Sjdp } 64533965Sjdp 64633965Sjdp if (s->search_dirs_flag 64733965Sjdp && s->filename != NULL 64833965Sjdp && strchr (global_needed->name, '/') == NULL) 64933965Sjdp { 65033965Sjdp const char *f; 65133965Sjdp 65233965Sjdp f = strrchr (s->filename, '/'); 65333965Sjdp if (f != NULL 65433965Sjdp && strcmp (f + 1, global_needed->name) == 0) 65533965Sjdp { 65633965Sjdp global_found = true; 65733965Sjdp return; 65833965Sjdp } 65933965Sjdp } 66033965Sjdp} 66133965Sjdp 66233965Sjdp/* See if an input file matches a DT_NEEDED entry by running stat on 66333965Sjdp the file. */ 66433965Sjdp 66533965Sjdpstatic void 66633965Sjdpgld${EMULATION_NAME}_stat_needed (s) 66733965Sjdp lang_input_statement_type *s; 66833965Sjdp{ 66933965Sjdp struct stat st; 67033965Sjdp const char *suffix; 67133965Sjdp const char *soname; 67233965Sjdp const char *f; 67333965Sjdp 67433965Sjdp if (global_found) 67533965Sjdp return; 67633965Sjdp if (s->the_bfd == NULL) 67733965Sjdp return; 67833965Sjdp 67933965Sjdp if (bfd_stat (s->the_bfd, &st) != 0) 68033965Sjdp { 68133965Sjdp einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd); 68233965Sjdp return; 68333965Sjdp } 68433965Sjdp 68533965Sjdp if (st.st_dev == global_stat.st_dev 68633965Sjdp && st.st_ino == global_stat.st_ino) 68733965Sjdp { 68833965Sjdp global_found = true; 68933965Sjdp return; 69033965Sjdp } 69133965Sjdp 69233965Sjdp /* We issue a warning if it looks like we are including two 69333965Sjdp different versions of the same shared library. For example, 69433965Sjdp there may be a problem if -lc picks up libc.so.6 but some other 69533965Sjdp shared library has a DT_NEEDED entry of libc.so.5. This is a 69633965Sjdp hueristic test, and it will only work if the name looks like 69733965Sjdp NAME.so.VERSION. FIXME: Depending on file names is error-prone. 69833965Sjdp If we really want to issue warnings about mixing version numbers 69933965Sjdp of shared libraries, we need to find a better way. */ 70033965Sjdp 70133965Sjdp if (strchr (global_needed->name, '/') != NULL) 70233965Sjdp return; 70333965Sjdp suffix = strstr (global_needed->name, ".so."); 70433965Sjdp if (suffix == NULL) 70533965Sjdp return; 70633965Sjdp suffix += sizeof ".so." - 1; 70733965Sjdp 70833965Sjdp soname = bfd_elf_get_dt_soname (s->the_bfd); 70933965Sjdp if (soname == NULL) 71033965Sjdp soname = s->filename; 71133965Sjdp 71233965Sjdp f = strrchr (soname, '/'); 71333965Sjdp if (f != NULL) 71433965Sjdp ++f; 71533965Sjdp else 71633965Sjdp f = soname; 71733965Sjdp 71833965Sjdp if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0) 71933965Sjdp einfo ("%P: warning: %s, needed by %B, may conflict with %s\n", 72033965Sjdp global_needed->name, global_needed->by, f); 72133965Sjdp} 72233965Sjdp 72338889Sjdp/* On Linux, it's possible to have different versions of the same 72438889Sjdp shared library linked against different versions of libc. The 72538889Sjdp dynamic linker somehow tags which libc version to use in 72638889Sjdp /etc/ld.so.cache, and, based on the libc that it sees in the 72738889Sjdp executable, chooses which version of the shared library to use. 72838889Sjdp 72938889Sjdp We try to do a similar check here by checking whether this shared 73038889Sjdp library needs any other shared libraries which may conflict with 73138889Sjdp libraries we have already included in the link. If it does, we 73238889Sjdp skip it, and try to find another shared library farther on down the 73338889Sjdp link path. 73438889Sjdp 73538889Sjdp This is called via lang_for_each_input_file. 73638889Sjdp GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object 73738889Sjdp which we ar checking. This sets GLOBAL_VERCHECK_FAILED if we find 73838889Sjdp a conflicting version. */ 73938889Sjdp 74038889Sjdpstatic void 74138889Sjdpgld${EMULATION_NAME}_vercheck (s) 74238889Sjdp lang_input_statement_type *s; 74338889Sjdp{ 74438889Sjdp const char *soname, *f; 74538889Sjdp struct bfd_link_needed_list *l; 74638889Sjdp 74738889Sjdp if (global_vercheck_failed) 74838889Sjdp return; 74938889Sjdp if (s->the_bfd == NULL 75038889Sjdp || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0) 75138889Sjdp return; 75238889Sjdp 75338889Sjdp soname = bfd_elf_get_dt_soname (s->the_bfd); 75438889Sjdp if (soname == NULL) 75538889Sjdp soname = bfd_get_filename (s->the_bfd); 75638889Sjdp 75738889Sjdp f = strrchr (soname, '/'); 75838889Sjdp if (f != NULL) 75938889Sjdp ++f; 76038889Sjdp else 76138889Sjdp f = soname; 76238889Sjdp 76338889Sjdp for (l = global_vercheck_needed; l != NULL; l = l->next) 76438889Sjdp { 76538889Sjdp const char *suffix; 76638889Sjdp 76738889Sjdp if (strcmp (f, l->name) == 0) 76838889Sjdp { 76938889Sjdp /* Probably can't happen, but it's an easy check. */ 77038889Sjdp continue; 77138889Sjdp } 77238889Sjdp 77338889Sjdp if (strchr (l->name, '/') != NULL) 77438889Sjdp continue; 77538889Sjdp 77638889Sjdp suffix = strstr (l->name, ".so."); 77738889Sjdp if (suffix == NULL) 77838889Sjdp continue; 77938889Sjdp 78038889Sjdp suffix += sizeof ".so." - 1; 78138889Sjdp 78238889Sjdp if (strncmp (f, l->name, suffix - l->name) == 0) 78338889Sjdp { 78438889Sjdp /* Here we know that S is a dynamic object FOO.SO.VER1, and 78538889Sjdp the object we are considering needs a dynamic object 78638889Sjdp FOO.SO.VER2, and VER1 and VER2 are different. This 78738889Sjdp appears to be a version mismatch, so we tell the caller 78838889Sjdp to try a different version of this library. */ 78938889Sjdp global_vercheck_failed = true; 79038889Sjdp return; 79138889Sjdp } 79238889Sjdp } 79338889Sjdp} 79438889Sjdp 79533965Sjdp/* This is called after the sections have been attached to output 79633965Sjdp sections, but before any sizes or addresses have been set. */ 79733965Sjdp 79833965Sjdpstatic void 79933965Sjdpgld${EMULATION_NAME}_before_allocation () 80033965Sjdp{ 80133965Sjdp const char *rpath; 80233965Sjdp asection *sinterp; 80333965Sjdp 80433965Sjdp /* If we are going to make any variable assignments, we need to let 80533965Sjdp the ELF backend know about them in case the variables are 80633965Sjdp referred to by dynamic objects. */ 80733965Sjdp lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment); 80833965Sjdp 80933965Sjdp /* Let the ELF backend work out the sizes of any sections required 81033965Sjdp by dynamic linking. */ 81133965Sjdp rpath = command_line.rpath; 81233965Sjdp if (rpath == NULL) 81333965Sjdp rpath = (const char *) getenv ("LD_RUN_PATH"); 81433965Sjdp if (! (bfd_elf${ELFSIZE}_size_dynamic_sections 81533965Sjdp (output_bfd, command_line.soname, rpath, 81633965Sjdp command_line.export_dynamic, command_line.filter_shlib, 81733965Sjdp (const char * const *) command_line.auxiliary_filters, 81833965Sjdp &link_info, &sinterp, lang_elf_version_info))) 81933965Sjdp einfo ("%P%F: failed to set dynamic section sizes: %E\n"); 82033965Sjdp 82133965Sjdp /* Let the user override the dynamic linker we are using. */ 82233965Sjdp if (command_line.interpreter != NULL 82333965Sjdp && sinterp != NULL) 82433965Sjdp { 82533965Sjdp sinterp->contents = (bfd_byte *) command_line.interpreter; 82633965Sjdp sinterp->_raw_size = strlen (command_line.interpreter) + 1; 82733965Sjdp } 82833965Sjdp 82933965Sjdp /* Look for any sections named .gnu.warning. As a GNU extensions, 83033965Sjdp we treat such sections as containing warning messages. We print 83133965Sjdp out the warning message, and then zero out the section size so 83233965Sjdp that it does not get copied into the output file. */ 83333965Sjdp 83433965Sjdp { 83533965Sjdp LANG_FOR_EACH_INPUT_STATEMENT (is) 83633965Sjdp { 83733965Sjdp asection *s; 83833965Sjdp bfd_size_type sz; 83933965Sjdp char *msg; 84033965Sjdp boolean ret; 84133965Sjdp 84233965Sjdp if (is->just_syms_flag) 84333965Sjdp continue; 84433965Sjdp 84533965Sjdp s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning"); 84633965Sjdp if (s == NULL) 84733965Sjdp continue; 84833965Sjdp 84933965Sjdp sz = bfd_section_size (is->the_bfd, s); 85033965Sjdp msg = xmalloc ((size_t) sz + 1); 85133965Sjdp if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz)) 85233965Sjdp einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", 85333965Sjdp is->the_bfd); 85433965Sjdp msg[sz] = '\0'; 85533965Sjdp ret = link_info.callbacks->warning (&link_info, msg, 85633965Sjdp (const char *) NULL, 85733965Sjdp is->the_bfd, (asection *) NULL, 85833965Sjdp (bfd_vma) 0); 85933965Sjdp ASSERT (ret); 86033965Sjdp free (msg); 86133965Sjdp 86233965Sjdp /* Clobber the section size, so that we don't waste copying the 86333965Sjdp warning into the output file. */ 86433965Sjdp s->_raw_size = 0; 86533965Sjdp } 86633965Sjdp } 86733965Sjdp} 86833965Sjdp 86933965Sjdp/* This is called by the before_allocation routine via 87033965Sjdp lang_for_each_statement. It locates any assignment statements, and 87133965Sjdp tells the ELF backend about them, in case they are assignments to 87233965Sjdp symbols which are referred to by dynamic objects. */ 87333965Sjdp 87433965Sjdpstatic void 87533965Sjdpgld${EMULATION_NAME}_find_statement_assignment (s) 87633965Sjdp lang_statement_union_type *s; 87733965Sjdp{ 87833965Sjdp if (s->header.type == lang_assignment_statement_enum) 87933965Sjdp gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); 88033965Sjdp} 88133965Sjdp 88233965Sjdp/* Look through an expression for an assignment statement. */ 88333965Sjdp 88433965Sjdpstatic void 88533965Sjdpgld${EMULATION_NAME}_find_exp_assignment (exp) 88633965Sjdp etree_type *exp; 88733965Sjdp{ 88833965Sjdp struct bfd_link_hash_entry *h; 88933965Sjdp 89033965Sjdp switch (exp->type.node_class) 89133965Sjdp { 89233965Sjdp case etree_provide: 89333965Sjdp h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, 89433965Sjdp false, false, false); 89533965Sjdp if (h == NULL) 89633965Sjdp break; 89733965Sjdp 89833965Sjdp /* We call record_link_assignment even if the symbol is defined. 89933965Sjdp This is because if it is defined by a dynamic object, we 90033965Sjdp actually want to use the value defined by the linker script, 90133965Sjdp not the value from the dynamic object (because we are setting 90233965Sjdp symbols like etext). If the symbol is defined by a regular 90333965Sjdp object, then, as it happens, calling record_link_assignment 90433965Sjdp will do no harm. */ 90533965Sjdp 90633965Sjdp /* Fall through. */ 90733965Sjdp case etree_assign: 90833965Sjdp if (strcmp (exp->assign.dst, ".") != 0) 90933965Sjdp { 91033965Sjdp if (! (bfd_elf${ELFSIZE}_record_link_assignment 91133965Sjdp (output_bfd, &link_info, exp->assign.dst, 91233965Sjdp exp->type.node_class == etree_provide ? true : false))) 91333965Sjdp einfo ("%P%F: failed to record assignment to %s: %E\n", 91433965Sjdp exp->assign.dst); 91533965Sjdp } 91633965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); 91733965Sjdp break; 91833965Sjdp 91933965Sjdp case etree_binary: 92033965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); 92133965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); 92233965Sjdp break; 92333965Sjdp 92433965Sjdp case etree_trinary: 92533965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); 92633965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); 92733965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); 92833965Sjdp break; 92933965Sjdp 93033965Sjdp case etree_unary: 93133965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); 93233965Sjdp break; 93333965Sjdp 93433965Sjdp default: 93533965Sjdp break; 93633965Sjdp } 93733965Sjdp} 93833965Sjdp 93968778Sobrien/* A variant of lang_output_section_find. Used by place_orphan. */ 94068778Sobrien 94168778Sobrienstatic lang_output_section_statement_type * 94268778Sobrienoutput_rel_find () 94368778Sobrien{ 94468778Sobrien lang_statement_union_type *u; 94568778Sobrien lang_output_section_statement_type *lookup; 94668778Sobrien 94768778Sobrien for (u = lang_output_section_statement.head; 94868778Sobrien u != (lang_statement_union_type *) NULL; 94968778Sobrien u = lookup->next) 95068778Sobrien { 95168778Sobrien lookup = &u->output_section_statement; 95268778Sobrien if (strncmp (".rel", lookup->name, 4) == 0 95368778Sobrien && lookup->bfd_section != NULL 95468778Sobrien && (lookup->bfd_section->flags & SEC_ALLOC) != 0) 95568778Sobrien { 95668778Sobrien return lookup; 95768778Sobrien } 95868778Sobrien } 95968778Sobrien return (lang_output_section_statement_type *) NULL; 96068778Sobrien} 96168778Sobrien 96233965Sjdp/* Place an orphan section. We use this to put random SHF_ALLOC 96333965Sjdp sections in the right segment. */ 96433965Sjdp 96568778Sobrienstruct orphan_save { 96668778Sobrien lang_output_section_statement_type *os; 96768778Sobrien asection **section; 96868778Sobrien lang_statement_union_type **stmt; 96968778Sobrien}; 97033965Sjdp 97133965Sjdpstatic boolean 97233965Sjdpgld${EMULATION_NAME}_place_orphan (file, s) 97333965Sjdp lang_input_statement_type *file; 97433965Sjdp asection *s; 97533965Sjdp{ 97668778Sobrien static struct orphan_save hold_text; 97768778Sobrien static struct orphan_save hold_rodata; 97868778Sobrien static struct orphan_save hold_data; 97968778Sobrien static struct orphan_save hold_bss; 98068778Sobrien static struct orphan_save hold_rel; 98168778Sobrien static struct orphan_save hold_interp; 98268778Sobrien struct orphan_save *place; 98333965Sjdp lang_statement_list_type *old; 98433965Sjdp lang_statement_list_type add; 98533965Sjdp etree_type *address; 98668778Sobrien const char *secname; 98733965Sjdp const char *outsecname; 98868778Sobrien const char *ps = NULL; 98933965Sjdp lang_output_section_statement_type *os; 99033965Sjdp 99168778Sobrien secname = bfd_get_section_name (s->owner, s); 99233965Sjdp 99368778Sobrien /* Look through the script to see where to place this section. */ 99468778Sobrien os = lang_output_section_find (secname); 99533965Sjdp 99668778Sobrien if (os != NULL 99768778Sobrien && os->bfd_section != NULL 99868778Sobrien && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0) 99933965Sjdp { 100033965Sjdp /* We have already placed a section with this name. */ 100168778Sobrien wild_doit (&os->children, s, os, file); 100233965Sjdp return true; 100333965Sjdp } 100433965Sjdp 100568778Sobrien if (hold_text.os == NULL) 100668778Sobrien hold_text.os = lang_output_section_find (".text"); 100733965Sjdp 100833965Sjdp /* If this is a final link, then always put .gnu.warning.SYMBOL 100933965Sjdp sections into the .text section to get them out of the way. */ 101033965Sjdp if (! link_info.shared 101133965Sjdp && ! link_info.relocateable 101233965Sjdp && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 101368778Sobrien && hold_text.os != NULL) 101433965Sjdp { 101568778Sobrien wild_doit (&hold_text.os->children, s, hold_text.os, file); 101633965Sjdp return true; 101733965Sjdp } 101833965Sjdp 101933965Sjdp /* Decide which segment the section should go in based on the 102033965Sjdp section name and section flags. We put loadable .note sections 102133965Sjdp right after the .interp section, so that the PT_NOTE segment is 102233965Sjdp stored right after the program headers where the OS can read it 102333965Sjdp in the first page. */ 102468778Sobrien#define HAVE_SECTION(hold, name) \ 102568778Sobrien(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL) 102668778Sobrien 102760525Sobrien if (s->flags & SEC_EXCLUDE) 102860525Sobrien return false; 102968778Sobrien 103068778Sobrien place = NULL; 103168778Sobrien if ((s->flags & SEC_ALLOC) == 0) 103268778Sobrien ; 103360525Sobrien else if ((s->flags & SEC_LOAD) != 0 103468778Sobrien && strncmp (secname, ".note", 4) == 0 103568778Sobrien && HAVE_SECTION (hold_interp, ".interp")) 103668778Sobrien place = &hold_interp; 103733965Sjdp else if ((s->flags & SEC_HAS_CONTENTS) == 0 103868778Sobrien && HAVE_SECTION (hold_bss, ".bss")) 103968778Sobrien place = &hold_bss; 104033965Sjdp else if ((s->flags & SEC_READONLY) == 0 104168778Sobrien && HAVE_SECTION (hold_data, ".data")) 104268778Sobrien place = &hold_data; 104333965Sjdp else if (strncmp (secname, ".rel", 4) == 0 104468778Sobrien && (hold_rel.os != NULL 104568778Sobrien || (hold_rel.os = output_rel_find ()) != NULL)) 104668778Sobrien place = &hold_rel; 104768778Sobrien else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY 104868778Sobrien && HAVE_SECTION (hold_rodata, ".rodata")) 104968778Sobrien place = &hold_rodata; 105068778Sobrien else if ((s->flags & (SEC_CODE | SEC_READONLY)) == (SEC_CODE | SEC_READONLY) 105168778Sobrien && hold_text.os != NULL) 105268778Sobrien place = &hold_text; 105333965Sjdp 105468778Sobrien#undef HAVE_SECTION 105568778Sobrien 105633965Sjdp /* Choose a unique name for the section. This will be needed if the 105733965Sjdp same section name appears in the input file with different 105833965Sjdp loadable or allocateable characteristics. */ 105933965Sjdp outsecname = secname; 106033965Sjdp if (bfd_get_section_by_name (output_bfd, outsecname) != NULL) 106133965Sjdp { 106233965Sjdp unsigned int len; 106333965Sjdp char *newname; 106433965Sjdp unsigned int i; 106533965Sjdp 106633965Sjdp len = strlen (outsecname); 106733965Sjdp newname = xmalloc (len + 5); 106833965Sjdp strcpy (newname, outsecname); 106933965Sjdp i = 0; 107033965Sjdp do 107133965Sjdp { 107233965Sjdp sprintf (newname + len, "%d", i); 107333965Sjdp ++i; 107433965Sjdp } 107533965Sjdp while (bfd_get_section_by_name (output_bfd, newname) != NULL); 107633965Sjdp 107733965Sjdp outsecname = newname; 107833965Sjdp } 107933965Sjdp 108068778Sobrien /* Start building a list of statements for this section. 108168778Sobrien First save the current statement pointer. */ 108268778Sobrien old = stat_ptr; 108368778Sobrien 108468778Sobrien /* If we have found an appropriate place for the output section 108568778Sobrien statements for this orphan, add them to our own private list, 108668778Sobrien inserting them later into the global statement list. */ 108768778Sobrien if (place != NULL) 108833965Sjdp { 108968778Sobrien stat_ptr = &add; 109068778Sobrien lang_list_init (stat_ptr); 109133965Sjdp } 109233965Sjdp 109368778Sobrien if (config.build_constructors) 109433965Sjdp { 109568778Sobrien /* If the name of the section is representable in C, then create 109668778Sobrien symbols to mark the start and the end of the section. */ 109768778Sobrien for (ps = outsecname; *ps != '\0'; ps++) 109868778Sobrien if (! isalnum ((unsigned char) *ps) && *ps != '_') 109968778Sobrien break; 110068778Sobrien if (*ps == '\0') 110168778Sobrien { 110268778Sobrien char *symname; 110368778Sobrien etree_type *e_align; 110433965Sjdp 110568778Sobrien symname = (char *) xmalloc (ps - outsecname + sizeof "__start_"); 110668778Sobrien sprintf (symname, "__start_%s", outsecname); 110768778Sobrien e_align = exp_unop (ALIGN_K, 110868778Sobrien exp_intop ((bfd_vma) 1 << s->alignment_power)); 110968778Sobrien lang_add_assignment (exp_assop ('=', symname, e_align)); 111068778Sobrien } 111133965Sjdp } 111233965Sjdp 111368778Sobrien if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) 111468778Sobrien address = exp_intop ((bfd_vma) 0); 111568778Sobrien else 111633965Sjdp address = NULL; 111733965Sjdp 111868778Sobrien os = lang_enter_output_section_statement (outsecname, address, 0, 111968778Sobrien (bfd_vma) 0, 112068778Sobrien (etree_type *) NULL, 112168778Sobrien (etree_type *) NULL, 112268778Sobrien (etree_type *) NULL); 112333965Sjdp 112433965Sjdp wild_doit (&os->children, s, os, file); 112533965Sjdp 112633965Sjdp lang_leave_output_section_statement 112768778Sobrien ((bfd_vma) 0, "*default*", 112868778Sobrien (struct lang_output_section_phdr_list *) NULL, "*default*"); 112933965Sjdp 113068778Sobrien if (config.build_constructors && *ps == '\0') 113133965Sjdp { 113233965Sjdp char *symname; 113333965Sjdp 113468778Sobrien /* lang_leave_ouput_section_statement resets stat_ptr. Put 113568778Sobrien stat_ptr back where we want it. */ 113668778Sobrien if (place != NULL) 113768778Sobrien stat_ptr = &add; 113868778Sobrien 113933965Sjdp symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_"); 114033965Sjdp sprintf (symname, "__stop_%s", outsecname); 114133965Sjdp lang_add_assignment (exp_assop ('=', symname, 114233965Sjdp exp_nameop (NAME, "."))); 114333965Sjdp } 114433965Sjdp 114568778Sobrien /* Restore the global list pointer. */ 114633965Sjdp stat_ptr = old; 114733965Sjdp 114868778Sobrien if (place != NULL) 114968778Sobrien { 115068778Sobrien asection *snew, **pps; 115133965Sjdp 115268778Sobrien snew = os->bfd_section; 115368778Sobrien if (place->section != NULL 115468778Sobrien || (place->os->bfd_section != NULL 115568778Sobrien && place->os->bfd_section != snew)) 115668778Sobrien { 115768778Sobrien /* Shuffle the section to make the output file look neater. 115868778Sobrien This is really only cosmetic. */ 115968778Sobrien if (place->section == NULL) 116068778Sobrien { 116168778Sobrien#if 0 116268778Sobrien /* Finding the end of the list is a little tricky. We 116368778Sobrien make a wild stab at it by comparing section flags. */ 116468778Sobrien flagword first_flags = place->os->bfd_section->flags; 116568778Sobrien for (pps = &place->os->bfd_section->next; 116668778Sobrien *pps != NULL && (*pps)->flags == first_flags; 116768778Sobrien pps = &(*pps)->next) 116868778Sobrien ; 116968778Sobrien place->section = pps; 117068778Sobrien#else 117168778Sobrien /* Put orphans after the first section on the list. */ 117268778Sobrien place->section = &place->os->bfd_section->next; 117368778Sobrien#endif 117468778Sobrien } 117533965Sjdp 117668778Sobrien /* Unlink the section. */ 117768778Sobrien for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) 117868778Sobrien ; 117968778Sobrien *pps = snew->next; 118033965Sjdp 118168778Sobrien /* Now tack it on to the "place->os" section list. */ 118268778Sobrien snew->next = *place->section; 118368778Sobrien *place->section = snew; 118468778Sobrien } 118568778Sobrien place->section = &snew->next; /* Save the end of this list. */ 118633965Sjdp 118768778Sobrien if (add.head != NULL) 118868778Sobrien { 118968778Sobrien /* We try to put the output statements in some sort of 119068778Sobrien reasonable order here, because they determine the final 119168778Sobrien load addresses of the orphan sections. */ 119268778Sobrien if (place->stmt == NULL) 119368778Sobrien { 119468778Sobrien /* Put the new statement list right at the head. */ 119568778Sobrien *add.tail = place->os->header.next; 119668778Sobrien place->os->header.next = add.head; 119768778Sobrien } 119868778Sobrien else 119968778Sobrien { 120068778Sobrien /* Put it after the last orphan statement we added. */ 120168778Sobrien *add.tail = *place->stmt; 120268778Sobrien *place->stmt = add.head; 120368778Sobrien } 120433965Sjdp 120568778Sobrien /* Fix the global list pointer if we happened to tack our 120668778Sobrien new list at the tail. */ 120768778Sobrien if (*old->tail == add.head) 120868778Sobrien old->tail = add.tail; 120968778Sobrien 121068778Sobrien /* Save the end of this list. */ 121168778Sobrien place->stmt = add.tail; 121268778Sobrien } 121368778Sobrien } 121468778Sobrien 121568778Sobrien return true; 121633965Sjdp} 121733965Sjdp 121833965Sjdpstatic char * 121933965Sjdpgld${EMULATION_NAME}_get_script(isfile) 122033965Sjdp int *isfile; 122133965SjdpEOF 122233965Sjdp 122333965Sjdpif test -n "$COMPILE_IN" 122433965Sjdpthen 122533965Sjdp# Scripts compiled in. 122633965Sjdp 122733965Sjdp# sed commands to quote an ld script as a C string. 122860525Sobriensc="-f stringify.sed" 122933965Sjdp 123033965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 123133965Sjdp{ 123233965Sjdp *isfile = 0; 123333965Sjdp 123433965Sjdp if (link_info.relocateable == true && config.build_constructors == true) 123560525Sobrien return 123633965SjdpEOF 123760525Sobriensed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c 123860525Sobrienecho ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c 123960525Sobriensed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c 124060525Sobrienecho ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c 124160525Sobriensed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c 124260525Sobrienecho ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c 124360525Sobriensed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c 124433965Sjdp 124560525Sobrienif test -n "$GENERATE_SHLIB_SCRIPT" ; then 124660525Sobrienecho ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c 124760525Sobriensed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c 124860525Sobrienfi 124960525Sobrien 125060525Sobrienecho ' ; else return' >> e${EMULATION_NAME}.c 125160525Sobriensed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c 125260525Sobrienecho '; }' >> e${EMULATION_NAME}.c 125360525Sobrien 125433965Sjdpelse 125533965Sjdp# Scripts read from the filesystem. 125633965Sjdp 125733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 125833965Sjdp{ 125933965Sjdp *isfile = 1; 126033965Sjdp 126133965Sjdp if (link_info.relocateable == true && config.build_constructors == true) 126233965Sjdp return "ldscripts/${EMULATION_NAME}.xu"; 126333965Sjdp else if (link_info.relocateable == true) 126433965Sjdp return "ldscripts/${EMULATION_NAME}.xr"; 126533965Sjdp else if (!config.text_read_only) 126633965Sjdp return "ldscripts/${EMULATION_NAME}.xbn"; 126733965Sjdp else if (!config.magic_demand_paged) 126833965Sjdp return "ldscripts/${EMULATION_NAME}.xn"; 126933965Sjdp else if (link_info.shared) 127033965Sjdp return "ldscripts/${EMULATION_NAME}.xs"; 127133965Sjdp else 127233965Sjdp return "ldscripts/${EMULATION_NAME}.x"; 127333965Sjdp} 127433965SjdpEOF 127533965Sjdp 127633965Sjdpfi 127733965Sjdp 127860525Sobrienif test -n "$PARSE_AND_LIST_ARGS" ; then 127933965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 128060525Sobrienstatic int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **)); 128160525Sobrienstatic void gld_${EMULATION_NAME}_list_options PARAMS ((FILE * file)); 128233965Sjdp 128360525Sobrien $PARSE_AND_LIST_ARGS 128460525SobrienEOF 128560525Sobrienelse 128660525Sobrien 128760525Sobriencat >>e${EMULATION_NAME}.c <<EOF 128860525Sobrien#define gld_${EMULATION_NAME}_parse_args NULL 128960525Sobrien#define gld_${EMULATION_NAME}_list_options NULL 129060525SobrienEOF 129160525Sobrien 129260525Sobrienfi 129360525Sobrien 129460525Sobriencat >>e${EMULATION_NAME}.c <<EOF 129560525Sobrien 129633965Sjdpstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 129733965Sjdp{ 129833965Sjdp gld${EMULATION_NAME}_before_parse, 129933965Sjdp syslib_default, 130033965Sjdp hll_default, 130133965Sjdp after_parse_default, 130233965Sjdp gld${EMULATION_NAME}_after_open, 130333965Sjdp after_allocation_default, 130433965Sjdp set_output_arch_default, 130533965Sjdp ldemul_default_target, 130633965Sjdp gld${EMULATION_NAME}_before_allocation, 130733965Sjdp gld${EMULATION_NAME}_get_script, 130833965Sjdp "${EMULATION_NAME}", 130933965Sjdp "${OUTPUT_FORMAT}", 131060525Sobrien NULL, /* finish */ 131160525Sobrien NULL, /* create output section statements */ 131233965Sjdp gld${EMULATION_NAME}_open_dynamic_archive, 131360525Sobrien gld${EMULATION_NAME}_place_orphan, 131460525Sobrien NULL, /* set_symbols */ 131560525Sobrien gld_${EMULATION_NAME}_parse_args, 131660525Sobrien NULL, /* unrecognized_file */ 131760525Sobrien gld_${EMULATION_NAME}_list_options, 131860525Sobrien NULL, /* recognized_file */ 131960525Sobrien NULL /* find_potential_libraries */ 132033965Sjdp}; 132133965SjdpEOF 1322