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 689872Sobrienif [ -z "$MACHINE" ]; then 789872Sobrien OUTPUT_ARCH=${ARCH} 889872Sobrienelse 989872Sobrien OUTPUT_ARCH=${ARCH}:${MACHINE} 1089872Sobrienfi 1133965Sjdpcat >e${EMULATION_NAME}.c <<EOF 1233965Sjdp/* This file is is generated by a shell script. DO NOT EDIT! */ 1333965Sjdp 1433965Sjdp/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME} 1591055Sobrien Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 16218822Sdim 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 1733965Sjdp Written by Steve Chamberlain <sac@cygnus.com> 1833965Sjdp ELF support by Ian Lance Taylor <ian@cygnus.com> 1933965Sjdp 2033965SjdpThis file is part of GLD, the Gnu Linker. 2133965Sjdp 2233965SjdpThis program is free software; you can redistribute it and/or modify 2333965Sjdpit under the terms of the GNU General Public License as published by 2433965Sjdpthe Free Software Foundation; either version 2 of the License, or 2533965Sjdp(at your option) any later version. 2633965Sjdp 2733965SjdpThis program is distributed in the hope that it will be useful, 2833965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 2933965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3033965SjdpGNU General Public License for more details. 3133965Sjdp 3233965SjdpYou should have received a copy of the GNU General Public License 3333965Sjdpalong with this program; if not, write to the Free Software 34218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 3533965Sjdp 3633965Sjdp#define TARGET_IS_${EMULATION_NAME} 3733965Sjdp 38218822Sdim#include "sysdep.h" 3933965Sjdp#include "bfd.h" 4078841Sobrien#include "libiberty.h" 4189872Sobrien#include "safe-ctype.h" 42130565Sobrien#include "getopt.h" 4333965Sjdp 4433965Sjdp#include "bfdlink.h" 4533965Sjdp 4633965Sjdp#include "ld.h" 4733965Sjdp#include "ldmain.h" 4833965Sjdp#include "ldmisc.h" 4933965Sjdp#include "ldexp.h" 5033965Sjdp#include "ldlang.h" 5177319Sobrien#include "ldfile.h" 5277319Sobrien#include "ldemul.h" 53107499Sobrien#include <ldgram.h> 5477319Sobrien#include "elf/common.h" 55218822Sdim#include "elf-bfd.h" 5633965Sjdp 57130565Sobrien/* Declare functions used by various EXTRA_EM_FILEs. */ 58130565Sobrienstatic void gld${EMULATION_NAME}_before_parse (void); 59130565Sobrienstatic void gld${EMULATION_NAME}_after_open (void); 60130565Sobrienstatic void gld${EMULATION_NAME}_before_allocation (void); 61218822Sdimstatic bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *s); 62130565Sobrienstatic void gld${EMULATION_NAME}_finish (void); 6333965Sjdp 6477319SobrienEOF 6577319Sobrien 66218822Sdimif [ "x${USE_LIBPATH}" = xyes ] ; then 67218822Sdim case ${target} in 68218822Sdim *-*-linux-* | *-*-k*bsd*-*) 69218822Sdim cat >>e${EMULATION_NAME}.c <<EOF 70218822Sdim#ifdef HAVE_GLOB 71218822Sdim#include <glob.h> 72218822Sdim#endif 73218822SdimEOF 74218822Sdim ;; 75218822Sdim esac 76218822Sdimfi 77218822Sdim 7877319Sobrien# Import any needed special functions and/or overrides. 7977319Sobrien# 80218822Sdim. ${srcdir}/emultempl/elf-generic.em 8177319Sobrienif test -n "$EXTRA_EM_FILE" ; then 8277319Sobrien. ${srcdir}/emultempl/${EXTRA_EM_FILE}.em 8377319Sobrienfi 8477319Sobrien 8577319Sobrien# Functions in this file can be overridden by setting the LDEMUL_* shell 8677319Sobrien# variables. If the name of the overriding function is the same as is 8777319Sobrien# defined in this file, then don't output this file's version. 8877319Sobrien# If a different overriding name is given then output the standard function 8977319Sobrien# as presumably it is called from the overriding function. 9077319Sobrien# 9177319Sobrienif test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then 9277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 9377319Sobrien 9433965Sjdpstatic void 95130565Sobriengld${EMULATION_NAME}_before_parse (void) 9633965Sjdp{ 97130565Sobrien ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`); 98130565Sobrien config.dynamic_link = ${DYNAMIC_LINK-TRUE}; 99130565Sobrien config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; 10033965Sjdp} 10133965Sjdp 10277319SobrienEOF 10377319Sobrienfi 10433965Sjdp 105130565Sobrienif test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then 10677319Sobriencat >>e${EMULATION_NAME}.c <<EOF 107130565Sobrien/* Handle as_needed DT_NEEDED. */ 10877319Sobrien 109130565Sobrienstatic bfd_boolean 110130565Sobriengld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry) 111130565Sobrien{ 112218822Sdim int class = 0; 113130565Sobrien 114130565Sobrien /* Tell the ELF linker that we don't want the output file to have a 115130565Sobrien DT_NEEDED entry for this file, unless it is used to resolve 116130565Sobrien references in a regular object. */ 117218822Sdim if (entry->as_needed) 118218822Sdim class = DYN_AS_NEEDED; 119130565Sobrien 120218822Sdim /* Tell the ELF linker that we don't want the output file to have a 121218822Sdim DT_NEEDED entry for any dynamic library in DT_NEEDED tags from 122218822Sdim this file at all. */ 123218822Sdim if (!entry->add_needed) 124218822Sdim class |= DYN_NO_ADD_NEEDED; 125218822Sdim 126218822Sdim if (entry->just_syms_flag 127218822Sdim && (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) != 0) 128218822Sdim einfo (_("%P%F: --just-symbols may not be used on DSO: %B\n"), 129218822Sdim entry->the_bfd); 130218822Sdim 131218822Sdim if (!class 132218822Sdim || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0) 133218822Sdim return FALSE; 134218822Sdim 135218822Sdim bfd_elf_set_dyn_lib_class (entry->the_bfd, class); 136218822Sdim 137130565Sobrien /* Continue on with normal load_symbols processing. */ 138130565Sobrien return FALSE; 139130565Sobrien} 140130565SobrienEOF 141130565Sobrienfi 142130565Sobrien 143130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 144130565Sobrien 14577319Sobrien/* These variables are required to pass information back and forth 14677319Sobrien between after_open and check_needed and stat_needed and vercheck. */ 14777319Sobrien 14877319Sobrienstatic struct bfd_link_needed_list *global_needed; 14977319Sobrienstatic struct stat global_stat; 150218822Sdimstatic lang_input_statement_type *global_found; 15177319Sobrienstatic struct bfd_link_needed_list *global_vercheck_needed; 152130565Sobrienstatic bfd_boolean global_vercheck_failed; 15377319Sobrien 15477319Sobrien 15577319Sobrien/* On Linux, it's possible to have different versions of the same 15677319Sobrien shared library linked against different versions of libc. The 15777319Sobrien dynamic linker somehow tags which libc version to use in 15877319Sobrien /etc/ld.so.cache, and, based on the libc that it sees in the 15977319Sobrien executable, chooses which version of the shared library to use. 16077319Sobrien 16177319Sobrien We try to do a similar check here by checking whether this shared 16277319Sobrien library needs any other shared libraries which may conflict with 16377319Sobrien libraries we have already included in the link. If it does, we 16477319Sobrien skip it, and try to find another shared library farther on down the 16577319Sobrien link path. 16677319Sobrien 16777319Sobrien This is called via lang_for_each_input_file. 16877319Sobrien GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object 16977319Sobrien which we are checking. This sets GLOBAL_VERCHECK_FAILED if we find 17077319Sobrien a conflicting version. */ 17177319Sobrien 17277319Sobrienstatic void 173130565Sobriengld${EMULATION_NAME}_vercheck (lang_input_statement_type *s) 17477319Sobrien{ 17578841Sobrien const char *soname; 17677319Sobrien struct bfd_link_needed_list *l; 17777319Sobrien 17877319Sobrien if (global_vercheck_failed) 17977319Sobrien return; 18077319Sobrien if (s->the_bfd == NULL 18177319Sobrien || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0) 18277319Sobrien return; 18377319Sobrien 18477319Sobrien soname = bfd_elf_get_dt_soname (s->the_bfd); 18577319Sobrien if (soname == NULL) 18692835Sobrien soname = lbasename (bfd_get_filename (s->the_bfd)); 18777319Sobrien 18877319Sobrien for (l = global_vercheck_needed; l != NULL; l = l->next) 18977319Sobrien { 19077319Sobrien const char *suffix; 19177319Sobrien 19278841Sobrien if (strcmp (soname, l->name) == 0) 19377319Sobrien { 19477319Sobrien /* Probably can't happen, but it's an easy check. */ 19577319Sobrien continue; 19677319Sobrien } 19777319Sobrien 19877319Sobrien if (strchr (l->name, '/') != NULL) 19977319Sobrien continue; 20077319Sobrien 20177319Sobrien suffix = strstr (l->name, ".so."); 20277319Sobrien if (suffix == NULL) 20377319Sobrien continue; 20477319Sobrien 20577319Sobrien suffix += sizeof ".so." - 1; 20677319Sobrien 20778841Sobrien if (strncmp (soname, l->name, suffix - l->name) == 0) 20877319Sobrien { 20977319Sobrien /* Here we know that S is a dynamic object FOO.SO.VER1, and 210130565Sobrien the object we are considering needs a dynamic object 211130565Sobrien FOO.SO.VER2, and VER1 and VER2 are different. This 212130565Sobrien appears to be a version mismatch, so we tell the caller 213130565Sobrien to try a different version of this library. */ 214130565Sobrien global_vercheck_failed = TRUE; 21577319Sobrien return; 21677319Sobrien } 21777319Sobrien } 21877319Sobrien} 21977319Sobrien 22077319Sobrien 22177319Sobrien/* See if an input file matches a DT_NEEDED entry by running stat on 22277319Sobrien the file. */ 22377319Sobrien 22477319Sobrienstatic void 225130565Sobriengld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s) 22677319Sobrien{ 22777319Sobrien struct stat st; 22877319Sobrien const char *suffix; 22977319Sobrien const char *soname; 23077319Sobrien 231218822Sdim if (global_found != NULL) 23277319Sobrien return; 23377319Sobrien if (s->the_bfd == NULL) 23477319Sobrien return; 23577319Sobrien 236218822Sdim /* If this input file was an as-needed entry, and wasn't found to be 237218822Sdim needed at the stage it was linked, then don't say we have loaded it. */ 238218822Sdim if ((bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0) 239218822Sdim return; 240218822Sdim 24177319Sobrien if (bfd_stat (s->the_bfd, &st) != 0) 24277319Sobrien { 24377319Sobrien einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd); 24477319Sobrien return; 24577319Sobrien } 24677319Sobrien 247218822Sdim /* Some operating systems, e.g. Windows, do not provide a meaningful 248218822Sdim st_ino; they always set it to zero. (Windows does provide a 249218822Sdim meaningful st_dev.) Do not indicate a duplicate library in that 250218822Sdim case. While there is no guarantee that a system that provides 251218822Sdim meaningful inode numbers will never set st_ino to zero, this is 252218822Sdim merely an optimization, so we do not need to worry about false 253218822Sdim negatives. */ 25477319Sobrien if (st.st_dev == global_stat.st_dev 255218822Sdim && st.st_ino == global_stat.st_ino 256218822Sdim && st.st_ino != 0) 25777319Sobrien { 258218822Sdim global_found = s; 25977319Sobrien return; 26077319Sobrien } 26177319Sobrien 26277319Sobrien /* We issue a warning if it looks like we are including two 26377319Sobrien different versions of the same shared library. For example, 26477319Sobrien there may be a problem if -lc picks up libc.so.6 but some other 26577319Sobrien shared library has a DT_NEEDED entry of libc.so.5. This is a 26677319Sobrien heuristic test, and it will only work if the name looks like 26777319Sobrien NAME.so.VERSION. FIXME: Depending on file names is error-prone. 26877319Sobrien If we really want to issue warnings about mixing version numbers 26977319Sobrien of shared libraries, we need to find a better way. */ 27077319Sobrien 27177319Sobrien if (strchr (global_needed->name, '/') != NULL) 27277319Sobrien return; 27377319Sobrien suffix = strstr (global_needed->name, ".so."); 27477319Sobrien if (suffix == NULL) 27577319Sobrien return; 27677319Sobrien suffix += sizeof ".so." - 1; 27777319Sobrien 27877319Sobrien soname = bfd_elf_get_dt_soname (s->the_bfd); 27977319Sobrien if (soname == NULL) 28092835Sobrien soname = lbasename (s->filename); 28177319Sobrien 28289872Sobrien if (strncmp (soname, global_needed->name, suffix - global_needed->name) == 0) 28377319Sobrien einfo ("%P: warning: %s, needed by %B, may conflict with %s\n", 28478841Sobrien global_needed->name, global_needed->by, soname); 28577319Sobrien} 28677319Sobrien 287218822Sdimstruct dt_needed 288218822Sdim{ 289218822Sdim bfd *by; 290218822Sdim const char *name; 291218822Sdim}; 29277319Sobrien 29377319Sobrien/* This function is called for each possible name for a dynamic object 29477319Sobrien named by a DT_NEEDED entry. The FORCE parameter indicates whether 29577319Sobrien to skip the check for a conflicting version. */ 29677319Sobrien 297130565Sobrienstatic bfd_boolean 298218822Sdimgld${EMULATION_NAME}_try_needed (struct dt_needed *needed, 299218822Sdim int force) 30033965Sjdp{ 30177319Sobrien bfd *abfd; 302218822Sdim const char *name = needed->name; 30377319Sobrien const char *soname; 304218822Sdim int class; 30533965Sjdp 30677319Sobrien abfd = bfd_openr (name, bfd_get_target (output_bfd)); 30777319Sobrien if (abfd == NULL) 308130565Sobrien return FALSE; 30977319Sobrien if (! bfd_check_format (abfd, bfd_object)) 31077319Sobrien { 31189872Sobrien bfd_close (abfd); 312130565Sobrien return FALSE; 31377319Sobrien } 31477319Sobrien if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) 31577319Sobrien { 31689872Sobrien bfd_close (abfd); 317130565Sobrien return FALSE; 31877319Sobrien } 31933965Sjdp 320104847Sobrien /* For DT_NEEDED, they have to match. */ 321104847Sobrien if (abfd->xvec != output_bfd->xvec) 322104847Sobrien { 323104847Sobrien bfd_close (abfd); 324130565Sobrien return FALSE; 325104847Sobrien } 326104847Sobrien 32777319Sobrien /* Check whether this object would include any conflicting library 32877319Sobrien versions. If FORCE is set, then we skip this check; we use this 32977319Sobrien the second time around, if we couldn't find any compatible 33077319Sobrien instance of the shared library. */ 33133965Sjdp 33277319Sobrien if (! force) 33377319Sobrien { 33477319Sobrien struct bfd_link_needed_list *needed; 33533965Sjdp 33677319Sobrien if (! bfd_elf_get_bfd_needed_list (abfd, &needed)) 33777319Sobrien einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd); 33833965Sjdp 33977319Sobrien if (needed != NULL) 34077319Sobrien { 34177319Sobrien global_vercheck_needed = needed; 342130565Sobrien global_vercheck_failed = FALSE; 34377319Sobrien lang_for_each_input_file (gld${EMULATION_NAME}_vercheck); 34477319Sobrien if (global_vercheck_failed) 34577319Sobrien { 34689872Sobrien bfd_close (abfd); 347130565Sobrien /* Return FALSE to force the caller to move on to try 348130565Sobrien another file on the search path. */ 349130565Sobrien return FALSE; 35077319Sobrien } 35160525Sobrien 35277319Sobrien /* But wait! It gets much worse. On Linux, if a shared 353130565Sobrien library does not use libc at all, we are supposed to skip 354130565Sobrien it the first time around in case we encounter a shared 355130565Sobrien library later on with the same name which does use the 356130565Sobrien version of libc that we want. This is much too horrible 357130565Sobrien to use on any system other than Linux. */ 35877319Sobrien 35977319SobrienEOF 36077319Sobriencase ${target} in 361218822Sdim *-*-linux-* | *-*-k*bsd*-*) 36277319Sobrien cat >>e${EMULATION_NAME}.c <<EOF 36377319Sobrien { 36477319Sobrien struct bfd_link_needed_list *l; 36577319Sobrien 36677319Sobrien for (l = needed; l != NULL; l = l->next) 367218822Sdim if (CONST_STRNEQ (l->name, "libc.so")) 36877319Sobrien break; 36977319Sobrien if (l == NULL) 37077319Sobrien { 37189872Sobrien bfd_close (abfd); 372130565Sobrien return FALSE; 37377319Sobrien } 37477319Sobrien } 37577319Sobrien 37677319SobrienEOF 37777319Sobrien ;; 37877319Sobrienesac 37977319Sobriencat >>e${EMULATION_NAME}.c <<EOF 38077319Sobrien } 38177319Sobrien } 38277319Sobrien 38377319Sobrien /* We've found a dynamic object matching the DT_NEEDED entry. */ 38477319Sobrien 38577319Sobrien /* We have already checked that there is no other input file of the 38677319Sobrien same name. We must now check again that we are not including the 38777319Sobrien same file twice. We need to do this because on many systems 38877319Sobrien libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will 38977319Sobrien reference libc.so.1. If we have already included libc.so, we 39077319Sobrien don't want to include libc.so.1 if they are the same file, and we 39177319Sobrien can only check that using stat. */ 39277319Sobrien 39377319Sobrien if (bfd_stat (abfd, &global_stat) != 0) 39477319Sobrien einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd); 39577319Sobrien 39677319Sobrien /* First strip off everything before the last '/'. */ 39792835Sobrien soname = lbasename (abfd->filename); 39877319Sobrien 39977319Sobrien if (trace_file_tries) 40077319Sobrien info_msg (_("found %s at %s\n"), soname, name); 40177319Sobrien 402218822Sdim global_found = NULL; 40377319Sobrien lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed); 404218822Sdim if (global_found != NULL) 40533965Sjdp { 406130565Sobrien /* Return TRUE to indicate that we found the file, even though 407130565Sobrien we aren't going to do anything with it. */ 408130565Sobrien return TRUE; 40933965Sjdp } 41033965Sjdp 411130565Sobrien /* Specify the soname to use. */ 412130565Sobrien bfd_elf_set_dt_needed_name (abfd, soname); 41333965Sjdp 414130565Sobrien /* Tell the ELF linker that we don't want the output file to have a 415130565Sobrien DT_NEEDED entry for this file, unless it is used to resolve 416130565Sobrien references in a regular object. */ 417218822Sdim class = DYN_DT_NEEDED; 41833965Sjdp 419218822Sdim /* Tell the ELF linker that we don't want the output file to have a 420218822Sdim DT_NEEDED entry for this file at all if the entry is from a file 421218822Sdim with DYN_NO_ADD_NEEDED. */ 422218822Sdim if (needed->by != NULL 423218822Sdim && (bfd_elf_get_dyn_lib_class (needed->by) & DYN_NO_ADD_NEEDED) != 0) 424218822Sdim class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED; 425218822Sdim 426218822Sdim bfd_elf_set_dyn_lib_class (abfd, class); 427218822Sdim 42877319Sobrien /* Add this file into the symbol table. */ 42977319Sobrien if (! bfd_link_add_symbols (abfd, &link_info)) 43077319Sobrien einfo ("%F%B: could not read symbols: %E\n", abfd); 43177319Sobrien 432130565Sobrien return TRUE; 43377319Sobrien} 43477319Sobrien 43577319Sobrien 43677319Sobrien/* Search for a needed file in a path. */ 43777319Sobrien 438130565Sobrienstatic bfd_boolean 439218822Sdimgld${EMULATION_NAME}_search_needed (const char *path, 440218822Sdim struct dt_needed *n, int force) 44177319Sobrien{ 44277319Sobrien const char *s; 443218822Sdim const char *name = n->name; 44477319Sobrien size_t len; 445218822Sdim struct dt_needed needed; 44677319Sobrien 44777319Sobrien if (name[0] == '/') 448218822Sdim return gld${EMULATION_NAME}_try_needed (n, force); 44977319Sobrien 45077319Sobrien if (path == NULL || *path == '\0') 451130565Sobrien return FALSE; 452218822Sdim 453218822Sdim needed.by = n->by; 454218822Sdim needed.name = n->name; 455218822Sdim 45677319Sobrien len = strlen (name); 45777319Sobrien while (1) 45833965Sjdp { 45977319Sobrien char *filename, *sset; 46033965Sjdp 461218822Sdim s = strchr (path, config.rpath_separator); 46277319Sobrien if (s == NULL) 46377319Sobrien s = path + strlen (path); 46460525Sobrien 46577319Sobrien filename = (char *) xmalloc (s - path + len + 2); 46677319Sobrien if (s == path) 46777319Sobrien sset = filename; 46877319Sobrien else 46977319Sobrien { 47077319Sobrien memcpy (filename, path, s - path); 47177319Sobrien filename[s - path] = '/'; 47277319Sobrien sset = filename + (s - path) + 1; 47377319Sobrien } 47477319Sobrien strcpy (sset, name); 47560525Sobrien 476218822Sdim needed.name = filename; 477218822Sdim if (gld${EMULATION_NAME}_try_needed (&needed, force)) 478130565Sobrien return TRUE; 47960525Sobrien 48077319Sobrien free (filename); 48177319Sobrien 48277319Sobrien if (*s == '\0') 48377319Sobrien break; 48477319Sobrien path = s + 1; 48533965Sjdp } 48633965Sjdp 487130565Sobrien return FALSE; 48833965Sjdp} 48933965Sjdp 49033965SjdpEOF 491130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 492130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 493130565Sobrien 494218822Sdim/* Add the sysroot to every entry in a path separated by 495218822Sdim config.rpath_separator. */ 496130565Sobrien 497130565Sobrienstatic char * 498130565Sobriengld${EMULATION_NAME}_add_sysroot (const char *path) 499130565Sobrien{ 500130565Sobrien int len, colons, i; 501130565Sobrien char *ret, *p; 502130565Sobrien 503130565Sobrien len = strlen (path); 504130565Sobrien colons = 0; 505130565Sobrien i = 0; 506130565Sobrien while (path[i]) 507218822Sdim if (path[i++] == config.rpath_separator) 508130565Sobrien colons++; 509130565Sobrien 510130565Sobrien if (path[i]) 511130565Sobrien colons++; 512130565Sobrien 513130565Sobrien len = len + (colons + 1) * strlen (ld_sysroot); 514130565Sobrien ret = xmalloc (len + 1); 515130565Sobrien strcpy (ret, ld_sysroot); 516130565Sobrien p = ret + strlen (ret); 517130565Sobrien i = 0; 518130565Sobrien while (path[i]) 519218822Sdim if (path[i] == config.rpath_separator) 520130565Sobrien { 521130565Sobrien *p++ = path[i++]; 522130565Sobrien strcpy (p, ld_sysroot); 523130565Sobrien p = p + strlen (p); 524130565Sobrien } 525130565Sobrien else 526130565Sobrien *p++ = path[i++]; 527130565Sobrien 528130565Sobrien *p = 0; 529130565Sobrien return ret; 530130565Sobrien} 531130565Sobrien 532130565SobrienEOF 533130565Sobrien case ${target} in 534218822Sdim *-*-freebsd* | *-*-dragonfly*) 535130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 536218822Sdim/* Read the system search path the FreeBSD way rather than the Linux way. */ 537218822Sdim#ifdef HAVE_ELF_HINTS_H 53876232Sobrien#include <elf-hints.h> 539218822Sdim#else 540218822Sdim#include "elf-hints-local.h" 541218822Sdim#endif 54233965Sjdp 543130565Sobrienstatic bfd_boolean 544130565Sobriengld${EMULATION_NAME}_check_ld_elf_hints (const char *name, int force) 54542372Speter{ 546130565Sobrien static bfd_boolean initialized; 54742372Speter static char *ld_elf_hints; 548218822Sdim struct dt_needed needed; 54942372Speter 550218822Sdim if (!initialized) 55142372Speter { 55242372Speter FILE *f; 553130565Sobrien char *tmppath; 55442372Speter 555130565Sobrien tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, NULL); 556130565Sobrien f = fopen (tmppath, FOPEN_RB); 557130565Sobrien free (tmppath); 55842372Speter if (f != NULL) 55942372Speter { 56042372Speter struct elfhints_hdr hdr; 56142372Speter 562218822Sdim if (fread (&hdr, 1, sizeof (hdr), f) == sizeof (hdr) 563218822Sdim && hdr.magic == ELFHINTS_MAGIC 564218822Sdim && hdr.version == 1) 56542372Speter { 566218822Sdim if (fseek (f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1) 56742372Speter { 56842372Speter char *b; 56942372Speter 570218822Sdim b = xmalloc (hdr.dirlistlen + 1); 571218822Sdim if (fread (b, 1, hdr.dirlistlen + 1, f) == 57242372Speter hdr.dirlistlen + 1) 573218822Sdim ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b); 574218822Sdim 575218822Sdim free (b); 57642372Speter } 57742372Speter } 57842372Speter fclose (f); 57942372Speter } 58042372Speter 581130565Sobrien initialized = TRUE; 58242372Speter } 58342372Speter 58442372Speter if (ld_elf_hints == NULL) 585130565Sobrien return FALSE; 58642372Speter 587218822Sdim needed.by = NULL; 588218822Sdim needed.name = name; 589218822Sdim return gld${EMULATION_NAME}_search_needed (ld_elf_hints, & needed, 590218822Sdim force); 59142372Speter} 59242372SpeterEOF 593130565Sobrien # FreeBSD 594130565Sobrien ;; 59560525Sobrien 596218822Sdim *-*-linux-* | *-*-k*bsd*-*) 597130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 59833965Sjdp/* For a native linker, check the file /etc/ld.so.conf for directories 59933965Sjdp in which we may find shared libraries. /etc/ld.so.conf is really 60060525Sobrien only meaningful on Linux. */ 60133965Sjdp 602218822Sdimstruct gld${EMULATION_NAME}_ld_so_conf 603218822Sdim{ 604218822Sdim char *path; 605218822Sdim size_t len, alloc; 606218822Sdim}; 607218822Sdim 608130565Sobrienstatic bfd_boolean 609218822Sdimgld${EMULATION_NAME}_parse_ld_so_conf 610218822Sdim (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename); 611218822Sdim 612218822Sdimstatic void 613218822Sdimgld${EMULATION_NAME}_parse_ld_so_conf_include 614218822Sdim (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename, 615218822Sdim const char *pattern) 61633965Sjdp{ 617218822Sdim char *newp = NULL; 618218822Sdim#ifdef HAVE_GLOB 619218822Sdim glob_t gl; 620218822Sdim#endif 62133965Sjdp 622218822Sdim if (pattern[0] != '/') 62333965Sjdp { 624218822Sdim char *p = strrchr (filename, '/'); 625218822Sdim size_t patlen = strlen (pattern) + 1; 62633965Sjdp 627218822Sdim newp = xmalloc (p - filename + 1 + patlen); 628218822Sdim memcpy (newp, filename, p - filename + 1); 629218822Sdim memcpy (newp + (p - filename + 1), pattern, patlen); 630218822Sdim pattern = newp; 631218822Sdim } 632218822Sdim 633218822Sdim#ifdef HAVE_GLOB 634218822Sdim if (glob (pattern, 0, NULL, &gl) == 0) 635218822Sdim { 636218822Sdim size_t i; 637218822Sdim 638218822Sdim for (i = 0; i < gl.gl_pathc; ++i) 639218822Sdim gld${EMULATION_NAME}_parse_ld_so_conf (info, gl.gl_pathv[i]); 640218822Sdim globfree (&gl); 641218822Sdim } 642218822Sdim#else 643218822Sdim /* If we do not have glob, treat the pattern as a literal filename. */ 644218822Sdim gld${EMULATION_NAME}_parse_ld_so_conf (info, pattern); 645218822Sdim#endif 646218822Sdim 647218822Sdim if (newp) 648218822Sdim free (newp); 649218822Sdim} 650218822Sdim 651218822Sdimstatic bfd_boolean 652218822Sdimgld${EMULATION_NAME}_parse_ld_so_conf 653218822Sdim (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename) 654218822Sdim{ 655218822Sdim FILE *f = fopen (filename, FOPEN_RT); 656218822Sdim char *line; 657218822Sdim size_t linelen; 658218822Sdim 659218822Sdim if (f == NULL) 660218822Sdim return FALSE; 661218822Sdim 662218822Sdim linelen = 256; 663218822Sdim line = xmalloc (linelen); 664218822Sdim do 665218822Sdim { 666218822Sdim char *p = line, *q; 667218822Sdim 668218822Sdim /* Normally this would use getline(3), but we need to be portable. */ 669218822Sdim while ((q = fgets (p, linelen - (p - line), f)) != NULL 670218822Sdim && strlen (q) == linelen - (p - line) - 1 671218822Sdim && line[linelen - 2] != '\n') 67233965Sjdp { 673218822Sdim line = xrealloc (line, 2 * linelen); 674218822Sdim p = line + linelen - 1; 675218822Sdim linelen += linelen; 676218822Sdim } 67733965Sjdp 678218822Sdim if (q == NULL && p == line) 679218822Sdim break; 68033965Sjdp 681218822Sdim p = strchr (line, '\n'); 682218822Sdim if (p) 683218822Sdim *p = '\0'; 684218822Sdim 685218822Sdim /* Because the file format does not know any form of quoting we 686218822Sdim can search forward for the next '#' character and if found 687218822Sdim make it terminating the line. */ 688218822Sdim p = strchr (line, '#'); 689218822Sdim if (p) 690218822Sdim *p = '\0'; 691218822Sdim 692218822Sdim /* Remove leading whitespace. NUL is no whitespace character. */ 693218822Sdim p = line; 694218822Sdim while (*p == ' ' || *p == '\f' || *p == '\r' || *p == '\t' || *p == '\v') 695218822Sdim ++p; 696218822Sdim 697218822Sdim /* If the line is blank it is ignored. */ 698218822Sdim if (p[0] == '\0') 699218822Sdim continue; 700218822Sdim 701218822Sdim if (CONST_STRNEQ (p, "include") && (p[7] == ' ' || p[7] == '\t')) 702218822Sdim { 703218822Sdim char *dir, c; 704218822Sdim p += 8; 705218822Sdim do 70633965Sjdp { 707218822Sdim while (*p == ' ' || *p == '\t') 708218822Sdim ++p; 709218822Sdim 710218822Sdim if (*p == '\0') 711218822Sdim break; 712218822Sdim 713218822Sdim dir = p; 714218822Sdim 715218822Sdim while (*p != ' ' && *p != '\t' && *p) 716218822Sdim ++p; 717218822Sdim 718218822Sdim c = *p; 719218822Sdim *p++ = '\0'; 720218822Sdim if (dir[0] != '\0') 721218822Sdim gld${EMULATION_NAME}_parse_ld_so_conf_include (info, filename, 722218822Sdim dir); 72333965Sjdp } 724218822Sdim while (c != '\0'); 725218822Sdim } 726218822Sdim else 727218822Sdim { 728218822Sdim char *dir = p; 729218822Sdim while (*p && *p != '=' && *p != ' ' && *p != '\t' && *p != '\f' 730218822Sdim && *p != '\r' && *p != '\v') 731218822Sdim ++p; 73233965Sjdp 733218822Sdim while (p != dir && p[-1] == '/') 734218822Sdim --p; 735218822Sdim if (info->path == NULL) 736218822Sdim { 737218822Sdim info->alloc = p - dir + 1 + 256; 738218822Sdim info->path = xmalloc (info->alloc); 739218822Sdim info->len = 0; 740218822Sdim } 74133965Sjdp else 74233965Sjdp { 743218822Sdim if (info->len + 1 + (p - dir) >= info->alloc) 744218822Sdim { 745218822Sdim info->alloc += p - dir + 256; 746218822Sdim info->path = xrealloc (info->path, info->alloc); 747218822Sdim } 748218822Sdim info->path[info->len++] = config.rpath_separator; 74933965Sjdp } 750218822Sdim memcpy (info->path + info->len, dir, p - dir); 751218822Sdim info->len += p - dir; 752218822Sdim info->path[info->len] = '\0'; 753218822Sdim } 754218822Sdim } 755218822Sdim while (! feof (f)); 756218822Sdim free (line); 757218822Sdim fclose (f); 758218822Sdim return TRUE; 759218822Sdim} 76033965Sjdp 761218822Sdimstatic bfd_boolean 762218822Sdimgld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force) 763218822Sdim{ 764218822Sdim static bfd_boolean initialized; 765218822Sdim static char *ld_so_conf; 766218822Sdim struct dt_needed needed; 76733965Sjdp 768218822Sdim if (! initialized) 769218822Sdim { 770218822Sdim char *tmppath; 771218822Sdim struct gld${EMULATION_NAME}_ld_so_conf info; 772130565Sobrien 773218822Sdim info.path = NULL; 774218822Sdim info.len = info.alloc = 0; 775218822Sdim tmppath = concat (ld_sysroot, "${prefix}/etc/ld.so.conf", NULL); 776218822Sdim if (!gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath)) 777218822Sdim { 778218822Sdim free (tmppath); 779218822Sdim tmppath = concat (ld_sysroot, "/etc/ld.so.conf", NULL); 780218822Sdim gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath); 78133965Sjdp } 782218822Sdim free (tmppath); 78333965Sjdp 784218822Sdim if (info.path) 785218822Sdim { 786218822Sdim char *d = gld${EMULATION_NAME}_add_sysroot (info.path); 787218822Sdim free (info.path); 788218822Sdim ld_so_conf = d; 789218822Sdim } 790130565Sobrien initialized = TRUE; 79133965Sjdp } 79233965Sjdp 79333965Sjdp if (ld_so_conf == NULL) 794130565Sobrien return FALSE; 79533965Sjdp 796218822Sdim 797218822Sdim needed.by = NULL; 798218822Sdim needed.name = name; 799218822Sdim return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force); 80033965Sjdp} 80160525Sobrien 80233965SjdpEOF 803130565Sobrien # Linux 804130565Sobrien ;; 80560525Sobrien esac 80633965Sjdpfi 80733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 80833965Sjdp 80977319Sobrien/* See if an input file matches a DT_NEEDED entry by name. */ 81033965Sjdp 81177319Sobrienstatic void 812130565Sobriengld${EMULATION_NAME}_check_needed (lang_input_statement_type *s) 81377319Sobrien{ 814218822Sdim const char *soname; 815218822Sdim 816218822Sdim /* Stop looking if we've found a loaded lib. */ 817218822Sdim if (global_found != NULL 818218822Sdim && (bfd_elf_get_dyn_lib_class (global_found->the_bfd) 819218822Sdim & DYN_AS_NEEDED) == 0) 82077319Sobrien return; 82133965Sjdp 822218822Sdim if (s->filename == NULL || s->the_bfd == NULL) 823218822Sdim return; 82477319Sobrien 825218822Sdim /* Don't look for a second non-loaded as-needed lib. */ 826218822Sdim if (global_found != NULL 827218822Sdim && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0) 828218822Sdim return; 82977319Sobrien 830218822Sdim if (strcmp (s->filename, global_needed->name) == 0) 831218822Sdim { 832218822Sdim global_found = s; 833218822Sdim return; 83477319Sobrien } 83577319Sobrien 836218822Sdim if (s->search_dirs_flag) 83777319Sobrien { 838218822Sdim const char *f = strrchr (s->filename, '/'); 839218822Sdim if (f != NULL 840218822Sdim && strcmp (f + 1, global_needed->name) == 0) 84177319Sobrien { 842218822Sdim global_found = s; 84377319Sobrien return; 84477319Sobrien } 84577319Sobrien } 846218822Sdim 847218822Sdim soname = bfd_elf_get_dt_soname (s->the_bfd); 848218822Sdim if (soname != NULL 849218822Sdim && strcmp (soname, global_needed->name) == 0) 850218822Sdim { 851218822Sdim global_found = s; 852218822Sdim return; 853218822Sdim } 85477319Sobrien} 85577319Sobrien 85677319SobrienEOF 85777319Sobrien 85877319Sobrienif test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then 85977319Sobriencat >>e${EMULATION_NAME}.c <<EOF 86077319Sobrien 86133965Sjdp/* This is called after all the input files have been opened. */ 86233965Sjdp 86333965Sjdpstatic void 864130565Sobriengld${EMULATION_NAME}_after_open (void) 86533965Sjdp{ 86633965Sjdp struct bfd_link_needed_list *needed, *l; 86733965Sjdp 868218822Sdim if (link_info.eh_frame_hdr 869218822Sdim && ! link_info.traditional_format 870218822Sdim && ! link_info.relocatable) 871218822Sdim { 872218822Sdim struct elf_link_hash_table *htab; 873218822Sdim 874218822Sdim htab = elf_hash_table (&link_info); 875218822Sdim if (is_elf_hash_table (htab)) 876218822Sdim { 877218822Sdim bfd *abfd; 878218822Sdim asection *s; 879218822Sdim 880218822Sdim for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next) 881218822Sdim { 882218822Sdim s = bfd_get_section_by_name (abfd, ".eh_frame"); 883218822Sdim if (s && s->size > 8 && !bfd_is_abs_section (s->output_section)) 884218822Sdim break; 885218822Sdim } 886218822Sdim if (abfd) 887218822Sdim { 888218822Sdim const struct elf_backend_data *bed; 889218822Sdim 890218822Sdim bed = get_elf_backend_data (abfd); 891218822Sdim s = bfd_make_section_with_flags (abfd, ".eh_frame_hdr", 892218822Sdim bed->dynamic_sec_flags 893218822Sdim | SEC_READONLY); 894218822Sdim if (s != NULL 895218822Sdim && bfd_set_section_alignment (abfd, s, 2)) 896218822Sdim htab->eh_info.hdr_sec = s; 897218822Sdim else 898218822Sdim einfo ("%P: warning: Cannot create .eh_frame_hdr section," 899218822Sdim " --eh-frame-hdr ignored.\n"); 900218822Sdim } 901218822Sdim } 902218822Sdim } 903218822Sdim 90433965Sjdp /* We only need to worry about this when doing a final link. */ 905130565Sobrien if (link_info.relocatable || !link_info.executable) 90633965Sjdp return; 90733965Sjdp 90833965Sjdp /* Get the list of files which appear in DT_NEEDED entries in 90933965Sjdp dynamic objects included in the link (often there will be none). 91033965Sjdp For each such file, we want to track down the corresponding 91133965Sjdp library, and include the symbol table in the link. This is what 91233965Sjdp the runtime dynamic linker will do. Tracking the files down here 91333965Sjdp permits one dynamic object to include another without requiring 91433965Sjdp special action by the person doing the link. Note that the 91533965Sjdp needed list can actually grow while we are stepping through this 91633965Sjdp loop. */ 91733965Sjdp needed = bfd_elf_get_needed_list (output_bfd, &link_info); 91833965Sjdp for (l = needed; l != NULL; l = l->next) 91933965Sjdp { 92033965Sjdp struct bfd_link_needed_list *ll; 921218822Sdim struct dt_needed n, nn; 92238889Sjdp int force; 92333965Sjdp 924218822Sdim /* If the lib that needs this one was --as-needed and wasn't 925218822Sdim found to be needed, then this lib isn't needed either. */ 926218822Sdim if (l->by != NULL 927218822Sdim && (bfd_elf_get_dyn_lib_class (l->by) & DYN_AS_NEEDED) != 0) 928218822Sdim continue; 929218822Sdim 93033965Sjdp /* If we've already seen this file, skip it. */ 93133965Sjdp for (ll = needed; ll != l; ll = ll->next) 932218822Sdim if ((ll->by == NULL 933218822Sdim || (bfd_elf_get_dyn_lib_class (ll->by) & DYN_AS_NEEDED) == 0) 934218822Sdim && strcmp (ll->name, l->name) == 0) 93533965Sjdp break; 93633965Sjdp if (ll != l) 93733965Sjdp continue; 93833965Sjdp 93933965Sjdp /* See if this file was included in the link explicitly. */ 94033965Sjdp global_needed = l; 941218822Sdim global_found = NULL; 94233965Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); 943218822Sdim if (global_found != NULL 944218822Sdim && (bfd_elf_get_dyn_lib_class (global_found->the_bfd) 945218822Sdim & DYN_AS_NEEDED) == 0) 94633965Sjdp continue; 94733965Sjdp 948218822Sdim n.by = l->by; 949218822Sdim n.name = l->name; 950218822Sdim nn.by = l->by; 95177319Sobrien if (trace_file_tries) 95277319Sobrien info_msg (_("%s needed by %B\n"), l->name, l->by); 95377319Sobrien 954218822Sdim /* As-needed libs specified on the command line (or linker script) 955218822Sdim take priority over libs found in search dirs. */ 956218822Sdim if (global_found != NULL) 957218822Sdim { 958218822Sdim nn.name = global_found->filename; 959218822Sdim if (gld${EMULATION_NAME}_try_needed (&nn, TRUE)) 960218822Sdim continue; 961218822Sdim } 962218822Sdim 96333965Sjdp /* We need to find this file and include the symbol table. We 96433965Sjdp want to search for the file in the same way that the dynamic 96533965Sjdp linker will search. That means that we want to use 96633965Sjdp rpath_link, rpath, then the environment variable 96777319Sobrien LD_LIBRARY_PATH (native only), then the DT_RPATH/DT_RUNPATH 96877319Sobrien entries (native only), then the linker script LIB_SEARCH_DIRS. 96977319Sobrien We do not search using the -L arguments. 97038889Sjdp 97138889Sjdp We search twice. The first time, we skip objects which may 97238889Sjdp introduce version mismatches. The second time, we force 97338889Sjdp their use. See gld${EMULATION_NAME}_vercheck comment. */ 97438889Sjdp for (force = 0; force < 2; force++) 97533965Sjdp { 97638889Sjdp size_t len; 97738889Sjdp search_dirs_type *search; 97877319SobrienEOF 979218822Sdimif [ "x${NATIVE}" = xyes ] ; then 980218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 981218822Sdim const char *lib_path; 982218822SdimEOF 983218822Sdimfi 984130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 98577319Sobriencat >>e${EMULATION_NAME}.c <<EOF 98677319Sobrien struct bfd_link_needed_list *rp; 98777319Sobrien int found; 98877319SobrienEOF 98977319Sobrienfi 99077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 99138889Sjdp 99238889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, 993218822Sdim &n, force)) 99438889Sjdp break; 99577319SobrienEOF 996130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 99777319Sobriencat >>e${EMULATION_NAME}.c <<EOF 99838889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath, 999218822Sdim &n, force)) 100038889Sjdp break; 1001130565SobrienEOF 1002130565Sobrienfi 1003130565Sobrienif [ "x${NATIVE}" = xyes ] ; then 1004130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 100538889Sjdp if (command_line.rpath_link == NULL 100638889Sjdp && command_line.rpath == NULL) 100738889Sjdp { 100838889Sjdp lib_path = (const char *) getenv ("LD_RUN_PATH"); 1009218822Sdim if (gld${EMULATION_NAME}_search_needed (lib_path, &n, 101038889Sjdp force)) 101138889Sjdp break; 101238889Sjdp } 101338889Sjdp lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); 1014218822Sdim if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force)) 101538889Sjdp break; 1016130565SobrienEOF 1017130565Sobrienfi 1018130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 1019130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 102077319Sobrien found = 0; 102177319Sobrien rp = bfd_elf_get_runpath_list (output_bfd, &link_info); 102277319Sobrien for (; !found && rp != NULL; rp = rp->next) 102377319Sobrien { 1024130565Sobrien char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name); 102577319Sobrien found = (rp->by == l->by 1026130565Sobrien && gld${EMULATION_NAME}_search_needed (tmpname, 1027218822Sdim &n, 102877319Sobrien force)); 1029130565Sobrien free (tmpname); 103077319Sobrien } 103177319Sobrien if (found) 103277319Sobrien break; 103377319Sobrien 103433965SjdpEOF 103533965Sjdpfi 1036130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 1037130565Sobrien case ${target} in 1038218822Sdim *-*-freebsd* | *-*-dragonfly*) 1039130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 104042372Speter if (gld${EMULATION_NAME}_check_ld_elf_hints (l->name, force)) 104142372Speter break; 104242372SpeterEOF 1043130565Sobrien # FreeBSD 1044130565Sobrien ;; 1045130565Sobrien 1046218822Sdim *-*-linux-* | *-*-k*bsd*-*) 1047218822Sdim # Linux 1048130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 104938889Sjdp if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force)) 105038889Sjdp break; 1051218822Sdim 105233965SjdpEOF 1053130565Sobrien ;; 105460525Sobrien esac 105533965Sjdpfi 105633965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 1057218822Sdim len = strlen (l->name); 1058218822Sdim for (search = search_head; search != NULL; search = search->next) 1059218822Sdim { 1060218822Sdim char *filename; 1061218822Sdim 1062218822Sdim if (search->cmdline) 1063218822Sdim continue; 1064218822Sdim filename = (char *) xmalloc (strlen (search->name) + len + 2); 1065218822Sdim sprintf (filename, "%s/%s", search->name, l->name); 1066218822Sdim nn.name = filename; 1067218822Sdim if (gld${EMULATION_NAME}_try_needed (&nn, force)) 1068218822Sdim break; 1069218822Sdim free (filename); 1070218822Sdim } 1071218822Sdim if (search != NULL) 1072218822Sdim break; 1073218822SdimEOF 1074218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 107538889Sjdp } 107633965Sjdp 107738889Sjdp if (force < 2) 107838889Sjdp continue; 107938889Sjdp 108068778Sobrien einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n", 108133965Sjdp l->name, l->by); 108233965Sjdp } 108333965Sjdp} 108433965Sjdp 108538889SjdpEOF 108677319Sobrienfi 108738889Sjdp 108838889Sjdpcat >>e${EMULATION_NAME}.c <<EOF 108938889Sjdp 109077319Sobrien/* Look through an expression for an assignment statement. */ 109133965Sjdp 109233965Sjdpstatic void 1093130565Sobriengld${EMULATION_NAME}_find_exp_assignment (etree_type *exp) 109433965Sjdp{ 1095218822Sdim bfd_boolean provide = FALSE; 109633965Sjdp 109777319Sobrien switch (exp->type.node_class) 109833965Sjdp { 109977319Sobrien case etree_provide: 1100218822Sdim provide = TRUE; 1101218822Sdim /* Fall thru */ 1102218822Sdim case etree_assign: 110377319Sobrien /* We call record_link_assignment even if the symbol is defined. 110477319Sobrien This is because if it is defined by a dynamic object, we 110577319Sobrien actually want to use the value defined by the linker script, 110677319Sobrien not the value from the dynamic object (because we are setting 110777319Sobrien symbols like etext). If the symbol is defined by a regular 110877319Sobrien object, then, as it happens, calling record_link_assignment 110977319Sobrien will do no harm. */ 111077319Sobrien if (strcmp (exp->assign.dst, ".") != 0) 111133965Sjdp { 1112218822Sdim if (!bfd_elf_record_link_assignment (output_bfd, &link_info, 1113218822Sdim exp->assign.dst, provide, 1114218822Sdim exp->assign.hidden)) 111577319Sobrien einfo ("%P%F: failed to record assignment to %s: %E\n", 111677319Sobrien exp->assign.dst); 111733965Sjdp } 111877319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); 111977319Sobrien break; 112033965Sjdp 112177319Sobrien case etree_binary: 112277319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); 112377319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); 112477319Sobrien break; 112533965Sjdp 112677319Sobrien case etree_trinary: 112777319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); 112877319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); 112977319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); 113077319Sobrien break; 113133965Sjdp 113277319Sobrien case etree_unary: 113377319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); 113477319Sobrien break; 113533965Sjdp 113677319Sobrien default: 113777319Sobrien break; 113833965Sjdp } 113933965Sjdp} 114033965Sjdp 114138889Sjdp 114277319Sobrien/* This is called by the before_allocation routine via 114377319Sobrien lang_for_each_statement. It locates any assignment statements, and 114477319Sobrien tells the ELF backend about them, in case they are assignments to 114577319Sobrien symbols which are referred to by dynamic objects. */ 114638889Sjdp 114738889Sjdpstatic void 1148130565Sobriengld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s) 114938889Sjdp{ 115077319Sobrien if (s->header.type == lang_assignment_statement_enum) 115177319Sobrien gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); 115277319Sobrien} 115338889Sjdp 115477319SobrienEOF 115538889Sjdp 115677319Sobrienif test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then 115789872Sobrien if test x"${ELF_INTERPRETER_NAME+set}" = xset; then 115889872Sobrien ELF_INTERPRETER_SET_DEFAULT=" 115989872Sobrien if (sinterp != NULL) 116089872Sobrien { 1161218822Sdim sinterp->contents = (unsigned char *) ${ELF_INTERPRETER_NAME}; 1162218822Sdim sinterp->size = strlen ((char *) sinterp->contents) + 1; 116389872Sobrien } 116489872Sobrien 116589872Sobrien" 116689872Sobrien else 116789872Sobrien ELF_INTERPRETER_SET_DEFAULT= 116889872Sobrien fi 116977319Sobriencat >>e${EMULATION_NAME}.c <<EOF 117038889Sjdp 117133965Sjdp/* This is called after the sections have been attached to output 117233965Sjdp sections, but before any sizes or addresses have been set. */ 117333965Sjdp 117433965Sjdpstatic void 1175130565Sobriengld${EMULATION_NAME}_before_allocation (void) 117633965Sjdp{ 117733965Sjdp const char *rpath; 117833965Sjdp asection *sinterp; 117933965Sjdp 1180130565Sobrien if (link_info.hash->type == bfd_link_elf_hash_table) 1181130565Sobrien _bfd_elf_tls_setup (output_bfd, &link_info); 1182130565Sobrien 118333965Sjdp /* If we are going to make any variable assignments, we need to let 118433965Sjdp the ELF backend know about them in case the variables are 118533965Sjdp referred to by dynamic objects. */ 118633965Sjdp lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment); 118733965Sjdp 118833965Sjdp /* Let the ELF backend work out the sizes of any sections required 118933965Sjdp by dynamic linking. */ 119033965Sjdp rpath = command_line.rpath; 119133965Sjdp if (rpath == NULL) 119233965Sjdp rpath = (const char *) getenv ("LD_RUN_PATH"); 1193130565Sobrien if (! (bfd_elf_size_dynamic_sections 1194130565Sobrien (output_bfd, command_line.soname, rpath, 119589872Sobrien command_line.filter_shlib, 119633965Sjdp (const char * const *) command_line.auxiliary_filters, 119733965Sjdp &link_info, &sinterp, lang_elf_version_info))) 119833965Sjdp einfo ("%P%F: failed to set dynamic section sizes: %E\n"); 1199218822Sdim 120089872Sobrien${ELF_INTERPRETER_SET_DEFAULT} 120133965Sjdp /* Let the user override the dynamic linker we are using. */ 120233965Sjdp if (command_line.interpreter != NULL 120333965Sjdp && sinterp != NULL) 120433965Sjdp { 120533965Sjdp sinterp->contents = (bfd_byte *) command_line.interpreter; 1206218822Sdim sinterp->size = strlen (command_line.interpreter) + 1; 120733965Sjdp } 120833965Sjdp 120933965Sjdp /* Look for any sections named .gnu.warning. As a GNU extensions, 121033965Sjdp we treat such sections as containing warning messages. We print 121133965Sjdp out the warning message, and then zero out the section size so 121233965Sjdp that it does not get copied into the output file. */ 121333965Sjdp 121433965Sjdp { 121533965Sjdp LANG_FOR_EACH_INPUT_STATEMENT (is) 121633965Sjdp { 121733965Sjdp asection *s; 121833965Sjdp bfd_size_type sz; 121933965Sjdp char *msg; 1220130565Sobrien bfd_boolean ret; 122133965Sjdp 122233965Sjdp if (is->just_syms_flag) 122333965Sjdp continue; 122433965Sjdp 122533965Sjdp s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning"); 122633965Sjdp if (s == NULL) 122733965Sjdp continue; 122833965Sjdp 1229218822Sdim sz = s->size; 1230218822Sdim msg = xmalloc ((size_t) (sz + 1)); 1231218822Sdim if (! bfd_get_section_contents (is->the_bfd, s, msg, 1232130565Sobrien (file_ptr) 0, sz)) 123333965Sjdp einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", 123433965Sjdp is->the_bfd); 1235218822Sdim msg[sz] = '\0'; 123633965Sjdp ret = link_info.callbacks->warning (&link_info, msg, 123733965Sjdp (const char *) NULL, 123833965Sjdp is->the_bfd, (asection *) NULL, 123933965Sjdp (bfd_vma) 0); 124033965Sjdp ASSERT (ret); 124133965Sjdp free (msg); 124233965Sjdp 1243218822Sdim /* Clobber the section size, so that we don't waste space 1244218822Sdim copying the warning into the output file. If we've already 1245218822Sdim sized the output section, adjust its size. The adjustment 1246218822Sdim is on rawsize because targets that size sections early will 1247218822Sdim have called lang_reset_memory_regions after sizing. */ 1248218822Sdim if (s->output_section != NULL 1249218822Sdim && s->output_section->rawsize >= s->size) 1250218822Sdim s->output_section->rawsize -= s->size; 1251218822Sdim 1252218822Sdim s->size = 0; 1253218822Sdim 1254218822Sdim /* Also set SEC_EXCLUDE, so that local symbols defined in the 1255218822Sdim warning section don't get copied to the output. */ 1256218822Sdim s->flags |= SEC_EXCLUDE | SEC_KEEP; 125733965Sjdp } 125833965Sjdp } 1259218822Sdim 1260218822Sdim before_allocation_default (); 1261218822Sdim 1262218822Sdim if (!bfd_elf_size_dynsym_hash_dynstr (output_bfd, &link_info)) 1263218822Sdim einfo ("%P%F: failed to set dynamic section sizes: %E\n"); 126433965Sjdp} 126533965Sjdp 126677319SobrienEOF 126777319Sobrienfi 126833965Sjdp 126977319Sobrienif test x"$LDEMUL_OPEN_DYNAMIC_ARCHIVE" != xgld"$EMULATION_NAME"_open_dynamic_archive; then 127077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 127133965Sjdp 127277319Sobrien/* Try to open a dynamic archive. This is where we know that ELF 127377319Sobrien dynamic libraries have an extension of .so (or .sl on oddball systems 127477319Sobrien like hpux). */ 127533965Sjdp 1276130565Sobrienstatic bfd_boolean 1277130565Sobriengld${EMULATION_NAME}_open_dynamic_archive 1278130565Sobrien (const char *arch, search_dirs_type *search, lang_input_statement_type *entry) 127933965Sjdp{ 128077319Sobrien const char *filename; 128177319Sobrien char *string; 128233965Sjdp 128377319Sobrien if (! entry->is_archive) 1284130565Sobrien return FALSE; 128577319Sobrien 128677319Sobrien filename = entry->filename; 128777319Sobrien 128877319Sobrien /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION 128977319Sobrien is defined, but it does not seem worth the headache to optimize 129077319Sobrien away those two bytes of space. */ 129177319Sobrien string = (char *) xmalloc (strlen (search->name) 129277319Sobrien + strlen (filename) 129377319Sobrien + strlen (arch) 129477319Sobrien#ifdef EXTRA_SHLIB_EXTENSION 129577319Sobrien + strlen (EXTRA_SHLIB_EXTENSION) 129677319Sobrien#endif 129777319Sobrien + sizeof "/lib.so"); 129877319Sobrien 129977319Sobrien sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); 130077319Sobrien 130177319Sobrien#ifdef EXTRA_SHLIB_EXTENSION 130277319Sobrien /* Try the .so extension first. If that fails build a new filename 130377319Sobrien using EXTRA_SHLIB_EXTENSION. */ 130477319Sobrien if (! ldfile_try_open_bfd (string, entry)) 130577319Sobrien sprintf (string, "%s/lib%s%s%s", search->name, 130677319Sobrien filename, arch, EXTRA_SHLIB_EXTENSION); 130777319Sobrien#endif 130877319Sobrien 130977319Sobrien if (! ldfile_try_open_bfd (string, entry)) 131033965Sjdp { 131177319Sobrien free (string); 1312130565Sobrien return FALSE; 131377319Sobrien } 131433965Sjdp 131577319Sobrien entry->filename = string; 131633965Sjdp 131777319Sobrien /* We have found a dynamic object to include in the link. The ELF 131877319Sobrien backend linker will create a DT_NEEDED entry in the .dynamic 131977319Sobrien section naming this file. If this file includes a DT_SONAME 132077319Sobrien entry, it will be used. Otherwise, the ELF linker will just use 132177319Sobrien the name of the file. For an archive found by searching, like 132277319Sobrien this one, the DT_NEEDED entry should consist of just the name of 132377319Sobrien the file, without the path information used to find it. Note 132477319Sobrien that we only need to do this if we have a dynamic object; an 132577319Sobrien archive will never be referenced by a DT_NEEDED entry. 132633965Sjdp 132777319Sobrien FIXME: This approach--using bfd_elf_set_dt_needed_name--is not 132877319Sobrien very pretty. I haven't been able to think of anything that is 132977319Sobrien pretty, though. */ 133077319Sobrien if (bfd_check_format (entry->the_bfd, bfd_object) 133177319Sobrien && (entry->the_bfd->flags & DYNAMIC) != 0) 133277319Sobrien { 133377319Sobrien ASSERT (entry->is_archive && entry->search_dirs_flag); 133433965Sjdp 133577319Sobrien /* Rather than duplicating the logic above. Just use the 133678841Sobrien filename we recorded earlier. */ 133733965Sjdp 133892835Sobrien filename = lbasename (entry->filename); 133978841Sobrien bfd_elf_set_dt_needed_name (entry->the_bfd, filename); 134033965Sjdp } 134177319Sobrien 1342130565Sobrien return TRUE; 134333965Sjdp} 134433965Sjdp 134577319SobrienEOF 134677319Sobrienfi 134789872Sobrien 134889872Sobrienif test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then 134977319Sobriencat >>e${EMULATION_NAME}.c <<EOF 135077319Sobrien 1351218822Sdim/* A variant of lang_output_section_find used by place_orphan. */ 135268778Sobrien 135368778Sobrienstatic lang_output_section_statement_type * 1354130565Sobrienoutput_rel_find (asection *sec, int isdyn) 135568778Sobrien{ 135668778Sobrien lang_output_section_statement_type *lookup; 1357107499Sobrien lang_output_section_statement_type *last = NULL; 1358130565Sobrien lang_output_section_statement_type *last_alloc = NULL; 1359107499Sobrien lang_output_section_statement_type *last_rel = NULL; 1360107499Sobrien lang_output_section_statement_type *last_rel_alloc = NULL; 1361107499Sobrien int rela = sec->name[4] == 'a'; 136268778Sobrien 1363218822Sdim for (lookup = &lang_output_section_statement.head->output_section_statement; 1364218822Sdim lookup != NULL; 1365218822Sdim lookup = lookup->next) 136668778Sobrien { 1367218822Sdim if (lookup->constraint != -1 1368218822Sdim && CONST_STRNEQ (lookup->name, ".rel")) 136968778Sobrien { 1370107499Sobrien int lookrela = lookup->name[4] == 'a'; 1371107499Sobrien 1372130565Sobrien /* .rel.dyn must come before all other reloc sections, to suit 1373130565Sobrien GNU ld.so. */ 1374130565Sobrien if (isdyn) 1375107499Sobrien break; 1376130565Sobrien 1377130565Sobrien /* Don't place after .rel.plt as doing so results in wrong 1378130565Sobrien dynamic tags. */ 1379130565Sobrien if (strcmp (".plt", lookup->name + 4 + lookrela) == 0) 1380130565Sobrien break; 1381130565Sobrien 1382130565Sobrien if (rela == lookrela || last_rel == NULL) 1383107499Sobrien last_rel = lookup; 1384130565Sobrien if ((rela == lookrela || last_rel_alloc == NULL) 1385130565Sobrien && lookup->bfd_section != NULL 1386107499Sobrien && (lookup->bfd_section->flags & SEC_ALLOC) != 0) 1387107499Sobrien last_rel_alloc = lookup; 138868778Sobrien } 1389130565Sobrien 1390130565Sobrien last = lookup; 1391130565Sobrien if (lookup->bfd_section != NULL 1392130565Sobrien && (lookup->bfd_section->flags & SEC_ALLOC) != 0) 1393130565Sobrien last_alloc = lookup; 139468778Sobrien } 1395107499Sobrien 1396107499Sobrien if (last_rel_alloc) 1397107499Sobrien return last_rel_alloc; 1398107499Sobrien 1399107499Sobrien if (last_rel) 1400107499Sobrien return last_rel; 1401107499Sobrien 1402130565Sobrien if (last_alloc) 1403130565Sobrien return last_alloc; 1404130565Sobrien 1405107499Sobrien return last; 140668778Sobrien} 140768778Sobrien 140833965Sjdp/* Place an orphan section. We use this to put random SHF_ALLOC 140933965Sjdp sections in the right segment. */ 141033965Sjdp 1411130565Sobrienstatic bfd_boolean 1412218822Sdimgld${EMULATION_NAME}_place_orphan (asection *s) 141333965Sjdp{ 1414218822Sdim static struct orphan_save hold[] = 1415218822Sdim { 1416218822Sdim { ".text", 1417218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE, 1418218822Sdim 0, 0, 0, 0 }, 1419218822Sdim { ".rodata", 1420218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA, 1421218822Sdim 0, 0, 0, 0 }, 1422218822Sdim { ".data", 1423218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA, 1424218822Sdim 0, 0, 0, 0 }, 1425218822Sdim { ".bss", 1426218822Sdim SEC_ALLOC, 1427218822Sdim 0, 0, 0, 0 }, 1428218822Sdim { 0, 1429218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA, 1430218822Sdim 0, 0, 0, 0 }, 1431218822Sdim { ".interp", 1432218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA, 1433218822Sdim 0, 0, 0, 0 }, 1434218822Sdim { ".sdata", 1435218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_SMALL_DATA, 1436218822Sdim 0, 0, 0, 0 } 1437218822Sdim }; 1438218822Sdim enum orphan_save_index 1439218822Sdim { 1440218822Sdim orphan_text = 0, 1441218822Sdim orphan_rodata, 1442218822Sdim orphan_data, 1443218822Sdim orphan_bss, 1444218822Sdim orphan_rel, 1445218822Sdim orphan_interp, 1446218822Sdim orphan_sdata 1447218822Sdim }; 1448218822Sdim static int orphan_init_done = 0; 144968778Sobrien struct orphan_save *place; 145068778Sobrien const char *secname; 1451218822Sdim lang_output_section_statement_type *after; 145233965Sjdp lang_output_section_statement_type *os; 1453107499Sobrien int isdyn = 0; 1454218822Sdim int iself = s->owner->xvec->flavour == bfd_target_elf_flavour; 1455218822Sdim unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL; 145633965Sjdp 145768778Sobrien secname = bfd_get_section_name (s->owner, s); 1458218822Sdim 1459130565Sobrien if (! link_info.relocatable 1460107499Sobrien && link_info.combreloc 1461218822Sdim && (s->flags & SEC_ALLOC)) 1462107499Sobrien { 1463218822Sdim if (iself) 1464218822Sdim switch (sh_type) 1465218822Sdim { 1466218822Sdim case SHT_RELA: 1467218822Sdim secname = ".rela.dyn"; 1468218822Sdim isdyn = 1; 1469218822Sdim break; 1470218822Sdim case SHT_REL: 1471218822Sdim secname = ".rel.dyn"; 1472218822Sdim isdyn = 1; 1473218822Sdim break; 1474218822Sdim default: 1475218822Sdim break; 1476218822Sdim } 1477218822Sdim else if (CONST_STRNEQ (secname, ".rel")) 1478218822Sdim { 1479218822Sdim secname = secname[4] == 'a' ? ".rela.dyn" : ".rel.dyn"; 1480218822Sdim isdyn = 1; 1481218822Sdim } 1482107499Sobrien } 148333965Sjdp 1484218822Sdim if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s))) 148577319Sobrien { 148677319Sobrien /* Look through the script to see where to place this section. */ 148777319Sobrien os = lang_output_section_find (secname); 148833965Sjdp 148977319Sobrien if (os != NULL 149089872Sobrien && (os->bfd_section == NULL 1491218822Sdim || os->bfd_section->flags == 0 1492218822Sdim || (_bfd_elf_match_sections_by_type (output_bfd, 1493218822Sdim os->bfd_section, 1494218822Sdim s->owner, s) 1495218822Sdim && ((s->flags ^ os->bfd_section->flags) 1496218822Sdim & (SEC_LOAD | SEC_ALLOC)) == 0))) 149777319Sobrien { 149889872Sobrien /* We already have an output section statement with this 1499218822Sdim name, and its bfd section, if any, has compatible flags. 1500218822Sdim If the section already exists but does not have any flags 1501218822Sdim set, then it has been created by the linker, probably as a 1502218822Sdim result of a --section-start command line switch. */ 1503218822Sdim lang_add_section (&os->children, s, os); 1504130565Sobrien return TRUE; 150577319Sobrien } 150633965Sjdp } 150733965Sjdp 1508218822Sdim if (!orphan_init_done) 1509218822Sdim { 1510218822Sdim struct orphan_save *ho; 1511218822Sdim for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho) 1512218822Sdim if (ho->name != NULL) 1513218822Sdim { 1514218822Sdim ho->os = lang_output_section_find (ho->name); 1515218822Sdim if (ho->os != NULL && ho->os->flags == 0) 1516218822Sdim ho->os->flags = ho->flags; 1517218822Sdim } 1518218822Sdim orphan_init_done = 1; 1519218822Sdim } 152033965Sjdp 152133965Sjdp /* If this is a final link, then always put .gnu.warning.SYMBOL 152233965Sjdp sections into the .text section to get them out of the way. */ 1523130565Sobrien if (link_info.executable 1524130565Sobrien && ! link_info.relocatable 1525218822Sdim && CONST_STRNEQ (secname, ".gnu.warning.") 1526218822Sdim && hold[orphan_text].os != NULL) 152733965Sjdp { 1528218822Sdim lang_add_section (&hold[orphan_text].os->children, s, 1529218822Sdim hold[orphan_text].os); 1530130565Sobrien return TRUE; 153133965Sjdp } 153233965Sjdp 153333965Sjdp /* Decide which segment the section should go in based on the 153433965Sjdp section name and section flags. We put loadable .note sections 153533965Sjdp right after the .interp section, so that the PT_NOTE segment is 153633965Sjdp stored right after the program headers where the OS can read it 153733965Sjdp in the first page. */ 153868778Sobrien 153968778Sobrien place = NULL; 154068778Sobrien if ((s->flags & SEC_ALLOC) == 0) 154168778Sobrien ; 154260525Sobrien else if ((s->flags & SEC_LOAD) != 0 1543218822Sdim && ((iself && sh_type == SHT_NOTE) 1544218822Sdim || (!iself && CONST_STRNEQ (secname, ".note")))) 1545218822Sdim place = &hold[orphan_interp]; 1546218822Sdim else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) 1547218822Sdim place = &hold[orphan_bss]; 1548218822Sdim else if ((s->flags & SEC_SMALL_DATA) != 0) 1549218822Sdim place = &hold[orphan_sdata]; 1550218822Sdim else if ((s->flags & SEC_READONLY) == 0) 1551218822Sdim place = &hold[orphan_data]; 1552218822Sdim else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL)) 1553218822Sdim || (!iself && CONST_STRNEQ (secname, ".rel"))) 1554218822Sdim && (s->flags & SEC_LOAD) != 0) 1555218822Sdim place = &hold[orphan_rel]; 1556218822Sdim else if ((s->flags & SEC_CODE) == 0) 1557218822Sdim place = &hold[orphan_rodata]; 1558218822Sdim else 1559218822Sdim place = &hold[orphan_text]; 156033965Sjdp 1561218822Sdim after = NULL; 1562218822Sdim if (place != NULL) 1563218822Sdim { 1564218822Sdim if (place->os == NULL) 1565218822Sdim { 1566218822Sdim if (place->name != NULL) 1567218822Sdim place->os = lang_output_section_find (place->name); 1568218822Sdim else 1569218822Sdim place->os = output_rel_find (s, isdyn); 1570218822Sdim } 1571218822Sdim after = place->os; 1572218822Sdim if (after == NULL) 1573218822Sdim after = lang_output_section_find_by_flags 1574218822Sdim (s, &place->os, _bfd_elf_match_sections_by_type); 1575218822Sdim if (after == NULL) 1576218822Sdim /* *ABS* is always the first output section statement. */ 1577218822Sdim after = &lang_output_section_statement.head->output_section_statement; 1578218822Sdim } 157968778Sobrien 158033965Sjdp /* Choose a unique name for the section. This will be needed if the 158133965Sjdp same section name appears in the input file with different 158277319Sobrien loadable or allocatable characteristics. */ 1583107499Sobrien if (bfd_get_section_by_name (output_bfd, secname) != NULL) 158433965Sjdp { 1585218822Sdim static int count = 1; 1586107499Sobrien secname = bfd_get_unique_section_name (output_bfd, secname, &count); 1587107499Sobrien if (secname == NULL) 158877319Sobrien einfo ("%F%P: place_orphan failed: %E\n"); 158933965Sjdp } 159033965Sjdp 1591218822Sdim lang_insert_orphan (s, secname, after, place, NULL, NULL); 159268778Sobrien 1593130565Sobrien return TRUE; 159433965Sjdp} 159589872SobrienEOF 159689872Sobrienfi 159733965Sjdp 159889872Sobrienif test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then 159989872Sobriencat >>e${EMULATION_NAME}.c <<EOF 160089872Sobrien 160189872Sobrienstatic void 1602130565Sobriengld${EMULATION_NAME}_finish (void) 160389872Sobrien{ 1604218822Sdim bfd_boolean need_layout = bfd_elf_discard_info (output_bfd, &link_info); 160591055Sobrien 1606218822Sdim gld${EMULATION_NAME}_map_segments (need_layout); 1607218822Sdim finish_default (); 160889872Sobrien} 160977319SobrienEOF 161077319Sobrienfi 161177319Sobrien 161277319Sobrienif test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then 161377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 161477319Sobrien 161533965Sjdpstatic char * 1616130565Sobriengld${EMULATION_NAME}_get_script (int *isfile) 161733965SjdpEOF 161833965Sjdp 161933965Sjdpif test -n "$COMPILE_IN" 162033965Sjdpthen 162133965Sjdp# Scripts compiled in. 162233965Sjdp 162333965Sjdp# sed commands to quote an ld script as a C string. 162460525Sobriensc="-f stringify.sed" 162533965Sjdp 162633965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 162777319Sobrien{ 162833965Sjdp *isfile = 0; 162933965Sjdp 1630130565Sobrien if (link_info.relocatable && config.build_constructors) 163160525Sobrien return 163233965SjdpEOF 1633218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c 1634218822Sdimecho ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c 1635218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c 1636218822Sdimecho ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c 1637218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c 163889872Sobrienif cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; else 1639218822Sdimecho ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c 1640218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c 164189872Sobrienfi 1642130565Sobrienif test -n "$GENERATE_PIE_SCRIPT" ; then 1643130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1644218822Sdimecho ' ; else if (link_info.pie && link_info.combreloc' >> e${EMULATION_NAME}.c 1645218822Sdimecho ' && link_info.relro' >> e${EMULATION_NAME}.c 1646218822Sdimecho ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c 1647218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xdw >> e${EMULATION_NAME}.c 1648130565Sobrienecho ' ; else if (link_info.pie && link_info.combreloc) return' >> e${EMULATION_NAME}.c 1649218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c 1650130565Sobrienfi 1651218822Sdimecho ' ; else if (link_info.pie) return' >> e${EMULATION_NAME}.c 1652218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c 1653130565Sobrienfi 165460525Sobrienif test -n "$GENERATE_SHLIB_SCRIPT" ; then 1655104847Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1656218822Sdimecho ' ; else if (link_info.shared && link_info.combreloc' >> e${EMULATION_NAME}.c 1657218822Sdimecho ' && link_info.relro' >> e${EMULATION_NAME}.c 1658218822Sdimecho ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c 1659218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xsw >> e${EMULATION_NAME}.c 166089872Sobrienecho ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c 1661218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c 1662104847Sobrienfi 1663218822Sdimecho ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c 1664218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c 166560525Sobrienfi 1666104847Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1667218822Sdimecho ' ; else if (link_info.combreloc && link_info.relro' >> e${EMULATION_NAME}.c 1668218822Sdimecho ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c 1669218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xw >> e${EMULATION_NAME}.c 1670218822Sdimecho ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c 1671218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c 1672104847Sobrienfi 1673218822Sdimecho ' ; else return' >> e${EMULATION_NAME}.c 1674218822Sdimsed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c 1675218822Sdimecho '; }' >> e${EMULATION_NAME}.c 167660525Sobrien 167733965Sjdpelse 167833965Sjdp# Scripts read from the filesystem. 167933965Sjdp 168033965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 168177319Sobrien{ 168233965Sjdp *isfile = 1; 168333965Sjdp 1684130565Sobrien if (link_info.relocatable && config.build_constructors) 168533965Sjdp return "ldscripts/${EMULATION_NAME}.xu"; 1686130565Sobrien else if (link_info.relocatable) 168733965Sjdp return "ldscripts/${EMULATION_NAME}.xr"; 168833965Sjdp else if (!config.text_read_only) 168933965Sjdp return "ldscripts/${EMULATION_NAME}.xbn"; 1690130565SobrienEOF 1691130565Sobrienif cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : 1692130565Sobrienelse 1693130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 169433965Sjdp else if (!config.magic_demand_paged) 169533965Sjdp return "ldscripts/${EMULATION_NAME}.xn"; 1696130565SobrienEOF 1697130565Sobrienfi 1698130565Sobrienif test -n "$GENERATE_PIE_SCRIPT" ; then 1699130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1700130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1701218822Sdim else if (link_info.pie && link_info.combreloc 1702218822Sdim && link_info.relro && (link_info.flags & DT_BIND_NOW)) 1703218822Sdim return "ldscripts/${EMULATION_NAME}.xdw"; 1704130565Sobrien else if (link_info.pie && link_info.combreloc) 1705130565Sobrien return "ldscripts/${EMULATION_NAME}.xdc"; 1706130565SobrienEOF 1707130565Sobrienfi 1708130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1709130565Sobrien else if (link_info.pie) 1710130565Sobrien return "ldscripts/${EMULATION_NAME}.xd"; 1711130565SobrienEOF 1712130565Sobrienfi 1713130565Sobrienif test -n "$GENERATE_SHLIB_SCRIPT" ; then 1714130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1715130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1716218822Sdim else if (link_info.shared && link_info.combreloc 1717218822Sdim && link_info.relro && (link_info.flags & DT_BIND_NOW)) 1718218822Sdim return "ldscripts/${EMULATION_NAME}.xsw"; 1719130565Sobrien else if (link_info.shared && link_info.combreloc) 1720130565Sobrien return "ldscripts/${EMULATION_NAME}.xsc"; 1721130565SobrienEOF 1722130565Sobrienfi 1723130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 172433965Sjdp else if (link_info.shared) 172533965Sjdp return "ldscripts/${EMULATION_NAME}.xs"; 1726130565SobrienEOF 1727130565Sobrienfi 1728130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1729130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1730218822Sdim else if (link_info.combreloc && link_info.relro 1731218822Sdim && (link_info.flags & DT_BIND_NOW)) 1732218822Sdim return "ldscripts/${EMULATION_NAME}.xw"; 1733130565Sobrien else if (link_info.combreloc) 1734130565Sobrien return "ldscripts/${EMULATION_NAME}.xc"; 1735130565SobrienEOF 1736130565Sobrienfi 1737130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 173833965Sjdp else 173933965Sjdp return "ldscripts/${EMULATION_NAME}.x"; 174033965Sjdp} 174177319Sobrien 174233965SjdpEOF 174377319Sobrienfi 174477319Sobrienfi 174533965Sjdp 174677319Sobrienif test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then 174777319Sobrien 174877319Sobrienif test -n "$PARSE_AND_LIST_PROLOGUE" ; then 174977319Sobriencat >>e${EMULATION_NAME}.c <<EOF 175077319Sobrien $PARSE_AND_LIST_PROLOGUE 175177319SobrienEOF 175233965Sjdpfi 175333965Sjdp 175433965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 175533965Sjdp 175677319Sobrien#define OPTION_DISABLE_NEW_DTAGS (400) 175777319Sobrien#define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1) 175878841Sobrien#define OPTION_GROUP (OPTION_ENABLE_NEW_DTAGS + 1) 175989872Sobrien#define OPTION_EH_FRAME_HDR (OPTION_GROUP + 1) 1760218822Sdim#define OPTION_EXCLUDE_LIBS (OPTION_EH_FRAME_HDR + 1) 1761218822Sdim#define OPTION_HASH_STYLE (OPTION_EXCLUDE_LIBS + 1) 176277319Sobrien 1763130565Sobrienstatic void 1764130565Sobriengld${EMULATION_NAME}_add_options 1765130565Sobrien (int ns, char **shortopts, int nl, struct option **longopts, 1766130565Sobrien int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED) 176777319Sobrien{ 1768130565Sobrien static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:"; 1769130565Sobrien static const struct option xtra_long[] = { 177060525SobrienEOF 177160525Sobrien 177277319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 177360525Sobriencat >>e${EMULATION_NAME}.c <<EOF 1774130565Sobrien {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS}, 1775130565Sobrien {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS}, 1776130565Sobrien {"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR}, 1777218822Sdim {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS}, 1778218822Sdim {"hash-style", required_argument, NULL, OPTION_HASH_STYLE}, 1779130565Sobrien {"Bgroup", no_argument, NULL, OPTION_GROUP}, 178060525SobrienEOF 178177319Sobrienfi 178260525Sobrien 178377319Sobrienif test -n "$PARSE_AND_LIST_LONGOPTS" ; then 178477319Sobriencat >>e${EMULATION_NAME}.c <<EOF 1785130565Sobrien $PARSE_AND_LIST_LONGOPTS 178677319SobrienEOF 178760525Sobrienfi 178860525Sobrien 178960525Sobriencat >>e${EMULATION_NAME}.c <<EOF 1790130565Sobrien {NULL, no_argument, NULL, 0} 1791130565Sobrien }; 179260525Sobrien 1793130565Sobrien *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short)); 1794130565Sobrien memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short)); 1795130565Sobrien *longopts = (struct option *) 1796130565Sobrien xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); 1797130565Sobrien memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); 1798130565Sobrien} 179977319Sobrien 1800130565Sobrienstatic bfd_boolean 1801130565Sobriengld${EMULATION_NAME}_handle_option (int optc) 180233965Sjdp{ 180377319Sobrien switch (optc) 180477319Sobrien { 180577319Sobrien default: 1806130565Sobrien return FALSE; 180777319Sobrien 180877319SobrienEOF 180977319Sobrien 181077319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 181177319Sobriencat >>e${EMULATION_NAME}.c <<EOF 181277319Sobrien case OPTION_DISABLE_NEW_DTAGS: 1813130565Sobrien link_info.new_dtags = FALSE; 181477319Sobrien break; 181577319Sobrien 181677319Sobrien case OPTION_ENABLE_NEW_DTAGS: 1817130565Sobrien link_info.new_dtags = TRUE; 181877319Sobrien break; 181977319Sobrien 182089872Sobrien case OPTION_EH_FRAME_HDR: 1821130565Sobrien link_info.eh_frame_hdr = TRUE; 182289872Sobrien break; 182389872Sobrien 182478841Sobrien case OPTION_GROUP: 182578841Sobrien link_info.flags_1 |= (bfd_vma) DF_1_GROUP; 182678841Sobrien /* Groups must be self-contained. */ 1827130565Sobrien link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR; 1828130565Sobrien link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR; 182978841Sobrien break; 183078841Sobrien 1831218822Sdim case OPTION_EXCLUDE_LIBS: 1832218822Sdim add_excluded_libs (optarg); 1833218822Sdim break; 1834218822Sdim 1835218822Sdim case OPTION_HASH_STYLE: 1836218822Sdim link_info.emit_hash = FALSE; 1837218822Sdim link_info.emit_gnu_hash = FALSE; 1838218822Sdim if (strcmp (optarg, "sysv") == 0) 1839218822Sdim link_info.emit_hash = TRUE; 1840218822Sdim else if (strcmp (optarg, "gnu") == 0) 1841218822Sdim link_info.emit_gnu_hash = TRUE; 1842218822Sdim else if (strcmp (optarg, "both") == 0) 1843218822Sdim { 1844218822Sdim link_info.emit_hash = TRUE; 1845218822Sdim link_info.emit_gnu_hash = TRUE; 1846218822Sdim } 1847218822Sdim else 1848218822Sdim einfo (_("%P%F: invalid hash style \`%s'\n"), optarg); 1849218822Sdim break; 1850218822Sdim 185177319Sobrien case 'z': 185277319Sobrien if (strcmp (optarg, "initfirst") == 0) 185377319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST; 185477319Sobrien else if (strcmp (optarg, "interpose") == 0) 185577319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_INTERPOSE; 185677319Sobrien else if (strcmp (optarg, "loadfltr") == 0) 185777319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_LOADFLTR; 185877319Sobrien else if (strcmp (optarg, "nodefaultlib") == 0) 185977319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODEFLIB; 186077319Sobrien else if (strcmp (optarg, "nodelete") == 0) 186177319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODELETE; 186277319Sobrien else if (strcmp (optarg, "nodlopen") == 0) 186377319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NOOPEN; 186477319Sobrien else if (strcmp (optarg, "nodump") == 0) 186577319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODUMP; 186677319Sobrien else if (strcmp (optarg, "now") == 0) 186777319Sobrien { 186877319Sobrien link_info.flags |= (bfd_vma) DF_BIND_NOW; 186977319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NOW; 187077319Sobrien } 1871218822Sdim else if (strcmp (optarg, "lazy") == 0) 1872218822Sdim { 1873218822Sdim link_info.flags &= ~(bfd_vma) DF_BIND_NOW; 1874218822Sdim link_info.flags_1 &= ~(bfd_vma) DF_1_NOW; 1875218822Sdim } 187677319Sobrien else if (strcmp (optarg, "origin") == 0) 187777319Sobrien { 187877319Sobrien link_info.flags |= (bfd_vma) DF_ORIGIN; 187977319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN; 188077319Sobrien } 188178841Sobrien else if (strcmp (optarg, "defs") == 0) 1882130565Sobrien link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR; 1883104847Sobrien else if (strcmp (optarg, "muldefs") == 0) 1884130565Sobrien link_info.allow_multiple_definition = TRUE; 188589872Sobrien else if (strcmp (optarg, "combreloc") == 0) 1886130565Sobrien link_info.combreloc = TRUE; 188789872Sobrien else if (strcmp (optarg, "nocombreloc") == 0) 1888130565Sobrien link_info.combreloc = FALSE; 188989872Sobrien else if (strcmp (optarg, "nocopyreloc") == 0) 1890130565Sobrien link_info.nocopyreloc = TRUE; 1891130565Sobrien else if (strcmp (optarg, "execstack") == 0) 1892130565Sobrien { 1893130565Sobrien link_info.execstack = TRUE; 1894130565Sobrien link_info.noexecstack = FALSE; 1895130565Sobrien } 1896130565Sobrien else if (strcmp (optarg, "noexecstack") == 0) 1897130565Sobrien { 1898130565Sobrien link_info.noexecstack = TRUE; 1899130565Sobrien link_info.execstack = FALSE; 1900130565Sobrien } 1901218822SdimEOF 1902218822Sdim 1903218822Sdim if test -n "$COMMONPAGESIZE"; then 1904218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 1905218822Sdim else if (strcmp (optarg, "relro") == 0) 1906218822Sdim link_info.relro = TRUE; 1907218822Sdim else if (strcmp (optarg, "norelro") == 0) 1908218822Sdim link_info.relro = FALSE; 1909218822SdimEOF 1910218822Sdim fi 1911218822Sdim 1912218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 1913218822Sdim else if (CONST_STRNEQ (optarg, "max-page-size=")) 1914218822Sdim { 1915218822Sdim char *end; 1916218822Sdim 1917218822Sdim config.maxpagesize = strtoul (optarg + 14, &end, 0); 1918218822Sdim if (*end || (config.maxpagesize & (config.maxpagesize - 1)) != 0) 1919218822Sdim einfo (_("%P%F: invalid maxium page size \`%s'\n"), 1920218822Sdim optarg + 14); 1921218822Sdim ASSERT (default_target != NULL); 1922218822Sdim bfd_emul_set_maxpagesize (default_target, config.maxpagesize); 1923218822Sdim } 1924218822Sdim else if (CONST_STRNEQ (optarg, "common-page-size=")) 1925218822Sdim { 1926218822Sdim char *end; 1927218822Sdim config.commonpagesize = strtoul (optarg + 17, &end, 0); 1928218822Sdim if (*end 1929218822Sdim || (config.commonpagesize & (config.commonpagesize - 1)) != 0) 1930218822Sdim einfo (_("%P%F: invalid common page size \`%s'\n"), 1931218822Sdim optarg + 17); 1932218822Sdim ASSERT (default_target != NULL); 1933218822Sdim bfd_emul_set_commonpagesize (default_target, 1934218822Sdim config.commonpagesize); 1935218822Sdim } 193677319Sobrien /* What about the other Solaris -z options? FIXME. */ 193777319Sobrien break; 193877319SobrienEOF 193977319Sobrienfi 194077319Sobrien 194177319Sobrienif test -n "$PARSE_AND_LIST_ARGS_CASES" ; then 194277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 194377319Sobrien $PARSE_AND_LIST_ARGS_CASES 194477319SobrienEOF 194577319Sobrienfi 194677319Sobrien 194777319Sobriencat >>e${EMULATION_NAME}.c <<EOF 194877319Sobrien } 194977319Sobrien 1950130565Sobrien return TRUE; 195177319Sobrien} 195277319Sobrien 195377319SobrienEOF 195477319Sobrien 195577319Sobrienif test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then 195677319Sobriencat >>e${EMULATION_NAME}.c <<EOF 195777319Sobrien 195877319Sobrienstatic void 1959130565Sobriengld${EMULATION_NAME}_list_options (FILE * file) 196077319Sobrien{ 196177319SobrienEOF 196277319Sobrien 196377319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 196477319Sobriencat >>e${EMULATION_NAME}.c <<EOF 196578841Sobrien fprintf (file, _(" -Bgroup\t\tSelects group name lookup rules for DSO\n")); 196677319Sobrien fprintf (file, _(" --disable-new-dtags\tDisable new dynamic tags\n")); 196777319Sobrien fprintf (file, _(" --enable-new-dtags\tEnable new dynamic tags\n")); 196889872Sobrien fprintf (file, _(" --eh-frame-hdr\tCreate .eh_frame_hdr section\n")); 1969218822Sdim fprintf (file, _(" --hash-style=STYLE\tSet hash style to sysv, gnu or both\n")); 197089872Sobrien fprintf (file, _(" -z combreloc\t\tMerge dynamic relocs into one section and sort\n")); 1971130565Sobrien fprintf (file, _(" -z defs\t\tReport unresolved symbols in object files.\n")); 1972130565Sobrien fprintf (file, _(" -z execstack\t\tMark executable as requiring executable stack\n")); 197377319Sobrien fprintf (file, _(" -z initfirst\t\tMark DSO to be initialized first at runtime\n")); 197477319Sobrien fprintf (file, _(" -z interpose\t\tMark object to interpose all DSOs but executable\n")); 1975218822Sdim fprintf (file, _(" -z lazy\t\tMark object lazy runtime binding (default)\n")); 197677319Sobrien fprintf (file, _(" -z loadfltr\t\tMark object requiring immediate process\n")); 1977104847Sobrien fprintf (file, _(" -z muldefs\t\tAllow multiple definitions\n")); 197889872Sobrien fprintf (file, _(" -z nocombreloc\tDon't merge dynamic relocs into one section\n")); 197989872Sobrien fprintf (file, _(" -z nocopyreloc\tDon't create copy relocs\n")); 198077319Sobrien fprintf (file, _(" -z nodefaultlib\tMark object not to use default search paths\n")); 198177319Sobrien fprintf (file, _(" -z nodelete\t\tMark DSO non-deletable at runtime\n")); 198277319Sobrien fprintf (file, _(" -z nodlopen\t\tMark DSO not available to dlopen\n")); 198377319Sobrien fprintf (file, _(" -z nodump\t\tMark DSO not available to dldump\n")); 1984130565Sobrien fprintf (file, _(" -z noexecstack\tMark executable as not requiring executable stack\n")); 1985218822SdimEOF 1986218822Sdim 1987218822Sdim if test -n "$COMMONPAGESIZE"; then 1988218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 1989218822Sdim fprintf (file, _(" -z norelro\t\tDon't create RELRO program header\n")); 1990218822SdimEOF 1991218822Sdim fi 1992218822Sdim 1993218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 199477319Sobrien fprintf (file, _(" -z now\t\tMark object non-lazy runtime binding\n")); 199589872Sobrien fprintf (file, _(" -z origin\t\tMark object requiring immediate \$ORIGIN processing\n\t\t\t at runtime\n")); 1996218822SdimEOF 1997218822Sdim 1998218822Sdim if test -n "$COMMONPAGESIZE"; then 1999218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 2000218822Sdim fprintf (file, _(" -z relro\t\tCreate RELRO program header\n")); 2001218822SdimEOF 2002218822Sdim fi 2003218822Sdim 2004218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 2005218822Sdim fprintf (file, _(" -z max-page-size=SIZE\tSet maximum page size to SIZE\n")); 2006218822Sdim fprintf (file, _(" -z common-page-size=SIZE\n\t\t\tSet common page size to SIZE\n")); 200777319Sobrien fprintf (file, _(" -z KEYWORD\t\tIgnored for Solaris compatibility\n")); 200877319SobrienEOF 200977319Sobrienfi 201077319Sobrien 201177319Sobrienif test -n "$PARSE_AND_LIST_OPTIONS" ; then 201277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 201377319Sobrien $PARSE_AND_LIST_OPTIONS 201477319SobrienEOF 201577319Sobrienfi 201677319Sobrien 201777319Sobriencat >>e${EMULATION_NAME}.c <<EOF 201877319Sobrien} 201977319SobrienEOF 202077319Sobrien 202177319Sobrienif test -n "$PARSE_AND_LIST_EPILOGUE" ; then 202277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 202377319Sobrien $PARSE_AND_LIST_EPILOGUE 202477319SobrienEOF 202577319Sobrienfi 202677319Sobrienfi 202777319Sobrienelse 202877319Sobriencat >>e${EMULATION_NAME}.c <<EOF 2029130565Sobrien#define gld${EMULATION_NAME}_add_options NULL 2030130565Sobrien#define gld${EMULATION_NAME}_handle_option NULL 203177319SobrienEOF 203277319Sobrienif test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then 203377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 203477319Sobrien#define gld${EMULATION_NAME}_list_options NULL 203577319SobrienEOF 203677319Sobrienfi 203777319Sobrienfi 203877319Sobrien 203977319Sobriencat >>e${EMULATION_NAME}.c <<EOF 204077319Sobrien 204177319Sobrienstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 204277319Sobrien{ 204377319Sobrien ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse}, 204477319Sobrien ${LDEMUL_SYSLIB-syslib_default}, 204577319Sobrien ${LDEMUL_HLL-hll_default}, 204677319Sobrien ${LDEMUL_AFTER_PARSE-after_parse_default}, 204777319Sobrien ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open}, 204877319Sobrien ${LDEMUL_AFTER_ALLOCATION-after_allocation_default}, 204977319Sobrien ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default}, 205077319Sobrien ${LDEMUL_CHOOSE_TARGET-ldemul_default_target}, 205177319Sobrien ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation}, 205277319Sobrien ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, 205333965Sjdp "${EMULATION_NAME}", 205433965Sjdp "${OUTPUT_FORMAT}", 205589872Sobrien ${LDEMUL_FINISH-gld${EMULATION_NAME}_finish}, 205677319Sobrien ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, 205777319Sobrien ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive}, 205877319Sobrien ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan}, 205977319Sobrien ${LDEMUL_SET_SYMBOLS-NULL}, 2060130565Sobrien ${LDEMUL_PARSE_ARGS-NULL}, 2061130565Sobrien gld${EMULATION_NAME}_add_options, 2062130565Sobrien gld${EMULATION_NAME}_handle_option, 206377319Sobrien ${LDEMUL_UNRECOGNIZED_FILE-NULL}, 206477319Sobrien ${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options}, 2065130565Sobrien ${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols}, 206677319Sobrien ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL}, 2067104847Sobrien ${LDEMUL_NEW_VERS_PATTERN-NULL} 206833965Sjdp}; 206933965SjdpEOF 2070