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 544271103Stijlgld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l, 545271103Stijl int force) 54642372Speter{ 547130565Sobrien static bfd_boolean initialized; 54842372Speter static char *ld_elf_hints; 549218822Sdim struct dt_needed needed; 55042372Speter 551218822Sdim if (!initialized) 55242372Speter { 55342372Speter FILE *f; 554130565Sobrien char *tmppath; 55542372Speter 556130565Sobrien tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, NULL); 557130565Sobrien f = fopen (tmppath, FOPEN_RB); 558130565Sobrien free (tmppath); 55942372Speter if (f != NULL) 56042372Speter { 56142372Speter struct elfhints_hdr hdr; 56242372Speter 563218822Sdim if (fread (&hdr, 1, sizeof (hdr), f) == sizeof (hdr) 564218822Sdim && hdr.magic == ELFHINTS_MAGIC 565218822Sdim && hdr.version == 1) 56642372Speter { 567218822Sdim if (fseek (f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1) 56842372Speter { 56942372Speter char *b; 57042372Speter 571218822Sdim b = xmalloc (hdr.dirlistlen + 1); 572218822Sdim if (fread (b, 1, hdr.dirlistlen + 1, f) == 57342372Speter hdr.dirlistlen + 1) 574218822Sdim ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b); 575218822Sdim 576218822Sdim free (b); 57742372Speter } 57842372Speter } 57942372Speter fclose (f); 58042372Speter } 58142372Speter 582130565Sobrien initialized = TRUE; 58342372Speter } 58442372Speter 58542372Speter if (ld_elf_hints == NULL) 586130565Sobrien return FALSE; 58742372Speter 588271103Stijl needed.by = l->by; 589271103Stijl needed.name = l->name; 590271103Stijl return gld${EMULATION_NAME}_search_needed (ld_elf_hints, &needed, 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 762271103Stijlgld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l, 763271103Stijl int force) 764218822Sdim{ 765218822Sdim static bfd_boolean initialized; 766218822Sdim static char *ld_so_conf; 767218822Sdim struct dt_needed needed; 76833965Sjdp 769218822Sdim if (! initialized) 770218822Sdim { 771218822Sdim char *tmppath; 772218822Sdim struct gld${EMULATION_NAME}_ld_so_conf info; 773130565Sobrien 774218822Sdim info.path = NULL; 775218822Sdim info.len = info.alloc = 0; 776218822Sdim tmppath = concat (ld_sysroot, "${prefix}/etc/ld.so.conf", NULL); 777218822Sdim if (!gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath)) 778218822Sdim { 779218822Sdim free (tmppath); 780218822Sdim tmppath = concat (ld_sysroot, "/etc/ld.so.conf", NULL); 781218822Sdim gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath); 78233965Sjdp } 783218822Sdim free (tmppath); 78433965Sjdp 785218822Sdim if (info.path) 786218822Sdim { 787218822Sdim char *d = gld${EMULATION_NAME}_add_sysroot (info.path); 788218822Sdim free (info.path); 789218822Sdim ld_so_conf = d; 790218822Sdim } 791130565Sobrien initialized = TRUE; 79233965Sjdp } 79333965Sjdp 79433965Sjdp if (ld_so_conf == NULL) 795130565Sobrien return FALSE; 79633965Sjdp 797218822Sdim 798271103Stijl needed.by = l->by; 799271103Stijl needed.name = l->name; 800218822Sdim return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force); 80133965Sjdp} 80260525Sobrien 80333965SjdpEOF 804130565Sobrien # Linux 805130565Sobrien ;; 80660525Sobrien esac 80733965Sjdpfi 80833965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 80933965Sjdp 81077319Sobrien/* See if an input file matches a DT_NEEDED entry by name. */ 81133965Sjdp 81277319Sobrienstatic void 813130565Sobriengld${EMULATION_NAME}_check_needed (lang_input_statement_type *s) 81477319Sobrien{ 815218822Sdim const char *soname; 816218822Sdim 817218822Sdim /* Stop looking if we've found a loaded lib. */ 818218822Sdim if (global_found != NULL 819218822Sdim && (bfd_elf_get_dyn_lib_class (global_found->the_bfd) 820218822Sdim & DYN_AS_NEEDED) == 0) 82177319Sobrien return; 82233965Sjdp 823218822Sdim if (s->filename == NULL || s->the_bfd == NULL) 824218822Sdim return; 82577319Sobrien 826218822Sdim /* Don't look for a second non-loaded as-needed lib. */ 827218822Sdim if (global_found != NULL 828218822Sdim && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0) 829218822Sdim return; 83077319Sobrien 831218822Sdim if (strcmp (s->filename, global_needed->name) == 0) 832218822Sdim { 833218822Sdim global_found = s; 834218822Sdim return; 83577319Sobrien } 83677319Sobrien 837218822Sdim if (s->search_dirs_flag) 83877319Sobrien { 839218822Sdim const char *f = strrchr (s->filename, '/'); 840218822Sdim if (f != NULL 841218822Sdim && strcmp (f + 1, global_needed->name) == 0) 84277319Sobrien { 843218822Sdim global_found = s; 84477319Sobrien return; 84577319Sobrien } 84677319Sobrien } 847218822Sdim 848218822Sdim soname = bfd_elf_get_dt_soname (s->the_bfd); 849218822Sdim if (soname != NULL 850218822Sdim && strcmp (soname, global_needed->name) == 0) 851218822Sdim { 852218822Sdim global_found = s; 853218822Sdim return; 854218822Sdim } 85577319Sobrien} 85677319Sobrien 85777319SobrienEOF 85877319Sobrien 85977319Sobrienif test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then 86077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 86177319Sobrien 86233965Sjdp/* This is called after all the input files have been opened. */ 86333965Sjdp 86433965Sjdpstatic void 865130565Sobriengld${EMULATION_NAME}_after_open (void) 86633965Sjdp{ 86733965Sjdp struct bfd_link_needed_list *needed, *l; 86833965Sjdp 869218822Sdim if (link_info.eh_frame_hdr 870218822Sdim && ! link_info.traditional_format 871218822Sdim && ! link_info.relocatable) 872218822Sdim { 873218822Sdim struct elf_link_hash_table *htab; 874218822Sdim 875218822Sdim htab = elf_hash_table (&link_info); 876218822Sdim if (is_elf_hash_table (htab)) 877218822Sdim { 878218822Sdim bfd *abfd; 879218822Sdim asection *s; 880218822Sdim 881218822Sdim for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next) 882218822Sdim { 883218822Sdim s = bfd_get_section_by_name (abfd, ".eh_frame"); 884218822Sdim if (s && s->size > 8 && !bfd_is_abs_section (s->output_section)) 885218822Sdim break; 886218822Sdim } 887218822Sdim if (abfd) 888218822Sdim { 889218822Sdim const struct elf_backend_data *bed; 890218822Sdim 891218822Sdim bed = get_elf_backend_data (abfd); 892218822Sdim s = bfd_make_section_with_flags (abfd, ".eh_frame_hdr", 893218822Sdim bed->dynamic_sec_flags 894218822Sdim | SEC_READONLY); 895218822Sdim if (s != NULL 896218822Sdim && bfd_set_section_alignment (abfd, s, 2)) 897218822Sdim htab->eh_info.hdr_sec = s; 898218822Sdim else 899218822Sdim einfo ("%P: warning: Cannot create .eh_frame_hdr section," 900218822Sdim " --eh-frame-hdr ignored.\n"); 901218822Sdim } 902218822Sdim } 903218822Sdim } 904218822Sdim 90533965Sjdp /* We only need to worry about this when doing a final link. */ 906130565Sobrien if (link_info.relocatable || !link_info.executable) 90733965Sjdp return; 90833965Sjdp 90933965Sjdp /* Get the list of files which appear in DT_NEEDED entries in 91033965Sjdp dynamic objects included in the link (often there will be none). 91133965Sjdp For each such file, we want to track down the corresponding 91233965Sjdp library, and include the symbol table in the link. This is what 91333965Sjdp the runtime dynamic linker will do. Tracking the files down here 91433965Sjdp permits one dynamic object to include another without requiring 91533965Sjdp special action by the person doing the link. Note that the 91633965Sjdp needed list can actually grow while we are stepping through this 91733965Sjdp loop. */ 91833965Sjdp needed = bfd_elf_get_needed_list (output_bfd, &link_info); 91933965Sjdp for (l = needed; l != NULL; l = l->next) 92033965Sjdp { 92133965Sjdp struct bfd_link_needed_list *ll; 922218822Sdim struct dt_needed n, nn; 92338889Sjdp int force; 92433965Sjdp 925218822Sdim /* If the lib that needs this one was --as-needed and wasn't 926218822Sdim found to be needed, then this lib isn't needed either. */ 927218822Sdim if (l->by != NULL 928218822Sdim && (bfd_elf_get_dyn_lib_class (l->by) & DYN_AS_NEEDED) != 0) 929218822Sdim continue; 930218822Sdim 93133965Sjdp /* If we've already seen this file, skip it. */ 93233965Sjdp for (ll = needed; ll != l; ll = ll->next) 933218822Sdim if ((ll->by == NULL 934218822Sdim || (bfd_elf_get_dyn_lib_class (ll->by) & DYN_AS_NEEDED) == 0) 935218822Sdim && strcmp (ll->name, l->name) == 0) 93633965Sjdp break; 93733965Sjdp if (ll != l) 93833965Sjdp continue; 93933965Sjdp 94033965Sjdp /* See if this file was included in the link explicitly. */ 94133965Sjdp global_needed = l; 942218822Sdim global_found = NULL; 94333965Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); 944218822Sdim if (global_found != NULL 945218822Sdim && (bfd_elf_get_dyn_lib_class (global_found->the_bfd) 946218822Sdim & DYN_AS_NEEDED) == 0) 94733965Sjdp continue; 94833965Sjdp 949218822Sdim n.by = l->by; 950218822Sdim n.name = l->name; 951218822Sdim nn.by = l->by; 95277319Sobrien if (trace_file_tries) 95377319Sobrien info_msg (_("%s needed by %B\n"), l->name, l->by); 95477319Sobrien 955218822Sdim /* As-needed libs specified on the command line (or linker script) 956218822Sdim take priority over libs found in search dirs. */ 957218822Sdim if (global_found != NULL) 958218822Sdim { 959218822Sdim nn.name = global_found->filename; 960218822Sdim if (gld${EMULATION_NAME}_try_needed (&nn, TRUE)) 961218822Sdim continue; 962218822Sdim } 963218822Sdim 96433965Sjdp /* We need to find this file and include the symbol table. We 96533965Sjdp want to search for the file in the same way that the dynamic 96633965Sjdp linker will search. That means that we want to use 96733965Sjdp rpath_link, rpath, then the environment variable 96877319Sobrien LD_LIBRARY_PATH (native only), then the DT_RPATH/DT_RUNPATH 96977319Sobrien entries (native only), then the linker script LIB_SEARCH_DIRS. 97077319Sobrien We do not search using the -L arguments. 97138889Sjdp 97238889Sjdp We search twice. The first time, we skip objects which may 97338889Sjdp introduce version mismatches. The second time, we force 97438889Sjdp their use. See gld${EMULATION_NAME}_vercheck comment. */ 97538889Sjdp for (force = 0; force < 2; force++) 97633965Sjdp { 97738889Sjdp size_t len; 97838889Sjdp search_dirs_type *search; 97977319SobrienEOF 980218822Sdimif [ "x${NATIVE}" = xyes ] ; then 981218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 982218822Sdim const char *lib_path; 983218822SdimEOF 984218822Sdimfi 985130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 98677319Sobriencat >>e${EMULATION_NAME}.c <<EOF 98777319Sobrien struct bfd_link_needed_list *rp; 98877319Sobrien int found; 98977319SobrienEOF 99077319Sobrienfi 99177319Sobriencat >>e${EMULATION_NAME}.c <<EOF 99238889Sjdp 99338889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, 994218822Sdim &n, force)) 99538889Sjdp break; 99677319SobrienEOF 997130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 99877319Sobriencat >>e${EMULATION_NAME}.c <<EOF 99938889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath, 1000218822Sdim &n, force)) 100138889Sjdp break; 1002130565SobrienEOF 1003130565Sobrienfi 1004130565Sobrienif [ "x${NATIVE}" = xyes ] ; then 1005130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 100638889Sjdp if (command_line.rpath_link == NULL 100738889Sjdp && command_line.rpath == NULL) 100838889Sjdp { 100938889Sjdp lib_path = (const char *) getenv ("LD_RUN_PATH"); 1010218822Sdim if (gld${EMULATION_NAME}_search_needed (lib_path, &n, 101138889Sjdp force)) 101238889Sjdp break; 101338889Sjdp } 101438889Sjdp lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); 1015218822Sdim if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force)) 101638889Sjdp break; 1017130565SobrienEOF 1018130565Sobrienfi 1019130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 1020130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 102177319Sobrien found = 0; 102277319Sobrien rp = bfd_elf_get_runpath_list (output_bfd, &link_info); 102377319Sobrien for (; !found && rp != NULL; rp = rp->next) 102477319Sobrien { 1025130565Sobrien char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name); 102677319Sobrien found = (rp->by == l->by 1027130565Sobrien && gld${EMULATION_NAME}_search_needed (tmpname, 1028218822Sdim &n, 102977319Sobrien force)); 1030130565Sobrien free (tmpname); 103177319Sobrien } 103277319Sobrien if (found) 103377319Sobrien break; 103477319Sobrien 103533965SjdpEOF 103633965Sjdpfi 1037130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 1038130565Sobrien case ${target} in 1039218822Sdim *-*-freebsd* | *-*-dragonfly*) 1040130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 1041271103Stijl if (gld${EMULATION_NAME}_check_ld_elf_hints (l, force)) 104242372Speter break; 104342372SpeterEOF 1044130565Sobrien # FreeBSD 1045130565Sobrien ;; 1046130565Sobrien 1047218822Sdim *-*-linux-* | *-*-k*bsd*-*) 1048218822Sdim # Linux 1049130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 1050271103Stijl if (gld${EMULATION_NAME}_check_ld_so_conf (l, force)) 105138889Sjdp break; 1052218822Sdim 105333965SjdpEOF 1054130565Sobrien ;; 105560525Sobrien esac 105633965Sjdpfi 105733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 1058218822Sdim len = strlen (l->name); 1059218822Sdim for (search = search_head; search != NULL; search = search->next) 1060218822Sdim { 1061218822Sdim char *filename; 1062218822Sdim 1063218822Sdim if (search->cmdline) 1064218822Sdim continue; 1065218822Sdim filename = (char *) xmalloc (strlen (search->name) + len + 2); 1066218822Sdim sprintf (filename, "%s/%s", search->name, l->name); 1067218822Sdim nn.name = filename; 1068218822Sdim if (gld${EMULATION_NAME}_try_needed (&nn, force)) 1069218822Sdim break; 1070218822Sdim free (filename); 1071218822Sdim } 1072218822Sdim if (search != NULL) 1073218822Sdim break; 1074218822SdimEOF 1075218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 107638889Sjdp } 107733965Sjdp 107838889Sjdp if (force < 2) 107938889Sjdp continue; 108038889Sjdp 108168778Sobrien einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n", 108233965Sjdp l->name, l->by); 108333965Sjdp } 108433965Sjdp} 108533965Sjdp 108638889SjdpEOF 108777319Sobrienfi 108838889Sjdp 108938889Sjdpcat >>e${EMULATION_NAME}.c <<EOF 109038889Sjdp 109177319Sobrien/* Look through an expression for an assignment statement. */ 109233965Sjdp 109333965Sjdpstatic void 1094130565Sobriengld${EMULATION_NAME}_find_exp_assignment (etree_type *exp) 109533965Sjdp{ 1096218822Sdim bfd_boolean provide = FALSE; 109733965Sjdp 109877319Sobrien switch (exp->type.node_class) 109933965Sjdp { 110077319Sobrien case etree_provide: 1101218822Sdim provide = TRUE; 1102218822Sdim /* Fall thru */ 1103218822Sdim case etree_assign: 110477319Sobrien /* We call record_link_assignment even if the symbol is defined. 110577319Sobrien This is because if it is defined by a dynamic object, we 110677319Sobrien actually want to use the value defined by the linker script, 110777319Sobrien not the value from the dynamic object (because we are setting 110877319Sobrien symbols like etext). If the symbol is defined by a regular 110977319Sobrien object, then, as it happens, calling record_link_assignment 111077319Sobrien will do no harm. */ 111177319Sobrien if (strcmp (exp->assign.dst, ".") != 0) 111233965Sjdp { 1113218822Sdim if (!bfd_elf_record_link_assignment (output_bfd, &link_info, 1114218822Sdim exp->assign.dst, provide, 1115218822Sdim exp->assign.hidden)) 111677319Sobrien einfo ("%P%F: failed to record assignment to %s: %E\n", 111777319Sobrien exp->assign.dst); 111833965Sjdp } 111977319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); 112077319Sobrien break; 112133965Sjdp 112277319Sobrien case etree_binary: 112377319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); 112477319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); 112577319Sobrien break; 112633965Sjdp 112777319Sobrien case etree_trinary: 112877319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); 112977319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); 113077319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); 113177319Sobrien break; 113233965Sjdp 113377319Sobrien case etree_unary: 113477319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); 113577319Sobrien break; 113633965Sjdp 113777319Sobrien default: 113877319Sobrien break; 113933965Sjdp } 114033965Sjdp} 114133965Sjdp 114238889Sjdp 114377319Sobrien/* This is called by the before_allocation routine via 114477319Sobrien lang_for_each_statement. It locates any assignment statements, and 114577319Sobrien tells the ELF backend about them, in case they are assignments to 114677319Sobrien symbols which are referred to by dynamic objects. */ 114738889Sjdp 114838889Sjdpstatic void 1149130565Sobriengld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s) 115038889Sjdp{ 115177319Sobrien if (s->header.type == lang_assignment_statement_enum) 115277319Sobrien gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); 115377319Sobrien} 115438889Sjdp 115577319SobrienEOF 115638889Sjdp 115777319Sobrienif test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then 115889872Sobrien if test x"${ELF_INTERPRETER_NAME+set}" = xset; then 115989872Sobrien ELF_INTERPRETER_SET_DEFAULT=" 116089872Sobrien if (sinterp != NULL) 116189872Sobrien { 1162218822Sdim sinterp->contents = (unsigned char *) ${ELF_INTERPRETER_NAME}; 1163218822Sdim sinterp->size = strlen ((char *) sinterp->contents) + 1; 116489872Sobrien } 116589872Sobrien 116689872Sobrien" 116789872Sobrien else 116889872Sobrien ELF_INTERPRETER_SET_DEFAULT= 116989872Sobrien fi 117077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 117138889Sjdp 117233965Sjdp/* This is called after the sections have been attached to output 117333965Sjdp sections, but before any sizes or addresses have been set. */ 117433965Sjdp 117533965Sjdpstatic void 1176130565Sobriengld${EMULATION_NAME}_before_allocation (void) 117733965Sjdp{ 117833965Sjdp const char *rpath; 117933965Sjdp asection *sinterp; 118033965Sjdp 1181130565Sobrien if (link_info.hash->type == bfd_link_elf_hash_table) 1182130565Sobrien _bfd_elf_tls_setup (output_bfd, &link_info); 1183130565Sobrien 118433965Sjdp /* If we are going to make any variable assignments, we need to let 118533965Sjdp the ELF backend know about them in case the variables are 118633965Sjdp referred to by dynamic objects. */ 118733965Sjdp lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment); 118833965Sjdp 118933965Sjdp /* Let the ELF backend work out the sizes of any sections required 119033965Sjdp by dynamic linking. */ 119133965Sjdp rpath = command_line.rpath; 119233965Sjdp if (rpath == NULL) 119333965Sjdp rpath = (const char *) getenv ("LD_RUN_PATH"); 1194130565Sobrien if (! (bfd_elf_size_dynamic_sections 1195130565Sobrien (output_bfd, command_line.soname, rpath, 119689872Sobrien command_line.filter_shlib, 119733965Sjdp (const char * const *) command_line.auxiliary_filters, 119833965Sjdp &link_info, &sinterp, lang_elf_version_info))) 119933965Sjdp einfo ("%P%F: failed to set dynamic section sizes: %E\n"); 1200218822Sdim 120189872Sobrien${ELF_INTERPRETER_SET_DEFAULT} 120233965Sjdp /* Let the user override the dynamic linker we are using. */ 120333965Sjdp if (command_line.interpreter != NULL 120433965Sjdp && sinterp != NULL) 120533965Sjdp { 120633965Sjdp sinterp->contents = (bfd_byte *) command_line.interpreter; 1207218822Sdim sinterp->size = strlen (command_line.interpreter) + 1; 120833965Sjdp } 120933965Sjdp 121033965Sjdp /* Look for any sections named .gnu.warning. As a GNU extensions, 121133965Sjdp we treat such sections as containing warning messages. We print 121233965Sjdp out the warning message, and then zero out the section size so 121333965Sjdp that it does not get copied into the output file. */ 121433965Sjdp 121533965Sjdp { 121633965Sjdp LANG_FOR_EACH_INPUT_STATEMENT (is) 121733965Sjdp { 121833965Sjdp asection *s; 121933965Sjdp bfd_size_type sz; 122033965Sjdp char *msg; 1221130565Sobrien bfd_boolean ret; 122233965Sjdp 122333965Sjdp if (is->just_syms_flag) 122433965Sjdp continue; 122533965Sjdp 122633965Sjdp s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning"); 122733965Sjdp if (s == NULL) 122833965Sjdp continue; 122933965Sjdp 1230218822Sdim sz = s->size; 1231218822Sdim msg = xmalloc ((size_t) (sz + 1)); 1232218822Sdim if (! bfd_get_section_contents (is->the_bfd, s, msg, 1233130565Sobrien (file_ptr) 0, sz)) 123433965Sjdp einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", 123533965Sjdp is->the_bfd); 1236218822Sdim msg[sz] = '\0'; 123733965Sjdp ret = link_info.callbacks->warning (&link_info, msg, 123833965Sjdp (const char *) NULL, 123933965Sjdp is->the_bfd, (asection *) NULL, 124033965Sjdp (bfd_vma) 0); 124133965Sjdp ASSERT (ret); 124233965Sjdp free (msg); 124333965Sjdp 1244218822Sdim /* Clobber the section size, so that we don't waste space 1245218822Sdim copying the warning into the output file. If we've already 1246218822Sdim sized the output section, adjust its size. The adjustment 1247218822Sdim is on rawsize because targets that size sections early will 1248218822Sdim have called lang_reset_memory_regions after sizing. */ 1249218822Sdim if (s->output_section != NULL 1250218822Sdim && s->output_section->rawsize >= s->size) 1251218822Sdim s->output_section->rawsize -= s->size; 1252218822Sdim 1253218822Sdim s->size = 0; 1254218822Sdim 1255218822Sdim /* Also set SEC_EXCLUDE, so that local symbols defined in the 1256218822Sdim warning section don't get copied to the output. */ 1257218822Sdim s->flags |= SEC_EXCLUDE | SEC_KEEP; 125833965Sjdp } 125933965Sjdp } 1260218822Sdim 1261218822Sdim before_allocation_default (); 1262218822Sdim 1263218822Sdim if (!bfd_elf_size_dynsym_hash_dynstr (output_bfd, &link_info)) 1264218822Sdim einfo ("%P%F: failed to set dynamic section sizes: %E\n"); 126533965Sjdp} 126633965Sjdp 126777319SobrienEOF 126877319Sobrienfi 126933965Sjdp 127077319Sobrienif test x"$LDEMUL_OPEN_DYNAMIC_ARCHIVE" != xgld"$EMULATION_NAME"_open_dynamic_archive; then 127177319Sobriencat >>e${EMULATION_NAME}.c <<EOF 127233965Sjdp 127377319Sobrien/* Try to open a dynamic archive. This is where we know that ELF 127477319Sobrien dynamic libraries have an extension of .so (or .sl on oddball systems 127577319Sobrien like hpux). */ 127633965Sjdp 1277130565Sobrienstatic bfd_boolean 1278130565Sobriengld${EMULATION_NAME}_open_dynamic_archive 1279130565Sobrien (const char *arch, search_dirs_type *search, lang_input_statement_type *entry) 128033965Sjdp{ 128177319Sobrien const char *filename; 128277319Sobrien char *string; 128333965Sjdp 128477319Sobrien if (! entry->is_archive) 1285130565Sobrien return FALSE; 128677319Sobrien 128777319Sobrien filename = entry->filename; 128877319Sobrien 128977319Sobrien /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION 129077319Sobrien is defined, but it does not seem worth the headache to optimize 129177319Sobrien away those two bytes of space. */ 129277319Sobrien string = (char *) xmalloc (strlen (search->name) 129377319Sobrien + strlen (filename) 129477319Sobrien + strlen (arch) 129577319Sobrien#ifdef EXTRA_SHLIB_EXTENSION 129677319Sobrien + strlen (EXTRA_SHLIB_EXTENSION) 129777319Sobrien#endif 129877319Sobrien + sizeof "/lib.so"); 129977319Sobrien 130077319Sobrien sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); 130177319Sobrien 130277319Sobrien#ifdef EXTRA_SHLIB_EXTENSION 130377319Sobrien /* Try the .so extension first. If that fails build a new filename 130477319Sobrien using EXTRA_SHLIB_EXTENSION. */ 130577319Sobrien if (! ldfile_try_open_bfd (string, entry)) 130677319Sobrien sprintf (string, "%s/lib%s%s%s", search->name, 130777319Sobrien filename, arch, EXTRA_SHLIB_EXTENSION); 130877319Sobrien#endif 130977319Sobrien 131077319Sobrien if (! ldfile_try_open_bfd (string, entry)) 131133965Sjdp { 131277319Sobrien free (string); 1313130565Sobrien return FALSE; 131477319Sobrien } 131533965Sjdp 131677319Sobrien entry->filename = string; 131733965Sjdp 131877319Sobrien /* We have found a dynamic object to include in the link. The ELF 131977319Sobrien backend linker will create a DT_NEEDED entry in the .dynamic 132077319Sobrien section naming this file. If this file includes a DT_SONAME 132177319Sobrien entry, it will be used. Otherwise, the ELF linker will just use 132277319Sobrien the name of the file. For an archive found by searching, like 132377319Sobrien this one, the DT_NEEDED entry should consist of just the name of 132477319Sobrien the file, without the path information used to find it. Note 132577319Sobrien that we only need to do this if we have a dynamic object; an 132677319Sobrien archive will never be referenced by a DT_NEEDED entry. 132733965Sjdp 132877319Sobrien FIXME: This approach--using bfd_elf_set_dt_needed_name--is not 132977319Sobrien very pretty. I haven't been able to think of anything that is 133077319Sobrien pretty, though. */ 133177319Sobrien if (bfd_check_format (entry->the_bfd, bfd_object) 133277319Sobrien && (entry->the_bfd->flags & DYNAMIC) != 0) 133377319Sobrien { 133477319Sobrien ASSERT (entry->is_archive && entry->search_dirs_flag); 133533965Sjdp 133677319Sobrien /* Rather than duplicating the logic above. Just use the 133778841Sobrien filename we recorded earlier. */ 133833965Sjdp 133992835Sobrien filename = lbasename (entry->filename); 134078841Sobrien bfd_elf_set_dt_needed_name (entry->the_bfd, filename); 134133965Sjdp } 134277319Sobrien 1343130565Sobrien return TRUE; 134433965Sjdp} 134533965Sjdp 134677319SobrienEOF 134777319Sobrienfi 134889872Sobrien 134989872Sobrienif test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then 135077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 135177319Sobrien 1352218822Sdim/* A variant of lang_output_section_find used by place_orphan. */ 135368778Sobrien 135468778Sobrienstatic lang_output_section_statement_type * 1355130565Sobrienoutput_rel_find (asection *sec, int isdyn) 135668778Sobrien{ 135768778Sobrien lang_output_section_statement_type *lookup; 1358107499Sobrien lang_output_section_statement_type *last = NULL; 1359130565Sobrien lang_output_section_statement_type *last_alloc = NULL; 1360107499Sobrien lang_output_section_statement_type *last_rel = NULL; 1361107499Sobrien lang_output_section_statement_type *last_rel_alloc = NULL; 1362107499Sobrien int rela = sec->name[4] == 'a'; 136368778Sobrien 1364218822Sdim for (lookup = &lang_output_section_statement.head->output_section_statement; 1365218822Sdim lookup != NULL; 1366218822Sdim lookup = lookup->next) 136768778Sobrien { 1368218822Sdim if (lookup->constraint != -1 1369218822Sdim && CONST_STRNEQ (lookup->name, ".rel")) 137068778Sobrien { 1371107499Sobrien int lookrela = lookup->name[4] == 'a'; 1372107499Sobrien 1373130565Sobrien /* .rel.dyn must come before all other reloc sections, to suit 1374130565Sobrien GNU ld.so. */ 1375130565Sobrien if (isdyn) 1376107499Sobrien break; 1377130565Sobrien 1378130565Sobrien /* Don't place after .rel.plt as doing so results in wrong 1379130565Sobrien dynamic tags. */ 1380130565Sobrien if (strcmp (".plt", lookup->name + 4 + lookrela) == 0) 1381130565Sobrien break; 1382130565Sobrien 1383130565Sobrien if (rela == lookrela || last_rel == NULL) 1384107499Sobrien last_rel = lookup; 1385130565Sobrien if ((rela == lookrela || last_rel_alloc == NULL) 1386130565Sobrien && lookup->bfd_section != NULL 1387107499Sobrien && (lookup->bfd_section->flags & SEC_ALLOC) != 0) 1388107499Sobrien last_rel_alloc = lookup; 138968778Sobrien } 1390130565Sobrien 1391130565Sobrien last = lookup; 1392130565Sobrien if (lookup->bfd_section != NULL 1393130565Sobrien && (lookup->bfd_section->flags & SEC_ALLOC) != 0) 1394130565Sobrien last_alloc = lookup; 139568778Sobrien } 1396107499Sobrien 1397107499Sobrien if (last_rel_alloc) 1398107499Sobrien return last_rel_alloc; 1399107499Sobrien 1400107499Sobrien if (last_rel) 1401107499Sobrien return last_rel; 1402107499Sobrien 1403130565Sobrien if (last_alloc) 1404130565Sobrien return last_alloc; 1405130565Sobrien 1406107499Sobrien return last; 140768778Sobrien} 140868778Sobrien 140933965Sjdp/* Place an orphan section. We use this to put random SHF_ALLOC 141033965Sjdp sections in the right segment. */ 141133965Sjdp 1412130565Sobrienstatic bfd_boolean 1413218822Sdimgld${EMULATION_NAME}_place_orphan (asection *s) 141433965Sjdp{ 1415218822Sdim static struct orphan_save hold[] = 1416218822Sdim { 1417218822Sdim { ".text", 1418218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE, 1419218822Sdim 0, 0, 0, 0 }, 1420218822Sdim { ".rodata", 1421218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA, 1422218822Sdim 0, 0, 0, 0 }, 1423218822Sdim { ".data", 1424218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA, 1425218822Sdim 0, 0, 0, 0 }, 1426218822Sdim { ".bss", 1427218822Sdim SEC_ALLOC, 1428218822Sdim 0, 0, 0, 0 }, 1429218822Sdim { 0, 1430218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA, 1431218822Sdim 0, 0, 0, 0 }, 1432218822Sdim { ".interp", 1433218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA, 1434218822Sdim 0, 0, 0, 0 }, 1435218822Sdim { ".sdata", 1436218822Sdim SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_SMALL_DATA, 1437218822Sdim 0, 0, 0, 0 } 1438218822Sdim }; 1439218822Sdim enum orphan_save_index 1440218822Sdim { 1441218822Sdim orphan_text = 0, 1442218822Sdim orphan_rodata, 1443218822Sdim orphan_data, 1444218822Sdim orphan_bss, 1445218822Sdim orphan_rel, 1446218822Sdim orphan_interp, 1447218822Sdim orphan_sdata 1448218822Sdim }; 1449218822Sdim static int orphan_init_done = 0; 145068778Sobrien struct orphan_save *place; 145168778Sobrien const char *secname; 1452218822Sdim lang_output_section_statement_type *after; 145333965Sjdp lang_output_section_statement_type *os; 1454107499Sobrien int isdyn = 0; 1455218822Sdim int iself = s->owner->xvec->flavour == bfd_target_elf_flavour; 1456218822Sdim unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL; 145733965Sjdp 145868778Sobrien secname = bfd_get_section_name (s->owner, s); 1459218822Sdim 1460130565Sobrien if (! link_info.relocatable 1461107499Sobrien && link_info.combreloc 1462218822Sdim && (s->flags & SEC_ALLOC)) 1463107499Sobrien { 1464218822Sdim if (iself) 1465218822Sdim switch (sh_type) 1466218822Sdim { 1467218822Sdim case SHT_RELA: 1468218822Sdim secname = ".rela.dyn"; 1469218822Sdim isdyn = 1; 1470218822Sdim break; 1471218822Sdim case SHT_REL: 1472218822Sdim secname = ".rel.dyn"; 1473218822Sdim isdyn = 1; 1474218822Sdim break; 1475218822Sdim default: 1476218822Sdim break; 1477218822Sdim } 1478218822Sdim else if (CONST_STRNEQ (secname, ".rel")) 1479218822Sdim { 1480218822Sdim secname = secname[4] == 'a' ? ".rela.dyn" : ".rel.dyn"; 1481218822Sdim isdyn = 1; 1482218822Sdim } 1483107499Sobrien } 148433965Sjdp 1485218822Sdim if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s))) 148677319Sobrien { 148777319Sobrien /* Look through the script to see where to place this section. */ 148877319Sobrien os = lang_output_section_find (secname); 148933965Sjdp 149077319Sobrien if (os != NULL 149189872Sobrien && (os->bfd_section == NULL 1492218822Sdim || os->bfd_section->flags == 0 1493218822Sdim || (_bfd_elf_match_sections_by_type (output_bfd, 1494218822Sdim os->bfd_section, 1495218822Sdim s->owner, s) 1496218822Sdim && ((s->flags ^ os->bfd_section->flags) 1497218822Sdim & (SEC_LOAD | SEC_ALLOC)) == 0))) 149877319Sobrien { 149989872Sobrien /* We already have an output section statement with this 1500218822Sdim name, and its bfd section, if any, has compatible flags. 1501218822Sdim If the section already exists but does not have any flags 1502218822Sdim set, then it has been created by the linker, probably as a 1503218822Sdim result of a --section-start command line switch. */ 1504218822Sdim lang_add_section (&os->children, s, os); 1505130565Sobrien return TRUE; 150677319Sobrien } 150733965Sjdp } 150833965Sjdp 1509218822Sdim if (!orphan_init_done) 1510218822Sdim { 1511218822Sdim struct orphan_save *ho; 1512218822Sdim for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho) 1513218822Sdim if (ho->name != NULL) 1514218822Sdim { 1515218822Sdim ho->os = lang_output_section_find (ho->name); 1516218822Sdim if (ho->os != NULL && ho->os->flags == 0) 1517218822Sdim ho->os->flags = ho->flags; 1518218822Sdim } 1519218822Sdim orphan_init_done = 1; 1520218822Sdim } 152133965Sjdp 152233965Sjdp /* If this is a final link, then always put .gnu.warning.SYMBOL 152333965Sjdp sections into the .text section to get them out of the way. */ 1524130565Sobrien if (link_info.executable 1525130565Sobrien && ! link_info.relocatable 1526218822Sdim && CONST_STRNEQ (secname, ".gnu.warning.") 1527218822Sdim && hold[orphan_text].os != NULL) 152833965Sjdp { 1529218822Sdim lang_add_section (&hold[orphan_text].os->children, s, 1530218822Sdim hold[orphan_text].os); 1531130565Sobrien return TRUE; 153233965Sjdp } 153333965Sjdp 153433965Sjdp /* Decide which segment the section should go in based on the 153533965Sjdp section name and section flags. We put loadable .note sections 153633965Sjdp right after the .interp section, so that the PT_NOTE segment is 153733965Sjdp stored right after the program headers where the OS can read it 153833965Sjdp in the first page. */ 153968778Sobrien 154068778Sobrien place = NULL; 154168778Sobrien if ((s->flags & SEC_ALLOC) == 0) 154268778Sobrien ; 154360525Sobrien else if ((s->flags & SEC_LOAD) != 0 1544218822Sdim && ((iself && sh_type == SHT_NOTE) 1545218822Sdim || (!iself && CONST_STRNEQ (secname, ".note")))) 1546218822Sdim place = &hold[orphan_interp]; 1547218822Sdim else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) 1548218822Sdim place = &hold[orphan_bss]; 1549218822Sdim else if ((s->flags & SEC_SMALL_DATA) != 0) 1550218822Sdim place = &hold[orphan_sdata]; 1551218822Sdim else if ((s->flags & SEC_READONLY) == 0) 1552218822Sdim place = &hold[orphan_data]; 1553218822Sdim else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL)) 1554218822Sdim || (!iself && CONST_STRNEQ (secname, ".rel"))) 1555218822Sdim && (s->flags & SEC_LOAD) != 0) 1556218822Sdim place = &hold[orphan_rel]; 1557218822Sdim else if ((s->flags & SEC_CODE) == 0) 1558218822Sdim place = &hold[orphan_rodata]; 1559218822Sdim else 1560218822Sdim place = &hold[orphan_text]; 156133965Sjdp 1562218822Sdim after = NULL; 1563218822Sdim if (place != NULL) 1564218822Sdim { 1565218822Sdim if (place->os == NULL) 1566218822Sdim { 1567218822Sdim if (place->name != NULL) 1568218822Sdim place->os = lang_output_section_find (place->name); 1569218822Sdim else 1570218822Sdim place->os = output_rel_find (s, isdyn); 1571218822Sdim } 1572218822Sdim after = place->os; 1573218822Sdim if (after == NULL) 1574218822Sdim after = lang_output_section_find_by_flags 1575218822Sdim (s, &place->os, _bfd_elf_match_sections_by_type); 1576218822Sdim if (after == NULL) 1577218822Sdim /* *ABS* is always the first output section statement. */ 1578218822Sdim after = &lang_output_section_statement.head->output_section_statement; 1579218822Sdim } 158068778Sobrien 158133965Sjdp /* Choose a unique name for the section. This will be needed if the 158233965Sjdp same section name appears in the input file with different 158377319Sobrien loadable or allocatable characteristics. */ 1584107499Sobrien if (bfd_get_section_by_name (output_bfd, secname) != NULL) 158533965Sjdp { 1586218822Sdim static int count = 1; 1587107499Sobrien secname = bfd_get_unique_section_name (output_bfd, secname, &count); 1588107499Sobrien if (secname == NULL) 158977319Sobrien einfo ("%F%P: place_orphan failed: %E\n"); 159033965Sjdp } 159133965Sjdp 1592218822Sdim lang_insert_orphan (s, secname, after, place, NULL, NULL); 159368778Sobrien 1594130565Sobrien return TRUE; 159533965Sjdp} 159689872SobrienEOF 159789872Sobrienfi 159833965Sjdp 159989872Sobrienif test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then 160089872Sobriencat >>e${EMULATION_NAME}.c <<EOF 160189872Sobrien 160289872Sobrienstatic void 1603130565Sobriengld${EMULATION_NAME}_finish (void) 160489872Sobrien{ 1605218822Sdim bfd_boolean need_layout = bfd_elf_discard_info (output_bfd, &link_info); 160691055Sobrien 1607218822Sdim gld${EMULATION_NAME}_map_segments (need_layout); 1608218822Sdim finish_default (); 160989872Sobrien} 161077319SobrienEOF 161177319Sobrienfi 161277319Sobrien 161377319Sobrienif test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then 161477319Sobriencat >>e${EMULATION_NAME}.c <<EOF 161577319Sobrien 161633965Sjdpstatic char * 1617130565Sobriengld${EMULATION_NAME}_get_script (int *isfile) 161833965SjdpEOF 161933965Sjdp 162033965Sjdpif test -n "$COMPILE_IN" 162133965Sjdpthen 162233965Sjdp# Scripts compiled in. 162333965Sjdp 162433965Sjdp# sed commands to quote an ld script as a C string. 162560525Sobriensc="-f stringify.sed" 162633965Sjdp 162733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 162877319Sobrien{ 162933965Sjdp *isfile = 0; 163033965Sjdp 1631130565Sobrien if (link_info.relocatable && config.build_constructors) 163260525Sobrien return 163333965SjdpEOF 1634218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c 1635218822Sdimecho ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c 1636218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c 1637218822Sdimecho ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c 1638218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c 163989872Sobrienif cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; else 1640218822Sdimecho ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c 1641218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c 164289872Sobrienfi 1643130565Sobrienif test -n "$GENERATE_PIE_SCRIPT" ; then 1644130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1645218822Sdimecho ' ; else if (link_info.pie && link_info.combreloc' >> e${EMULATION_NAME}.c 1646218822Sdimecho ' && link_info.relro' >> e${EMULATION_NAME}.c 1647218822Sdimecho ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c 1648218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xdw >> e${EMULATION_NAME}.c 1649130565Sobrienecho ' ; else if (link_info.pie && link_info.combreloc) return' >> e${EMULATION_NAME}.c 1650218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c 1651130565Sobrienfi 1652218822Sdimecho ' ; else if (link_info.pie) return' >> e${EMULATION_NAME}.c 1653218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c 1654130565Sobrienfi 165560525Sobrienif test -n "$GENERATE_SHLIB_SCRIPT" ; then 1656104847Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1657218822Sdimecho ' ; else if (link_info.shared && link_info.combreloc' >> e${EMULATION_NAME}.c 1658218822Sdimecho ' && link_info.relro' >> e${EMULATION_NAME}.c 1659218822Sdimecho ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c 1660218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xsw >> e${EMULATION_NAME}.c 166189872Sobrienecho ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c 1662218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c 1663104847Sobrienfi 1664218822Sdimecho ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c 1665218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c 166660525Sobrienfi 1667104847Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1668218822Sdimecho ' ; else if (link_info.combreloc && link_info.relro' >> e${EMULATION_NAME}.c 1669218822Sdimecho ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c 1670218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xw >> e${EMULATION_NAME}.c 1671218822Sdimecho ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c 1672218822Sdimsed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c 1673104847Sobrienfi 1674218822Sdimecho ' ; else return' >> e${EMULATION_NAME}.c 1675218822Sdimsed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c 1676218822Sdimecho '; }' >> e${EMULATION_NAME}.c 167760525Sobrien 167833965Sjdpelse 167933965Sjdp# Scripts read from the filesystem. 168033965Sjdp 168133965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 168277319Sobrien{ 168333965Sjdp *isfile = 1; 168433965Sjdp 1685130565Sobrien if (link_info.relocatable && config.build_constructors) 168633965Sjdp return "ldscripts/${EMULATION_NAME}.xu"; 1687130565Sobrien else if (link_info.relocatable) 168833965Sjdp return "ldscripts/${EMULATION_NAME}.xr"; 168933965Sjdp else if (!config.text_read_only) 169033965Sjdp return "ldscripts/${EMULATION_NAME}.xbn"; 1691130565SobrienEOF 1692130565Sobrienif cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : 1693130565Sobrienelse 1694130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 169533965Sjdp else if (!config.magic_demand_paged) 169633965Sjdp return "ldscripts/${EMULATION_NAME}.xn"; 1697130565SobrienEOF 1698130565Sobrienfi 1699130565Sobrienif test -n "$GENERATE_PIE_SCRIPT" ; then 1700130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1701130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1702218822Sdim else if (link_info.pie && link_info.combreloc 1703218822Sdim && link_info.relro && (link_info.flags & DT_BIND_NOW)) 1704218822Sdim return "ldscripts/${EMULATION_NAME}.xdw"; 1705130565Sobrien else if (link_info.pie && link_info.combreloc) 1706130565Sobrien return "ldscripts/${EMULATION_NAME}.xdc"; 1707130565SobrienEOF 1708130565Sobrienfi 1709130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1710130565Sobrien else if (link_info.pie) 1711130565Sobrien return "ldscripts/${EMULATION_NAME}.xd"; 1712130565SobrienEOF 1713130565Sobrienfi 1714130565Sobrienif test -n "$GENERATE_SHLIB_SCRIPT" ; then 1715130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1716130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1717218822Sdim else if (link_info.shared && link_info.combreloc 1718218822Sdim && link_info.relro && (link_info.flags & DT_BIND_NOW)) 1719218822Sdim return "ldscripts/${EMULATION_NAME}.xsw"; 1720130565Sobrien else if (link_info.shared && link_info.combreloc) 1721130565Sobrien return "ldscripts/${EMULATION_NAME}.xsc"; 1722130565SobrienEOF 1723130565Sobrienfi 1724130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 172533965Sjdp else if (link_info.shared) 172633965Sjdp return "ldscripts/${EMULATION_NAME}.xs"; 1727130565SobrienEOF 1728130565Sobrienfi 1729130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1730130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1731218822Sdim else if (link_info.combreloc && link_info.relro 1732218822Sdim && (link_info.flags & DT_BIND_NOW)) 1733218822Sdim return "ldscripts/${EMULATION_NAME}.xw"; 1734130565Sobrien else if (link_info.combreloc) 1735130565Sobrien return "ldscripts/${EMULATION_NAME}.xc"; 1736130565SobrienEOF 1737130565Sobrienfi 1738130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 173933965Sjdp else 174033965Sjdp return "ldscripts/${EMULATION_NAME}.x"; 174133965Sjdp} 174277319Sobrien 174333965SjdpEOF 174477319Sobrienfi 174577319Sobrienfi 174633965Sjdp 174777319Sobrienif test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then 174877319Sobrien 174977319Sobrienif test -n "$PARSE_AND_LIST_PROLOGUE" ; then 175077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 175177319Sobrien $PARSE_AND_LIST_PROLOGUE 175277319SobrienEOF 175333965Sjdpfi 175433965Sjdp 175533965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 175633965Sjdp 175777319Sobrien#define OPTION_DISABLE_NEW_DTAGS (400) 175877319Sobrien#define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1) 175978841Sobrien#define OPTION_GROUP (OPTION_ENABLE_NEW_DTAGS + 1) 176089872Sobrien#define OPTION_EH_FRAME_HDR (OPTION_GROUP + 1) 1761218822Sdim#define OPTION_EXCLUDE_LIBS (OPTION_EH_FRAME_HDR + 1) 1762218822Sdim#define OPTION_HASH_STYLE (OPTION_EXCLUDE_LIBS + 1) 176377319Sobrien 1764130565Sobrienstatic void 1765130565Sobriengld${EMULATION_NAME}_add_options 1766130565Sobrien (int ns, char **shortopts, int nl, struct option **longopts, 1767130565Sobrien int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED) 176877319Sobrien{ 1769130565Sobrien static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:"; 1770130565Sobrien static const struct option xtra_long[] = { 177160525SobrienEOF 177260525Sobrien 177377319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 177460525Sobriencat >>e${EMULATION_NAME}.c <<EOF 1775130565Sobrien {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS}, 1776130565Sobrien {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS}, 1777130565Sobrien {"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR}, 1778218822Sdim {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS}, 1779218822Sdim {"hash-style", required_argument, NULL, OPTION_HASH_STYLE}, 1780130565Sobrien {"Bgroup", no_argument, NULL, OPTION_GROUP}, 178160525SobrienEOF 178277319Sobrienfi 178360525Sobrien 178477319Sobrienif test -n "$PARSE_AND_LIST_LONGOPTS" ; then 178577319Sobriencat >>e${EMULATION_NAME}.c <<EOF 1786130565Sobrien $PARSE_AND_LIST_LONGOPTS 178777319SobrienEOF 178860525Sobrienfi 178960525Sobrien 179060525Sobriencat >>e${EMULATION_NAME}.c <<EOF 1791130565Sobrien {NULL, no_argument, NULL, 0} 1792130565Sobrien }; 179360525Sobrien 1794130565Sobrien *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short)); 1795130565Sobrien memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short)); 1796130565Sobrien *longopts = (struct option *) 1797130565Sobrien xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); 1798130565Sobrien memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); 1799130565Sobrien} 180077319Sobrien 1801130565Sobrienstatic bfd_boolean 1802130565Sobriengld${EMULATION_NAME}_handle_option (int optc) 180333965Sjdp{ 180477319Sobrien switch (optc) 180577319Sobrien { 180677319Sobrien default: 1807130565Sobrien return FALSE; 180877319Sobrien 180977319SobrienEOF 181077319Sobrien 181177319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 181277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 181377319Sobrien case OPTION_DISABLE_NEW_DTAGS: 1814130565Sobrien link_info.new_dtags = FALSE; 181577319Sobrien break; 181677319Sobrien 181777319Sobrien case OPTION_ENABLE_NEW_DTAGS: 1818130565Sobrien link_info.new_dtags = TRUE; 181977319Sobrien break; 182077319Sobrien 182189872Sobrien case OPTION_EH_FRAME_HDR: 1822130565Sobrien link_info.eh_frame_hdr = TRUE; 182389872Sobrien break; 182489872Sobrien 182578841Sobrien case OPTION_GROUP: 182678841Sobrien link_info.flags_1 |= (bfd_vma) DF_1_GROUP; 182778841Sobrien /* Groups must be self-contained. */ 1828130565Sobrien link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR; 1829130565Sobrien link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR; 183078841Sobrien break; 183178841Sobrien 1832218822Sdim case OPTION_EXCLUDE_LIBS: 1833218822Sdim add_excluded_libs (optarg); 1834218822Sdim break; 1835218822Sdim 1836218822Sdim case OPTION_HASH_STYLE: 1837218822Sdim link_info.emit_hash = FALSE; 1838218822Sdim link_info.emit_gnu_hash = FALSE; 1839218822Sdim if (strcmp (optarg, "sysv") == 0) 1840218822Sdim link_info.emit_hash = TRUE; 1841218822Sdim else if (strcmp (optarg, "gnu") == 0) 1842218822Sdim link_info.emit_gnu_hash = TRUE; 1843218822Sdim else if (strcmp (optarg, "both") == 0) 1844218822Sdim { 1845218822Sdim link_info.emit_hash = TRUE; 1846218822Sdim link_info.emit_gnu_hash = TRUE; 1847218822Sdim } 1848218822Sdim else 1849218822Sdim einfo (_("%P%F: invalid hash style \`%s'\n"), optarg); 1850218822Sdim break; 1851218822Sdim 185277319Sobrien case 'z': 185377319Sobrien if (strcmp (optarg, "initfirst") == 0) 185477319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST; 185577319Sobrien else if (strcmp (optarg, "interpose") == 0) 185677319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_INTERPOSE; 185777319Sobrien else if (strcmp (optarg, "loadfltr") == 0) 185877319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_LOADFLTR; 185977319Sobrien else if (strcmp (optarg, "nodefaultlib") == 0) 186077319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODEFLIB; 186177319Sobrien else if (strcmp (optarg, "nodelete") == 0) 186277319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODELETE; 186377319Sobrien else if (strcmp (optarg, "nodlopen") == 0) 186477319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NOOPEN; 186577319Sobrien else if (strcmp (optarg, "nodump") == 0) 186677319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODUMP; 186777319Sobrien else if (strcmp (optarg, "now") == 0) 186877319Sobrien { 186977319Sobrien link_info.flags |= (bfd_vma) DF_BIND_NOW; 187077319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NOW; 187177319Sobrien } 1872218822Sdim else if (strcmp (optarg, "lazy") == 0) 1873218822Sdim { 1874218822Sdim link_info.flags &= ~(bfd_vma) DF_BIND_NOW; 1875218822Sdim link_info.flags_1 &= ~(bfd_vma) DF_1_NOW; 1876218822Sdim } 187777319Sobrien else if (strcmp (optarg, "origin") == 0) 187877319Sobrien { 187977319Sobrien link_info.flags |= (bfd_vma) DF_ORIGIN; 188077319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN; 188177319Sobrien } 188278841Sobrien else if (strcmp (optarg, "defs") == 0) 1883130565Sobrien link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR; 1884104847Sobrien else if (strcmp (optarg, "muldefs") == 0) 1885130565Sobrien link_info.allow_multiple_definition = TRUE; 188689872Sobrien else if (strcmp (optarg, "combreloc") == 0) 1887130565Sobrien link_info.combreloc = TRUE; 188889872Sobrien else if (strcmp (optarg, "nocombreloc") == 0) 1889130565Sobrien link_info.combreloc = FALSE; 189089872Sobrien else if (strcmp (optarg, "nocopyreloc") == 0) 1891130565Sobrien link_info.nocopyreloc = TRUE; 1892130565Sobrien else if (strcmp (optarg, "execstack") == 0) 1893130565Sobrien { 1894130565Sobrien link_info.execstack = TRUE; 1895130565Sobrien link_info.noexecstack = FALSE; 1896130565Sobrien } 1897130565Sobrien else if (strcmp (optarg, "noexecstack") == 0) 1898130565Sobrien { 1899130565Sobrien link_info.noexecstack = TRUE; 1900130565Sobrien link_info.execstack = FALSE; 1901130565Sobrien } 1902218822SdimEOF 1903218822Sdim 1904218822Sdim if test -n "$COMMONPAGESIZE"; then 1905218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 1906218822Sdim else if (strcmp (optarg, "relro") == 0) 1907218822Sdim link_info.relro = TRUE; 1908218822Sdim else if (strcmp (optarg, "norelro") == 0) 1909218822Sdim link_info.relro = FALSE; 1910218822SdimEOF 1911218822Sdim fi 1912218822Sdim 1913218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 1914218822Sdim else if (CONST_STRNEQ (optarg, "max-page-size=")) 1915218822Sdim { 1916218822Sdim char *end; 1917218822Sdim 1918218822Sdim config.maxpagesize = strtoul (optarg + 14, &end, 0); 1919218822Sdim if (*end || (config.maxpagesize & (config.maxpagesize - 1)) != 0) 1920218822Sdim einfo (_("%P%F: invalid maxium page size \`%s'\n"), 1921218822Sdim optarg + 14); 1922218822Sdim ASSERT (default_target != NULL); 1923218822Sdim bfd_emul_set_maxpagesize (default_target, config.maxpagesize); 1924218822Sdim } 1925218822Sdim else if (CONST_STRNEQ (optarg, "common-page-size=")) 1926218822Sdim { 1927218822Sdim char *end; 1928218822Sdim config.commonpagesize = strtoul (optarg + 17, &end, 0); 1929218822Sdim if (*end 1930218822Sdim || (config.commonpagesize & (config.commonpagesize - 1)) != 0) 1931218822Sdim einfo (_("%P%F: invalid common page size \`%s'\n"), 1932218822Sdim optarg + 17); 1933218822Sdim ASSERT (default_target != NULL); 1934218822Sdim bfd_emul_set_commonpagesize (default_target, 1935218822Sdim config.commonpagesize); 1936218822Sdim } 193777319Sobrien /* What about the other Solaris -z options? FIXME. */ 193877319Sobrien break; 193977319SobrienEOF 194077319Sobrienfi 194177319Sobrien 194277319Sobrienif test -n "$PARSE_AND_LIST_ARGS_CASES" ; then 194377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 194477319Sobrien $PARSE_AND_LIST_ARGS_CASES 194577319SobrienEOF 194677319Sobrienfi 194777319Sobrien 194877319Sobriencat >>e${EMULATION_NAME}.c <<EOF 194977319Sobrien } 195077319Sobrien 1951130565Sobrien return TRUE; 195277319Sobrien} 195377319Sobrien 195477319SobrienEOF 195577319Sobrien 195677319Sobrienif test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then 195777319Sobriencat >>e${EMULATION_NAME}.c <<EOF 195877319Sobrien 195977319Sobrienstatic void 1960130565Sobriengld${EMULATION_NAME}_list_options (FILE * file) 196177319Sobrien{ 196277319SobrienEOF 196377319Sobrien 196477319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 196577319Sobriencat >>e${EMULATION_NAME}.c <<EOF 196678841Sobrien fprintf (file, _(" -Bgroup\t\tSelects group name lookup rules for DSO\n")); 196777319Sobrien fprintf (file, _(" --disable-new-dtags\tDisable new dynamic tags\n")); 196877319Sobrien fprintf (file, _(" --enable-new-dtags\tEnable new dynamic tags\n")); 196989872Sobrien fprintf (file, _(" --eh-frame-hdr\tCreate .eh_frame_hdr section\n")); 1970218822Sdim fprintf (file, _(" --hash-style=STYLE\tSet hash style to sysv, gnu or both\n")); 197189872Sobrien fprintf (file, _(" -z combreloc\t\tMerge dynamic relocs into one section and sort\n")); 1972130565Sobrien fprintf (file, _(" -z defs\t\tReport unresolved symbols in object files.\n")); 1973130565Sobrien fprintf (file, _(" -z execstack\t\tMark executable as requiring executable stack\n")); 197477319Sobrien fprintf (file, _(" -z initfirst\t\tMark DSO to be initialized first at runtime\n")); 197577319Sobrien fprintf (file, _(" -z interpose\t\tMark object to interpose all DSOs but executable\n")); 1976218822Sdim fprintf (file, _(" -z lazy\t\tMark object lazy runtime binding (default)\n")); 197777319Sobrien fprintf (file, _(" -z loadfltr\t\tMark object requiring immediate process\n")); 1978104847Sobrien fprintf (file, _(" -z muldefs\t\tAllow multiple definitions\n")); 197989872Sobrien fprintf (file, _(" -z nocombreloc\tDon't merge dynamic relocs into one section\n")); 198089872Sobrien fprintf (file, _(" -z nocopyreloc\tDon't create copy relocs\n")); 198177319Sobrien fprintf (file, _(" -z nodefaultlib\tMark object not to use default search paths\n")); 198277319Sobrien fprintf (file, _(" -z nodelete\t\tMark DSO non-deletable at runtime\n")); 198377319Sobrien fprintf (file, _(" -z nodlopen\t\tMark DSO not available to dlopen\n")); 198477319Sobrien fprintf (file, _(" -z nodump\t\tMark DSO not available to dldump\n")); 1985130565Sobrien fprintf (file, _(" -z noexecstack\tMark executable as not requiring executable stack\n")); 1986218822SdimEOF 1987218822Sdim 1988218822Sdim if test -n "$COMMONPAGESIZE"; then 1989218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 1990218822Sdim fprintf (file, _(" -z norelro\t\tDon't create RELRO program header\n")); 1991218822SdimEOF 1992218822Sdim fi 1993218822Sdim 1994218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 199577319Sobrien fprintf (file, _(" -z now\t\tMark object non-lazy runtime binding\n")); 199689872Sobrien fprintf (file, _(" -z origin\t\tMark object requiring immediate \$ORIGIN processing\n\t\t\t at runtime\n")); 1997218822SdimEOF 1998218822Sdim 1999218822Sdim if test -n "$COMMONPAGESIZE"; then 2000218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 2001218822Sdim fprintf (file, _(" -z relro\t\tCreate RELRO program header\n")); 2002218822SdimEOF 2003218822Sdim fi 2004218822Sdim 2005218822Sdimcat >>e${EMULATION_NAME}.c <<EOF 2006218822Sdim fprintf (file, _(" -z max-page-size=SIZE\tSet maximum page size to SIZE\n")); 2007218822Sdim fprintf (file, _(" -z common-page-size=SIZE\n\t\t\tSet common page size to SIZE\n")); 200877319Sobrien fprintf (file, _(" -z KEYWORD\t\tIgnored for Solaris compatibility\n")); 200977319SobrienEOF 201077319Sobrienfi 201177319Sobrien 201277319Sobrienif test -n "$PARSE_AND_LIST_OPTIONS" ; then 201377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 201477319Sobrien $PARSE_AND_LIST_OPTIONS 201577319SobrienEOF 201677319Sobrienfi 201777319Sobrien 201877319Sobriencat >>e${EMULATION_NAME}.c <<EOF 201977319Sobrien} 202077319SobrienEOF 202177319Sobrien 202277319Sobrienif test -n "$PARSE_AND_LIST_EPILOGUE" ; then 202377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 202477319Sobrien $PARSE_AND_LIST_EPILOGUE 202577319SobrienEOF 202677319Sobrienfi 202777319Sobrienfi 202877319Sobrienelse 202977319Sobriencat >>e${EMULATION_NAME}.c <<EOF 2030130565Sobrien#define gld${EMULATION_NAME}_add_options NULL 2031130565Sobrien#define gld${EMULATION_NAME}_handle_option NULL 203277319SobrienEOF 203377319Sobrienif test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then 203477319Sobriencat >>e${EMULATION_NAME}.c <<EOF 203577319Sobrien#define gld${EMULATION_NAME}_list_options NULL 203677319SobrienEOF 203777319Sobrienfi 203877319Sobrienfi 203977319Sobrien 204077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 204177319Sobrien 204277319Sobrienstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 204377319Sobrien{ 204477319Sobrien ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse}, 204577319Sobrien ${LDEMUL_SYSLIB-syslib_default}, 204677319Sobrien ${LDEMUL_HLL-hll_default}, 204777319Sobrien ${LDEMUL_AFTER_PARSE-after_parse_default}, 204877319Sobrien ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open}, 204977319Sobrien ${LDEMUL_AFTER_ALLOCATION-after_allocation_default}, 205077319Sobrien ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default}, 205177319Sobrien ${LDEMUL_CHOOSE_TARGET-ldemul_default_target}, 205277319Sobrien ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation}, 205377319Sobrien ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, 205433965Sjdp "${EMULATION_NAME}", 205533965Sjdp "${OUTPUT_FORMAT}", 205689872Sobrien ${LDEMUL_FINISH-gld${EMULATION_NAME}_finish}, 205777319Sobrien ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, 205877319Sobrien ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive}, 205977319Sobrien ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan}, 206077319Sobrien ${LDEMUL_SET_SYMBOLS-NULL}, 2061130565Sobrien ${LDEMUL_PARSE_ARGS-NULL}, 2062130565Sobrien gld${EMULATION_NAME}_add_options, 2063130565Sobrien gld${EMULATION_NAME}_handle_option, 206477319Sobrien ${LDEMUL_UNRECOGNIZED_FILE-NULL}, 206577319Sobrien ${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options}, 2066130565Sobrien ${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols}, 206777319Sobrien ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL}, 2068104847Sobrien ${LDEMUL_NEW_VERS_PATTERN-NULL} 206933965Sjdp}; 207033965SjdpEOF 2071