elf32.em revision 38889
133965Sjdp# This shell script emits a C file. -*- C -*- 233965Sjdp# It does some substitutions. 333965Sjdp# This file is now misnamed, because it supports both 32 bit and 64 bit 433965Sjdp# ELF emulations. 533965Sjdptest -z "${ELFSIZE}" && ELFSIZE=32 633965Sjdpcat >e${EMULATION_NAME}.c <<EOF 733965Sjdp/* This file is is generated by a shell script. DO NOT EDIT! */ 833965Sjdp 933965Sjdp/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME} 1038889Sjdp Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. 1133965Sjdp Written by Steve Chamberlain <sac@cygnus.com> 1233965Sjdp ELF support by Ian Lance Taylor <ian@cygnus.com> 1333965Sjdp 1433965SjdpThis file is part of GLD, the Gnu Linker. 1533965Sjdp 1633965SjdpThis program is free software; you can redistribute it and/or modify 1733965Sjdpit under the terms of the GNU General Public License as published by 1833965Sjdpthe Free Software Foundation; either version 2 of the License, or 1933965Sjdp(at your option) any later version. 2033965Sjdp 2133965SjdpThis program is distributed in the hope that it will be useful, 2233965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 2333965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2433965SjdpGNU General Public License for more details. 2533965Sjdp 2633965SjdpYou should have received a copy of the GNU General Public License 2733965Sjdpalong with this program; if not, write to the Free Software 2833965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2933965Sjdp 3033965Sjdp#define TARGET_IS_${EMULATION_NAME} 3133965Sjdp 3233965Sjdp#include "bfd.h" 3333965Sjdp#include "sysdep.h" 3433965Sjdp 3533965Sjdp#include <ctype.h> 3633965Sjdp 3733965Sjdp#include "bfdlink.h" 3833965Sjdp 3933965Sjdp#include "ld.h" 4033965Sjdp#include "ldmain.h" 4133965Sjdp#include "ldemul.h" 4233965Sjdp#include "ldfile.h" 4333965Sjdp#include "ldmisc.h" 4433965Sjdp#include "ldexp.h" 4533965Sjdp#include "ldlang.h" 4633965Sjdp#include "ldgram.h" 4733965Sjdp 4833965Sjdpstatic void gld${EMULATION_NAME}_before_parse PARAMS ((void)); 4933965Sjdpstatic boolean gld${EMULATION_NAME}_open_dynamic_archive 5033965Sjdp PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); 5133965Sjdpstatic void gld${EMULATION_NAME}_after_open PARAMS ((void)); 5233965Sjdpstatic void gld${EMULATION_NAME}_check_needed 5333965Sjdp PARAMS ((lang_input_statement_type *)); 5433965Sjdpstatic void gld${EMULATION_NAME}_stat_needed 5533965Sjdp PARAMS ((lang_input_statement_type *)); 5633965Sjdpstatic boolean gld${EMULATION_NAME}_search_needed 5738889Sjdp PARAMS ((const char *, const char *, int)); 5838889Sjdpstatic boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, int)); 5938889Sjdpstatic void gld${EMULATION_NAME}_vercheck 6038889Sjdp PARAMS ((lang_input_statement_type *)); 6133965Sjdpstatic void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); 6233965Sjdpstatic void gld${EMULATION_NAME}_find_statement_assignment 6333965Sjdp PARAMS ((lang_statement_union_type *)); 6433965Sjdpstatic void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); 6533965Sjdpstatic boolean gld${EMULATION_NAME}_place_orphan 6633965Sjdp PARAMS ((lang_input_statement_type *, asection *)); 6733965Sjdpstatic void gld${EMULATION_NAME}_place_section 6833965Sjdp PARAMS ((lang_statement_union_type *)); 6933965Sjdpstatic char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); 7033965Sjdp 7133965Sjdpstatic void 7233965Sjdpgld${EMULATION_NAME}_before_parse() 7333965Sjdp{ 7433965Sjdp ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; 7533965Sjdp config.dynamic_link = ${DYNAMIC_LINK-true}; 7633965Sjdp} 7733965Sjdp 7833965Sjdp/* Try to open a dynamic archive. This is where we know that ELF 7933965Sjdp dynamic libraries have an extension of .so. */ 8033965Sjdp 8133965Sjdpstatic boolean 8233965Sjdpgld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) 8333965Sjdp const char *arch; 8433965Sjdp search_dirs_type *search; 8533965Sjdp lang_input_statement_type *entry; 8633965Sjdp{ 8733965Sjdp const char *filename; 8833965Sjdp char *string; 8933965Sjdp 9033965Sjdp if (! entry->is_archive) 9133965Sjdp return false; 9233965Sjdp 9333965Sjdp filename = entry->filename; 9433965Sjdp 9533965Sjdp string = (char *) xmalloc (strlen (search->name) 9633965Sjdp + strlen (filename) 9733965Sjdp + strlen (arch) 9833965Sjdp + sizeof "/lib.so"); 9933965Sjdp 10033965Sjdp sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); 10133965Sjdp 10233965Sjdp if (! ldfile_try_open_bfd (string, entry)) 10333965Sjdp { 10433965Sjdp free (string); 10533965Sjdp return false; 10633965Sjdp } 10733965Sjdp 10833965Sjdp entry->filename = string; 10933965Sjdp 11033965Sjdp /* We have found a dynamic object to include in the link. The ELF 11133965Sjdp backend linker will create a DT_NEEDED entry in the .dynamic 11233965Sjdp section naming this file. If this file includes a DT_SONAME 11333965Sjdp entry, it will be used. Otherwise, the ELF linker will just use 11433965Sjdp the name of the file. For an archive found by searching, like 11533965Sjdp this one, the DT_NEEDED entry should consist of just the name of 11633965Sjdp the file, without the path information used to find it. Note 11733965Sjdp that we only need to do this if we have a dynamic object; an 11833965Sjdp archive will never be referenced by a DT_NEEDED entry. 11933965Sjdp 12033965Sjdp FIXME: This approach--using bfd_elf_set_dt_needed_name--is not 12133965Sjdp very pretty. I haven't been able to think of anything that is 12233965Sjdp pretty, though. */ 12333965Sjdp if (bfd_check_format (entry->the_bfd, bfd_object) 12433965Sjdp && (entry->the_bfd->flags & DYNAMIC) != 0) 12533965Sjdp { 12633965Sjdp char *needed_name; 12733965Sjdp 12833965Sjdp ASSERT (entry->is_archive && entry->search_dirs_flag); 12933965Sjdp needed_name = (char *) xmalloc (strlen (filename) 13033965Sjdp + strlen (arch) 13133965Sjdp + sizeof "lib.so"); 13233965Sjdp sprintf (needed_name, "lib%s%s.so", filename, arch); 13333965Sjdp bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name); 13433965Sjdp } 13533965Sjdp 13633965Sjdp return true; 13733965Sjdp} 13833965Sjdp 13933965SjdpEOF 14033965Sjdpif [ "x${host}" = "x${target}" ] ; then 14133965Sjdp if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then 14233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 14333965Sjdp 14433965Sjdp/* For a native linker, check the file /etc/ld.so.conf for directories 14533965Sjdp in which we may find shared libraries. /etc/ld.so.conf is really 14633965Sjdp only meaningful on Linux, but we check it on other systems anyhow. */ 14733965Sjdp 14838889Sjdpstatic boolean gld${EMULATION_NAME}_check_ld_so_conf 14938889Sjdp PARAMS ((const char *, int)); 15033965Sjdp 15133965Sjdpstatic boolean 15238889Sjdpgld${EMULATION_NAME}_check_ld_so_conf (name, force) 15333965Sjdp const char *name; 15438889Sjdp int force; 15533965Sjdp{ 15633965Sjdp static boolean initialized; 15733965Sjdp static char *ld_so_conf; 15833965Sjdp 15933965Sjdp if (! initialized) 16033965Sjdp { 16133965Sjdp FILE *f; 16233965Sjdp 16333965Sjdp f = fopen ("/etc/ld.so.conf", FOPEN_RT); 16433965Sjdp if (f != NULL) 16533965Sjdp { 16633965Sjdp char *b; 16733965Sjdp size_t len, alloc; 16833965Sjdp int c; 16933965Sjdp 17033965Sjdp len = 0; 17133965Sjdp alloc = 100; 17233965Sjdp b = (char *) xmalloc (alloc); 17333965Sjdp 17433965Sjdp while ((c = getc (f)) != EOF) 17533965Sjdp { 17633965Sjdp if (len + 1 >= alloc) 17733965Sjdp { 17833965Sjdp alloc *= 2; 17933965Sjdp b = (char *) xrealloc (b, alloc); 18033965Sjdp } 18133965Sjdp if (c != ':' 18233965Sjdp && c != ' ' 18333965Sjdp && c != '\t' 18433965Sjdp && c != '\n' 18533965Sjdp && c != ',') 18633965Sjdp { 18733965Sjdp b[len] = c; 18833965Sjdp ++len; 18933965Sjdp } 19033965Sjdp else 19133965Sjdp { 19233965Sjdp if (len > 0 && b[len - 1] != ':') 19333965Sjdp { 19433965Sjdp b[len] = ':'; 19533965Sjdp ++len; 19633965Sjdp } 19733965Sjdp } 19833965Sjdp } 19933965Sjdp 20033965Sjdp if (len > 0 && b[len - 1] == ':') 20133965Sjdp --len; 20233965Sjdp 20333965Sjdp if (len > 0) 20433965Sjdp b[len] = '\0'; 20533965Sjdp else 20633965Sjdp { 20733965Sjdp free (b); 20833965Sjdp b = NULL; 20933965Sjdp } 21033965Sjdp 21133965Sjdp fclose (f); 21233965Sjdp 21333965Sjdp ld_so_conf = b; 21433965Sjdp } 21533965Sjdp 21633965Sjdp initialized = true; 21733965Sjdp } 21833965Sjdp 21933965Sjdp if (ld_so_conf == NULL) 22033965Sjdp return false; 22133965Sjdp 22238889Sjdp return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force); 22333965Sjdp} 22433965Sjdp 22533965SjdpEOF 22633965Sjdp fi 22733965Sjdpfi 22833965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 22933965Sjdp 23033965Sjdp/* These variables are required to pass information back and forth 23138889Sjdp between after_open and check_needed and stat_needed and vercheck. */ 23233965Sjdp 23333965Sjdpstatic struct bfd_link_needed_list *global_needed; 23433965Sjdpstatic struct stat global_stat; 23533965Sjdpstatic boolean global_found; 23638889Sjdpstatic struct bfd_link_needed_list *global_vercheck_needed; 23738889Sjdpstatic boolean global_vercheck_failed; 23833965Sjdp 23933965Sjdp/* This is called after all the input files have been opened. */ 24033965Sjdp 24133965Sjdpstatic void 24233965Sjdpgld${EMULATION_NAME}_after_open () 24333965Sjdp{ 24433965Sjdp struct bfd_link_needed_list *needed, *l; 24533965Sjdp 24633965Sjdp /* We only need to worry about this when doing a final link. */ 24733965Sjdp if (link_info.relocateable || link_info.shared) 24833965Sjdp return; 24933965Sjdp 25033965Sjdp /* Get the list of files which appear in DT_NEEDED entries in 25133965Sjdp dynamic objects included in the link (often there will be none). 25233965Sjdp For each such file, we want to track down the corresponding 25333965Sjdp library, and include the symbol table in the link. This is what 25433965Sjdp the runtime dynamic linker will do. Tracking the files down here 25533965Sjdp permits one dynamic object to include another without requiring 25633965Sjdp special action by the person doing the link. Note that the 25733965Sjdp needed list can actually grow while we are stepping through this 25833965Sjdp loop. */ 25933965Sjdp needed = bfd_elf_get_needed_list (output_bfd, &link_info); 26033965Sjdp for (l = needed; l != NULL; l = l->next) 26133965Sjdp { 26233965Sjdp struct bfd_link_needed_list *ll; 26338889Sjdp int force; 26433965Sjdp 26533965Sjdp /* If we've already seen this file, skip it. */ 26633965Sjdp for (ll = needed; ll != l; ll = ll->next) 26733965Sjdp if (strcmp (ll->name, l->name) == 0) 26833965Sjdp break; 26933965Sjdp if (ll != l) 27033965Sjdp continue; 27133965Sjdp 27233965Sjdp /* See if this file was included in the link explicitly. */ 27333965Sjdp global_needed = l; 27433965Sjdp global_found = false; 27533965Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); 27633965Sjdp if (global_found) 27733965Sjdp continue; 27833965Sjdp 27933965Sjdp /* We need to find this file and include the symbol table. We 28033965Sjdp want to search for the file in the same way that the dynamic 28133965Sjdp linker will search. That means that we want to use 28233965Sjdp rpath_link, rpath, then the environment variable 28333965Sjdp LD_LIBRARY_PATH (native only), then the linker script 28438889Sjdp LIB_SEARCH_DIRS. We do not search using the -L arguments. 28538889Sjdp 28638889Sjdp We search twice. The first time, we skip objects which may 28738889Sjdp introduce version mismatches. The second time, we force 28838889Sjdp their use. See gld${EMULATION_NAME}_vercheck comment. */ 28938889Sjdp for (force = 0; force < 2; force++) 29033965Sjdp { 29138889Sjdp const char *lib_path; 29238889Sjdp size_t len; 29338889Sjdp search_dirs_type *search; 29438889Sjdp 29538889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, 29638889Sjdp l->name, force)) 29738889Sjdp break; 29838889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath, 29938889Sjdp l->name, force)) 30038889Sjdp break; 30138889Sjdp if (command_line.rpath_link == NULL 30238889Sjdp && command_line.rpath == NULL) 30338889Sjdp { 30438889Sjdp lib_path = (const char *) getenv ("LD_RUN_PATH"); 30538889Sjdp if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, 30638889Sjdp force)) 30738889Sjdp break; 30838889Sjdp } 30933965SjdpEOF 31033965Sjdpif [ "x${host}" = "x${target}" ] ; then 31133965Sjdp if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then 31233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 31338889Sjdp lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); 31438889Sjdp if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force)) 31538889Sjdp break; 31633965SjdpEOF 31733965Sjdp fi 31833965Sjdpfi 31933965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 32038889Sjdp len = strlen (l->name); 32138889Sjdp for (search = search_head; search != NULL; search = search->next) 32238889Sjdp { 32338889Sjdp char *filename; 32433965Sjdp 32538889Sjdp if (search->cmdline) 32638889Sjdp continue; 32738889Sjdp filename = (char *) xmalloc (strlen (search->name) + len + 2); 32838889Sjdp sprintf (filename, "%s/%s", search->name, l->name); 32938889Sjdp if (gld${EMULATION_NAME}_try_needed (filename, force)) 33038889Sjdp break; 33138889Sjdp free (filename); 33238889Sjdp } 33338889Sjdp if (search != NULL) 33433965Sjdp break; 33533965SjdpEOF 33633965Sjdpif [ "x${host}" = "x${target}" ] ; then 33733965Sjdp if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then 33833965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 33938889Sjdp if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force)) 34038889Sjdp break; 34133965SjdpEOF 34233965Sjdp fi 34333965Sjdpfi 34433965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 34538889Sjdp } 34633965Sjdp 34738889Sjdp if (force < 2) 34838889Sjdp continue; 34938889Sjdp 35033965Sjdp einfo ("%P: warning: %s, needed by %B, not found (try using --rpath)\n", 35133965Sjdp l->name, l->by); 35233965Sjdp } 35333965Sjdp} 35433965Sjdp 35533965Sjdp/* Search for a needed file in a path. */ 35633965Sjdp 35733965Sjdpstatic boolean 35838889Sjdpgld${EMULATION_NAME}_search_needed (path, name, force) 35933965Sjdp const char *path; 36033965Sjdp const char *name; 36138889Sjdp int force; 36233965Sjdp{ 36333965Sjdp const char *s; 36433965Sjdp size_t len; 36533965Sjdp 36633965Sjdp if (path == NULL || *path == '\0') 36733965Sjdp return false; 36833965Sjdp len = strlen (name); 36933965Sjdp while (1) 37033965Sjdp { 37133965Sjdp char *filename, *sset; 37233965Sjdp 37333965Sjdp s = strchr (path, ':'); 37433965Sjdp if (s == NULL) 37533965Sjdp s = path + strlen (path); 37633965Sjdp 37733965Sjdp filename = (char *) xmalloc (s - path + len + 2); 37833965Sjdp if (s == path) 37933965Sjdp sset = filename; 38033965Sjdp else 38133965Sjdp { 38233965Sjdp memcpy (filename, path, s - path); 38333965Sjdp filename[s - path] = '/'; 38433965Sjdp sset = filename + (s - path) + 1; 38533965Sjdp } 38633965Sjdp strcpy (sset, name); 38733965Sjdp 38838889Sjdp if (gld${EMULATION_NAME}_try_needed (filename, force)) 38933965Sjdp return true; 39033965Sjdp 39133965Sjdp free (filename); 39233965Sjdp 39333965Sjdp if (*s == '\0') 39433965Sjdp break; 39533965Sjdp path = s + 1; 39633965Sjdp } 39733965Sjdp 39833965Sjdp return false; 39933965Sjdp} 40033965Sjdp 40133965Sjdp/* This function is called for each possible name for a dynamic object 40238889Sjdp named by a DT_NEEDED entry. The FORCE parameter indicates whether 40338889Sjdp to skip the check for a conflicting version. */ 40433965Sjdp 40533965Sjdpstatic boolean 40638889Sjdpgld${EMULATION_NAME}_try_needed (name, force) 40733965Sjdp const char *name; 40838889Sjdp int force; 40933965Sjdp{ 41033965Sjdp bfd *abfd; 41133965Sjdp 41233965Sjdp abfd = bfd_openr (name, bfd_get_target (output_bfd)); 41333965Sjdp if (abfd == NULL) 41433965Sjdp return false; 41533965Sjdp if (! bfd_check_format (abfd, bfd_object)) 41633965Sjdp { 41733965Sjdp (void) bfd_close (abfd); 41833965Sjdp return false; 41933965Sjdp } 42033965Sjdp if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) 42133965Sjdp { 42233965Sjdp (void) bfd_close (abfd); 42333965Sjdp return false; 42433965Sjdp } 42533965Sjdp 42638889Sjdp /* Check whether this object would include any conflicting library 42738889Sjdp versions. If FORCE is set, then we skip this check; we use this 42838889Sjdp the second time around, if we couldn't find any compatible 42938889Sjdp instance of the shared library. */ 43038889Sjdp 43138889Sjdp if (! force) 43238889Sjdp { 43338889Sjdp struct bfd_link_needed_list *needed; 43438889Sjdp 43538889Sjdp if (! bfd_elf_get_bfd_needed_list (abfd, &needed)) 43638889Sjdp einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd); 43738889Sjdp 43838889Sjdp if (needed != NULL) 43938889Sjdp { 44038889Sjdp global_vercheck_needed = needed; 44138889Sjdp global_vercheck_failed = false; 44238889Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_vercheck); 44338889Sjdp if (global_vercheck_failed) 44438889Sjdp { 44538889Sjdp (void) bfd_close (abfd); 44638889Sjdp /* Return false to force the caller to move on to try 44738889Sjdp another file on the search path. */ 44838889Sjdp return false; 44938889Sjdp } 45038889Sjdp 45138889Sjdp /* But wait! It gets much worse. On Linux, if a shared 45238889Sjdp library does not use libc at all, we are supposed to skip 45338889Sjdp it the first time around in case we encounter a shared 45438889Sjdp library later on with the same name which does use the 45538889Sjdp version of libc that we want. This is much too horrible 45638889Sjdp to use on any system other than Linux. */ 45738889Sjdp 45838889SjdpEOF 45938889Sjdpcase ${target} in 46038889Sjdp *-*-linux-gnu*) 46138889Sjdp cat >>e${EMULATION_NAME}.c <<EOF 46238889Sjdp { 46338889Sjdp struct bfd_link_needed_list *l; 46438889Sjdp 46538889Sjdp for (l = needed; l != NULL; l = l->next) 46638889Sjdp if (strncmp (l->name, "libc.so", 7) == 0) 46738889Sjdp break; 46838889Sjdp if (l == NULL) 46938889Sjdp { 47038889Sjdp (void) bfd_close (abfd); 47138889Sjdp return false; 47238889Sjdp } 47338889Sjdp } 47438889Sjdp 47538889SjdpEOF 47638889Sjdp ;; 47738889Sjdpesac 47838889Sjdpcat >>e${EMULATION_NAME}.c <<EOF 47938889Sjdp } 48038889Sjdp } 48138889Sjdp 48233965Sjdp /* We've found a dynamic object matching the DT_NEEDED entry. */ 48333965Sjdp 48433965Sjdp /* We have already checked that there is no other input file of the 48533965Sjdp same name. We must now check again that we are not including the 48633965Sjdp same file twice. We need to do this because on many systems 48733965Sjdp libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will 48833965Sjdp reference libc.so.1. If we have already included libc.so, we 48933965Sjdp don't want to include libc.so.1 if they are the same file, and we 49033965Sjdp can only check that using stat. */ 49133965Sjdp 49233965Sjdp if (bfd_stat (abfd, &global_stat) != 0) 49333965Sjdp einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd); 49433965Sjdp global_found = false; 49533965Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed); 49633965Sjdp if (global_found) 49733965Sjdp { 49833965Sjdp /* Return true to indicate that we found the file, even though 49933965Sjdp we aren't going to do anything with it. */ 50033965Sjdp return true; 50133965Sjdp } 50233965Sjdp 50333965Sjdp /* Tell the ELF backend that don't want the output file to have a 50433965Sjdp DT_NEEDED entry for this file. */ 50533965Sjdp bfd_elf_set_dt_needed_name (abfd, ""); 50633965Sjdp 50733965Sjdp /* Add this file into the symbol table. */ 50833965Sjdp if (! bfd_link_add_symbols (abfd, &link_info)) 50933965Sjdp einfo ("%F%B: could not read symbols: %E\n", abfd); 51033965Sjdp 51133965Sjdp return true; 51233965Sjdp} 51333965Sjdp 51433965Sjdp/* See if an input file matches a DT_NEEDED entry by name. */ 51533965Sjdp 51633965Sjdpstatic void 51733965Sjdpgld${EMULATION_NAME}_check_needed (s) 51833965Sjdp lang_input_statement_type *s; 51933965Sjdp{ 52033965Sjdp if (global_found) 52133965Sjdp return; 52233965Sjdp 52333965Sjdp if (s->filename != NULL 52433965Sjdp && strcmp (s->filename, global_needed->name) == 0) 52533965Sjdp { 52633965Sjdp global_found = true; 52733965Sjdp return; 52833965Sjdp } 52933965Sjdp 53033965Sjdp if (s->the_bfd != NULL) 53133965Sjdp { 53233965Sjdp const char *soname; 53333965Sjdp 53433965Sjdp soname = bfd_elf_get_dt_soname (s->the_bfd); 53533965Sjdp if (soname != NULL 53633965Sjdp && strcmp (soname, global_needed->name) == 0) 53733965Sjdp { 53833965Sjdp global_found = true; 53933965Sjdp return; 54033965Sjdp } 54133965Sjdp } 54233965Sjdp 54333965Sjdp if (s->search_dirs_flag 54433965Sjdp && s->filename != NULL 54533965Sjdp && strchr (global_needed->name, '/') == NULL) 54633965Sjdp { 54733965Sjdp const char *f; 54833965Sjdp 54933965Sjdp f = strrchr (s->filename, '/'); 55033965Sjdp if (f != NULL 55133965Sjdp && strcmp (f + 1, global_needed->name) == 0) 55233965Sjdp { 55333965Sjdp global_found = true; 55433965Sjdp return; 55533965Sjdp } 55633965Sjdp } 55733965Sjdp} 55833965Sjdp 55933965Sjdp/* See if an input file matches a DT_NEEDED entry by running stat on 56033965Sjdp the file. */ 56133965Sjdp 56233965Sjdpstatic void 56333965Sjdpgld${EMULATION_NAME}_stat_needed (s) 56433965Sjdp lang_input_statement_type *s; 56533965Sjdp{ 56633965Sjdp struct stat st; 56733965Sjdp const char *suffix; 56833965Sjdp const char *soname; 56933965Sjdp const char *f; 57033965Sjdp 57133965Sjdp if (global_found) 57233965Sjdp return; 57333965Sjdp if (s->the_bfd == NULL) 57433965Sjdp return; 57533965Sjdp 57633965Sjdp if (bfd_stat (s->the_bfd, &st) != 0) 57733965Sjdp { 57833965Sjdp einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd); 57933965Sjdp return; 58033965Sjdp } 58133965Sjdp 58233965Sjdp if (st.st_dev == global_stat.st_dev 58333965Sjdp && st.st_ino == global_stat.st_ino) 58433965Sjdp { 58533965Sjdp global_found = true; 58633965Sjdp return; 58733965Sjdp } 58833965Sjdp 58933965Sjdp /* We issue a warning if it looks like we are including two 59033965Sjdp different versions of the same shared library. For example, 59133965Sjdp there may be a problem if -lc picks up libc.so.6 but some other 59233965Sjdp shared library has a DT_NEEDED entry of libc.so.5. This is a 59333965Sjdp hueristic test, and it will only work if the name looks like 59433965Sjdp NAME.so.VERSION. FIXME: Depending on file names is error-prone. 59533965Sjdp If we really want to issue warnings about mixing version numbers 59633965Sjdp of shared libraries, we need to find a better way. */ 59733965Sjdp 59833965Sjdp if (strchr (global_needed->name, '/') != NULL) 59933965Sjdp return; 60033965Sjdp suffix = strstr (global_needed->name, ".so."); 60133965Sjdp if (suffix == NULL) 60233965Sjdp return; 60333965Sjdp suffix += sizeof ".so." - 1; 60433965Sjdp 60533965Sjdp soname = bfd_elf_get_dt_soname (s->the_bfd); 60633965Sjdp if (soname == NULL) 60733965Sjdp soname = s->filename; 60833965Sjdp 60933965Sjdp f = strrchr (soname, '/'); 61033965Sjdp if (f != NULL) 61133965Sjdp ++f; 61233965Sjdp else 61333965Sjdp f = soname; 61433965Sjdp 61533965Sjdp if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0) 61633965Sjdp einfo ("%P: warning: %s, needed by %B, may conflict with %s\n", 61733965Sjdp global_needed->name, global_needed->by, f); 61833965Sjdp} 61933965Sjdp 62038889Sjdp/* On Linux, it's possible to have different versions of the same 62138889Sjdp shared library linked against different versions of libc. The 62238889Sjdp dynamic linker somehow tags which libc version to use in 62338889Sjdp /etc/ld.so.cache, and, based on the libc that it sees in the 62438889Sjdp executable, chooses which version of the shared library to use. 62538889Sjdp 62638889Sjdp We try to do a similar check here by checking whether this shared 62738889Sjdp library needs any other shared libraries which may conflict with 62838889Sjdp libraries we have already included in the link. If it does, we 62938889Sjdp skip it, and try to find another shared library farther on down the 63038889Sjdp link path. 63138889Sjdp 63238889Sjdp This is called via lang_for_each_input_file. 63338889Sjdp GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object 63438889Sjdp which we ar checking. This sets GLOBAL_VERCHECK_FAILED if we find 63538889Sjdp a conflicting version. */ 63638889Sjdp 63738889Sjdpstatic void 63838889Sjdpgld${EMULATION_NAME}_vercheck (s) 63938889Sjdp lang_input_statement_type *s; 64038889Sjdp{ 64138889Sjdp const char *soname, *f; 64238889Sjdp struct bfd_link_needed_list *l; 64338889Sjdp 64438889Sjdp if (global_vercheck_failed) 64538889Sjdp return; 64638889Sjdp if (s->the_bfd == NULL 64738889Sjdp || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0) 64838889Sjdp return; 64938889Sjdp 65038889Sjdp soname = bfd_elf_get_dt_soname (s->the_bfd); 65138889Sjdp if (soname == NULL) 65238889Sjdp soname = bfd_get_filename (s->the_bfd); 65338889Sjdp 65438889Sjdp f = strrchr (soname, '/'); 65538889Sjdp if (f != NULL) 65638889Sjdp ++f; 65738889Sjdp else 65838889Sjdp f = soname; 65938889Sjdp 66038889Sjdp for (l = global_vercheck_needed; l != NULL; l = l->next) 66138889Sjdp { 66238889Sjdp const char *suffix; 66338889Sjdp 66438889Sjdp if (strcmp (f, l->name) == 0) 66538889Sjdp { 66638889Sjdp /* Probably can't happen, but it's an easy check. */ 66738889Sjdp continue; 66838889Sjdp } 66938889Sjdp 67038889Sjdp if (strchr (l->name, '/') != NULL) 67138889Sjdp continue; 67238889Sjdp 67338889Sjdp suffix = strstr (l->name, ".so."); 67438889Sjdp if (suffix == NULL) 67538889Sjdp continue; 67638889Sjdp 67738889Sjdp suffix += sizeof ".so." - 1; 67838889Sjdp 67938889Sjdp if (strncmp (f, l->name, suffix - l->name) == 0) 68038889Sjdp { 68138889Sjdp /* Here we know that S is a dynamic object FOO.SO.VER1, and 68238889Sjdp the object we are considering needs a dynamic object 68338889Sjdp FOO.SO.VER2, and VER1 and VER2 are different. This 68438889Sjdp appears to be a version mismatch, so we tell the caller 68538889Sjdp to try a different version of this library. */ 68638889Sjdp global_vercheck_failed = true; 68738889Sjdp return; 68838889Sjdp } 68938889Sjdp } 69038889Sjdp} 69138889Sjdp 69233965Sjdp/* This is called after the sections have been attached to output 69333965Sjdp sections, but before any sizes or addresses have been set. */ 69433965Sjdp 69533965Sjdpstatic void 69633965Sjdpgld${EMULATION_NAME}_before_allocation () 69733965Sjdp{ 69833965Sjdp const char *rpath; 69933965Sjdp asection *sinterp; 70033965Sjdp 70133965Sjdp /* If we are going to make any variable assignments, we need to let 70233965Sjdp the ELF backend know about them in case the variables are 70333965Sjdp referred to by dynamic objects. */ 70433965Sjdp lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment); 70533965Sjdp 70633965Sjdp /* Let the ELF backend work out the sizes of any sections required 70733965Sjdp by dynamic linking. */ 70833965Sjdp rpath = command_line.rpath; 70933965Sjdp if (rpath == NULL) 71033965Sjdp rpath = (const char *) getenv ("LD_RUN_PATH"); 71133965Sjdp if (! (bfd_elf${ELFSIZE}_size_dynamic_sections 71233965Sjdp (output_bfd, command_line.soname, rpath, 71333965Sjdp command_line.export_dynamic, command_line.filter_shlib, 71433965Sjdp (const char * const *) command_line.auxiliary_filters, 71533965Sjdp &link_info, &sinterp, lang_elf_version_info))) 71633965Sjdp einfo ("%P%F: failed to set dynamic section sizes: %E\n"); 71733965Sjdp 71833965Sjdp /* Let the user override the dynamic linker we are using. */ 71933965Sjdp if (command_line.interpreter != NULL 72033965Sjdp && sinterp != NULL) 72133965Sjdp { 72233965Sjdp sinterp->contents = (bfd_byte *) command_line.interpreter; 72333965Sjdp sinterp->_raw_size = strlen (command_line.interpreter) + 1; 72433965Sjdp } 72533965Sjdp 72633965Sjdp /* Look for any sections named .gnu.warning. As a GNU extensions, 72733965Sjdp we treat such sections as containing warning messages. We print 72833965Sjdp out the warning message, and then zero out the section size so 72933965Sjdp that it does not get copied into the output file. */ 73033965Sjdp 73133965Sjdp { 73233965Sjdp LANG_FOR_EACH_INPUT_STATEMENT (is) 73333965Sjdp { 73433965Sjdp asection *s; 73533965Sjdp bfd_size_type sz; 73633965Sjdp char *msg; 73733965Sjdp boolean ret; 73833965Sjdp 73933965Sjdp if (is->just_syms_flag) 74033965Sjdp continue; 74133965Sjdp 74233965Sjdp s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning"); 74333965Sjdp if (s == NULL) 74433965Sjdp continue; 74533965Sjdp 74633965Sjdp sz = bfd_section_size (is->the_bfd, s); 74733965Sjdp msg = xmalloc ((size_t) sz + 1); 74833965Sjdp if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz)) 74933965Sjdp einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", 75033965Sjdp is->the_bfd); 75133965Sjdp msg[sz] = '\0'; 75233965Sjdp ret = link_info.callbacks->warning (&link_info, msg, 75333965Sjdp (const char *) NULL, 75433965Sjdp is->the_bfd, (asection *) NULL, 75533965Sjdp (bfd_vma) 0); 75633965Sjdp ASSERT (ret); 75733965Sjdp free (msg); 75833965Sjdp 75933965Sjdp /* Clobber the section size, so that we don't waste copying the 76033965Sjdp warning into the output file. */ 76133965Sjdp s->_raw_size = 0; 76233965Sjdp } 76333965Sjdp } 76433965Sjdp 76533965Sjdp#if defined (TARGET_IS_elf32bmip) || defined (TARGET_IS_elf32lmip) 76633965Sjdp /* For MIPS ELF the .reginfo section requires special handling. 76733965Sjdp Each input section is 24 bytes, and the final output section must 76833965Sjdp also be 24 bytes. We handle this by clobbering all but the first 76933965Sjdp input section size to 0. The .reginfo section is handled 77033965Sjdp specially by the backend code anyhow. */ 77133965Sjdp { 77233965Sjdp boolean found = false; 77333965Sjdp LANG_FOR_EACH_INPUT_STATEMENT (is) 77433965Sjdp { 77533965Sjdp asection *s; 77633965Sjdp 77733965Sjdp if (is->just_syms_flag) 77833965Sjdp continue; 77933965Sjdp 78033965Sjdp s = bfd_get_section_by_name (is->the_bfd, ".reginfo"); 78133965Sjdp if (s == NULL) 78233965Sjdp continue; 78333965Sjdp 78433965Sjdp if (! found) 78533965Sjdp { 78633965Sjdp found = true; 78733965Sjdp continue; 78833965Sjdp } 78933965Sjdp 79033965Sjdp s->_raw_size = 0; 79133965Sjdp s->_cooked_size = 0; 79233965Sjdp } 79333965Sjdp } 79433965Sjdp#endif 79533965Sjdp} 79633965Sjdp 79733965Sjdp/* This is called by the before_allocation routine via 79833965Sjdp lang_for_each_statement. It locates any assignment statements, and 79933965Sjdp tells the ELF backend about them, in case they are assignments to 80033965Sjdp symbols which are referred to by dynamic objects. */ 80133965Sjdp 80233965Sjdpstatic void 80333965Sjdpgld${EMULATION_NAME}_find_statement_assignment (s) 80433965Sjdp lang_statement_union_type *s; 80533965Sjdp{ 80633965Sjdp if (s->header.type == lang_assignment_statement_enum) 80733965Sjdp gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); 80833965Sjdp} 80933965Sjdp 81033965Sjdp/* Look through an expression for an assignment statement. */ 81133965Sjdp 81233965Sjdpstatic void 81333965Sjdpgld${EMULATION_NAME}_find_exp_assignment (exp) 81433965Sjdp etree_type *exp; 81533965Sjdp{ 81633965Sjdp struct bfd_link_hash_entry *h; 81733965Sjdp 81833965Sjdp switch (exp->type.node_class) 81933965Sjdp { 82033965Sjdp case etree_provide: 82133965Sjdp h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, 82233965Sjdp false, false, false); 82333965Sjdp if (h == NULL) 82433965Sjdp break; 82533965Sjdp 82633965Sjdp /* We call record_link_assignment even if the symbol is defined. 82733965Sjdp This is because if it is defined by a dynamic object, we 82833965Sjdp actually want to use the value defined by the linker script, 82933965Sjdp not the value from the dynamic object (because we are setting 83033965Sjdp symbols like etext). If the symbol is defined by a regular 83133965Sjdp object, then, as it happens, calling record_link_assignment 83233965Sjdp will do no harm. */ 83333965Sjdp 83433965Sjdp /* Fall through. */ 83533965Sjdp case etree_assign: 83633965Sjdp if (strcmp (exp->assign.dst, ".") != 0) 83733965Sjdp { 83833965Sjdp if (! (bfd_elf${ELFSIZE}_record_link_assignment 83933965Sjdp (output_bfd, &link_info, exp->assign.dst, 84033965Sjdp exp->type.node_class == etree_provide ? true : false))) 84133965Sjdp einfo ("%P%F: failed to record assignment to %s: %E\n", 84233965Sjdp exp->assign.dst); 84333965Sjdp } 84433965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); 84533965Sjdp break; 84633965Sjdp 84733965Sjdp case etree_binary: 84833965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); 84933965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); 85033965Sjdp break; 85133965Sjdp 85233965Sjdp case etree_trinary: 85333965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); 85433965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); 85533965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); 85633965Sjdp break; 85733965Sjdp 85833965Sjdp case etree_unary: 85933965Sjdp gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); 86033965Sjdp break; 86133965Sjdp 86233965Sjdp default: 86333965Sjdp break; 86433965Sjdp } 86533965Sjdp} 86633965Sjdp 86733965Sjdp/* Place an orphan section. We use this to put random SHF_ALLOC 86833965Sjdp sections in the right segment. */ 86933965Sjdp 87033965Sjdpstatic asection *hold_section; 87133965Sjdpstatic lang_output_section_statement_type *hold_use; 87233965Sjdpstatic lang_output_section_statement_type *hold_text; 87333965Sjdpstatic lang_output_section_statement_type *hold_rodata; 87433965Sjdpstatic lang_output_section_statement_type *hold_data; 87533965Sjdpstatic lang_output_section_statement_type *hold_bss; 87633965Sjdpstatic lang_output_section_statement_type *hold_rel; 87733965Sjdpstatic lang_output_section_statement_type *hold_interp; 87833965Sjdp 87933965Sjdp/*ARGSUSED*/ 88033965Sjdpstatic boolean 88133965Sjdpgld${EMULATION_NAME}_place_orphan (file, s) 88233965Sjdp lang_input_statement_type *file; 88333965Sjdp asection *s; 88433965Sjdp{ 88533965Sjdp lang_output_section_statement_type *place; 88633965Sjdp asection *snew, **pps; 88733965Sjdp lang_statement_list_type *old; 88833965Sjdp lang_statement_list_type add; 88933965Sjdp etree_type *address; 89033965Sjdp const char *secname, *ps; 89133965Sjdp const char *outsecname; 89233965Sjdp lang_output_section_statement_type *os; 89333965Sjdp 89433965Sjdp if ((s->flags & SEC_ALLOC) == 0) 89533965Sjdp return false; 89633965Sjdp 89733965Sjdp /* Look through the script to see where to place this section. */ 89833965Sjdp hold_section = s; 89933965Sjdp hold_use = NULL; 90033965Sjdp lang_for_each_statement (gld${EMULATION_NAME}_place_section); 90133965Sjdp 90233965Sjdp if (hold_use != NULL) 90333965Sjdp { 90433965Sjdp /* We have already placed a section with this name. */ 90533965Sjdp wild_doit (&hold_use->children, s, hold_use, file); 90633965Sjdp return true; 90733965Sjdp } 90833965Sjdp 90933965Sjdp secname = bfd_get_section_name (s->owner, s); 91033965Sjdp 91133965Sjdp /* If this is a final link, then always put .gnu.warning.SYMBOL 91233965Sjdp sections into the .text section to get them out of the way. */ 91333965Sjdp if (! link_info.shared 91433965Sjdp && ! link_info.relocateable 91533965Sjdp && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 91633965Sjdp && hold_text != NULL) 91733965Sjdp { 91833965Sjdp wild_doit (&hold_text->children, s, hold_text, file); 91933965Sjdp return true; 92033965Sjdp } 92133965Sjdp 92233965Sjdp /* Decide which segment the section should go in based on the 92333965Sjdp section name and section flags. We put loadable .note sections 92433965Sjdp right after the .interp section, so that the PT_NOTE segment is 92533965Sjdp stored right after the program headers where the OS can read it 92633965Sjdp in the first page. */ 92733965Sjdp place = NULL; 92833965Sjdp if ((s->flags & SEC_LOAD) != 0 92933965Sjdp && strncmp (secname, ".note", 4) == 0 93033965Sjdp && hold_interp != NULL) 93133965Sjdp place = hold_interp; 93233965Sjdp else if ((s->flags & SEC_HAS_CONTENTS) == 0 93333965Sjdp && hold_bss != NULL) 93433965Sjdp place = hold_bss; 93533965Sjdp else if ((s->flags & SEC_READONLY) == 0 93633965Sjdp && hold_data != NULL) 93733965Sjdp place = hold_data; 93833965Sjdp else if (strncmp (secname, ".rel", 4) == 0 93933965Sjdp && hold_rel != NULL) 94033965Sjdp place = hold_rel; 94133965Sjdp else if ((s->flags & SEC_CODE) == 0 94233965Sjdp && (s->flags & SEC_READONLY) != 0 94333965Sjdp && hold_rodata != NULL) 94433965Sjdp place = hold_rodata; 94533965Sjdp else if ((s->flags & SEC_READONLY) != 0 94633965Sjdp && hold_text != NULL) 94733965Sjdp place = hold_text; 94833965Sjdp if (place == NULL) 94933965Sjdp return false; 95033965Sjdp 95133965Sjdp /* Choose a unique name for the section. This will be needed if the 95233965Sjdp same section name appears in the input file with different 95333965Sjdp loadable or allocateable characteristics. */ 95433965Sjdp outsecname = secname; 95533965Sjdp if (bfd_get_section_by_name (output_bfd, outsecname) != NULL) 95633965Sjdp { 95733965Sjdp unsigned int len; 95833965Sjdp char *newname; 95933965Sjdp unsigned int i; 96033965Sjdp 96133965Sjdp len = strlen (outsecname); 96233965Sjdp newname = xmalloc (len + 5); 96333965Sjdp strcpy (newname, outsecname); 96433965Sjdp i = 0; 96533965Sjdp do 96633965Sjdp { 96733965Sjdp sprintf (newname + len, "%d", i); 96833965Sjdp ++i; 96933965Sjdp } 97033965Sjdp while (bfd_get_section_by_name (output_bfd, newname) != NULL); 97133965Sjdp 97233965Sjdp outsecname = newname; 97333965Sjdp } 97433965Sjdp 97533965Sjdp /* Create the section in the output file, and put it in the right 97633965Sjdp place. This shuffling is to make the output file look neater. */ 97733965Sjdp snew = bfd_make_section (output_bfd, outsecname); 97833965Sjdp if (snew == NULL) 97933965Sjdp einfo ("%P%F: output format %s cannot represent section called %s\n", 98033965Sjdp output_bfd->xvec->name, outsecname); 98133965Sjdp if (place->bfd_section != NULL) 98233965Sjdp { 98333965Sjdp for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) 98433965Sjdp ; 98533965Sjdp *pps = snew->next; 98633965Sjdp snew->next = place->bfd_section->next; 98733965Sjdp place->bfd_section->next = snew; 98833965Sjdp } 98933965Sjdp 99033965Sjdp /* Start building a list of statements for this section. */ 99133965Sjdp old = stat_ptr; 99233965Sjdp stat_ptr = &add; 99333965Sjdp lang_list_init (stat_ptr); 99433965Sjdp 99533965Sjdp /* If the name of the section is representable in C, then create 99633965Sjdp symbols to mark the start and the end of the section. */ 99733965Sjdp for (ps = outsecname; *ps != '\0'; ps++) 99838889Sjdp if (! isalnum ((unsigned char) *ps) && *ps != '_') 99933965Sjdp break; 100033965Sjdp if (*ps == '\0' && config.build_constructors) 100133965Sjdp { 100233965Sjdp char *symname; 100333965Sjdp 100433965Sjdp symname = (char *) xmalloc (ps - outsecname + sizeof "__start_"); 100533965Sjdp sprintf (symname, "__start_%s", outsecname); 100633965Sjdp lang_add_assignment (exp_assop ('=', symname, 100733965Sjdp exp_unop (ALIGN_K, 100833965Sjdp exp_intop ((bfd_vma) 1 100933965Sjdp << s->alignment_power)))); 101033965Sjdp } 101133965Sjdp 101233965Sjdp if (! link_info.relocateable) 101333965Sjdp address = NULL; 101433965Sjdp else 101533965Sjdp address = exp_intop ((bfd_vma) 0); 101633965Sjdp 101733965Sjdp lang_enter_output_section_statement (outsecname, address, 0, 101833965Sjdp (bfd_vma) 0, 101933965Sjdp (etree_type *) NULL, 102033965Sjdp (etree_type *) NULL, 102133965Sjdp (etree_type *) NULL); 102233965Sjdp 102333965Sjdp os = lang_output_section_statement_lookup (outsecname); 102433965Sjdp wild_doit (&os->children, s, os, file); 102533965Sjdp 102633965Sjdp lang_leave_output_section_statement 102733965Sjdp ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL); 102833965Sjdp stat_ptr = &add; 102933965Sjdp 103033965Sjdp if (*ps == '\0' && config.build_constructors) 103133965Sjdp { 103233965Sjdp char *symname; 103333965Sjdp 103433965Sjdp symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_"); 103533965Sjdp sprintf (symname, "__stop_%s", outsecname); 103633965Sjdp lang_add_assignment (exp_assop ('=', symname, 103733965Sjdp exp_nameop (NAME, "."))); 103833965Sjdp } 103933965Sjdp 104033965Sjdp /* Now stick the new statement list right after PLACE. */ 104133965Sjdp *add.tail = place->header.next; 104233965Sjdp place->header.next = add.head; 104333965Sjdp 104433965Sjdp stat_ptr = old; 104533965Sjdp 104633965Sjdp return true; 104733965Sjdp} 104833965Sjdp 104933965Sjdpstatic void 105033965Sjdpgld${EMULATION_NAME}_place_section (s) 105133965Sjdp lang_statement_union_type *s; 105233965Sjdp{ 105333965Sjdp lang_output_section_statement_type *os; 105433965Sjdp 105533965Sjdp if (s->header.type != lang_output_section_statement_enum) 105633965Sjdp return; 105733965Sjdp 105833965Sjdp os = &s->output_section_statement; 105933965Sjdp 106033965Sjdp if (strcmp (os->name, hold_section->name) == 0 106138889Sjdp && os->bfd_section != NULL 106233965Sjdp && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC)) 106333965Sjdp == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC)))) 106433965Sjdp hold_use = os; 106533965Sjdp 106633965Sjdp if (strcmp (os->name, ".text") == 0) 106733965Sjdp hold_text = os; 106833965Sjdp else if (strcmp (os->name, ".rodata") == 0) 106933965Sjdp hold_rodata = os; 107033965Sjdp else if (strcmp (os->name, ".data") == 0) 107133965Sjdp hold_data = os; 107233965Sjdp else if (strcmp (os->name, ".bss") == 0) 107333965Sjdp hold_bss = os; 107433965Sjdp else if (hold_rel == NULL 107533965Sjdp && os->bfd_section != NULL 107633965Sjdp && (os->bfd_section->flags & SEC_ALLOC) != 0 107733965Sjdp && strncmp (os->name, ".rel", 4) == 0) 107833965Sjdp hold_rel = os; 107933965Sjdp else if (strcmp (os->name, ".interp") == 0) 108033965Sjdp hold_interp = os; 108133965Sjdp} 108233965Sjdp 108333965Sjdpstatic char * 108433965Sjdpgld${EMULATION_NAME}_get_script(isfile) 108533965Sjdp int *isfile; 108633965SjdpEOF 108733965Sjdp 108833965Sjdpif test -n "$COMPILE_IN" 108933965Sjdpthen 109033965Sjdp# Scripts compiled in. 109133965Sjdp 109233965Sjdp# sed commands to quote an ld script as a C string. 109333965Sjdpsc='s/["\\]/\\&/g 109433965Sjdps/$/\\n\\/ 109533965Sjdp1s/^/"/ 109633965Sjdp$s/$/n"/ 109733965Sjdp' 109833965Sjdp 109933965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 110033965Sjdp{ 110133965Sjdp *isfile = 0; 110233965Sjdp 110333965Sjdp if (link_info.relocateable == true && config.build_constructors == true) 110433965Sjdp return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; 110533965Sjdp else if (link_info.relocateable == true) 110633965Sjdp return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; 110733965Sjdp else if (!config.text_read_only) 110833965Sjdp return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; 110933965Sjdp else if (!config.magic_demand_paged) 111033965Sjdp return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; 111133965Sjdp else if (link_info.shared) 111233965Sjdp return `sed "$sc" ldscripts/${EMULATION_NAME}.xs`; 111333965Sjdp else 111433965Sjdp return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; 111533965Sjdp} 111633965SjdpEOF 111733965Sjdp 111833965Sjdpelse 111933965Sjdp# Scripts read from the filesystem. 112033965Sjdp 112133965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 112233965Sjdp{ 112333965Sjdp *isfile = 1; 112433965Sjdp 112533965Sjdp if (link_info.relocateable == true && config.build_constructors == true) 112633965Sjdp return "ldscripts/${EMULATION_NAME}.xu"; 112733965Sjdp else if (link_info.relocateable == true) 112833965Sjdp return "ldscripts/${EMULATION_NAME}.xr"; 112933965Sjdp else if (!config.text_read_only) 113033965Sjdp return "ldscripts/${EMULATION_NAME}.xbn"; 113133965Sjdp else if (!config.magic_demand_paged) 113233965Sjdp return "ldscripts/${EMULATION_NAME}.xn"; 113333965Sjdp else if (link_info.shared) 113433965Sjdp return "ldscripts/${EMULATION_NAME}.xs"; 113533965Sjdp else 113633965Sjdp return "ldscripts/${EMULATION_NAME}.x"; 113733965Sjdp} 113833965SjdpEOF 113933965Sjdp 114033965Sjdpfi 114133965Sjdp 114233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 114333965Sjdp 114433965Sjdpstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 114533965Sjdp{ 114633965Sjdp gld${EMULATION_NAME}_before_parse, 114733965Sjdp syslib_default, 114833965Sjdp hll_default, 114933965Sjdp after_parse_default, 115033965Sjdp gld${EMULATION_NAME}_after_open, 115133965Sjdp after_allocation_default, 115233965Sjdp set_output_arch_default, 115333965Sjdp ldemul_default_target, 115433965Sjdp gld${EMULATION_NAME}_before_allocation, 115533965Sjdp gld${EMULATION_NAME}_get_script, 115633965Sjdp "${EMULATION_NAME}", 115733965Sjdp "${OUTPUT_FORMAT}", 115833965Sjdp NULL, 115933965Sjdp NULL, 116033965Sjdp gld${EMULATION_NAME}_open_dynamic_archive, 116133965Sjdp gld${EMULATION_NAME}_place_orphan 116233965Sjdp}; 116333965SjdpEOF 1164