elf32.em revision 130565
160525Sobrien# $FreeBSD: head/contrib/binutils/ld/emultempl/elf32.em 130565 2004-06-16 06:09:06Z obrien $ 277319Sobrien 377319Sobrien 433965Sjdp# This shell script emits a C file. -*- C -*- 533965Sjdp# It does some substitutions. 633965Sjdp# This file is now misnamed, because it supports both 32 bit and 64 bit 733965Sjdp# ELF emulations. 833965Sjdptest -z "${ELFSIZE}" && ELFSIZE=32 989872Sobrienif [ -z "$MACHINE" ]; then 1089872Sobrien OUTPUT_ARCH=${ARCH} 1189872Sobrienelse 1289872Sobrien OUTPUT_ARCH=${ARCH}:${MACHINE} 1389872Sobrienfi 1433965Sjdpcat >e${EMULATION_NAME}.c <<EOF 1533965Sjdp/* This file is is generated by a shell script. DO NOT EDIT! */ 1633965Sjdp 1733965Sjdp/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME} 1891055Sobrien Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 19130565Sobrien 2002, 2003, 2004 Free Software Foundation, Inc. 2033965Sjdp Written by Steve Chamberlain <sac@cygnus.com> 2133965Sjdp ELF support by Ian Lance Taylor <ian@cygnus.com> 2233965Sjdp 2333965SjdpThis file is part of GLD, the Gnu Linker. 2433965Sjdp 2533965SjdpThis program is free software; you can redistribute it and/or modify 2633965Sjdpit under the terms of the GNU General Public License as published by 2733965Sjdpthe Free Software Foundation; either version 2 of the License, or 2833965Sjdp(at your option) any later version. 2933965Sjdp 3033965SjdpThis program is distributed in the hope that it will be useful, 3133965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 3233965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3333965SjdpGNU General Public License for more details. 3433965Sjdp 3533965SjdpYou should have received a copy of the GNU General Public License 3633965Sjdpalong with this program; if not, write to the Free Software 3733965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 3833965Sjdp 3933965Sjdp#define TARGET_IS_${EMULATION_NAME} 4033965Sjdp 4133965Sjdp#include "bfd.h" 4233965Sjdp#include "sysdep.h" 4378841Sobrien#include "libiberty.h" 4489872Sobrien#include "safe-ctype.h" 45130565Sobrien#include "getopt.h" 4633965Sjdp 4733965Sjdp#include "bfdlink.h" 4833965Sjdp 4933965Sjdp#include "ld.h" 5033965Sjdp#include "ldmain.h" 5133965Sjdp#include "ldmisc.h" 5233965Sjdp#include "ldexp.h" 5333965Sjdp#include "ldlang.h" 5477319Sobrien#include "ldfile.h" 5577319Sobrien#include "ldemul.h" 56107499Sobrien#include <ldgram.h> 5777319Sobrien#include "elf/common.h" 5833965Sjdp 59130565Sobrien/* Declare functions used by various EXTRA_EM_FILEs. */ 60130565Sobrienstatic void gld${EMULATION_NAME}_before_parse (void); 61130565Sobrienstatic void gld${EMULATION_NAME}_after_open (void); 62130565Sobrienstatic void gld${EMULATION_NAME}_before_allocation (void); 63130565Sobrienstatic bfd_boolean gld${EMULATION_NAME}_place_orphan 64130565Sobrien (lang_input_statement_type *file, asection *s); 65130565Sobrienstatic void gld${EMULATION_NAME}_finish (void); 6633965Sjdp 6777319SobrienEOF 6877319Sobrien 6977319Sobrien# Import any needed special functions and/or overrides. 7077319Sobrien# 7177319Sobrienif test -n "$EXTRA_EM_FILE" ; then 7277319Sobrien. ${srcdir}/emultempl/${EXTRA_EM_FILE}.em 7377319Sobrienfi 7477319Sobrien 7577319Sobrien# Functions in this file can be overridden by setting the LDEMUL_* shell 7677319Sobrien# variables. If the name of the overriding function is the same as is 7777319Sobrien# defined in this file, then don't output this file's version. 7877319Sobrien# If a different overriding name is given then output the standard function 7977319Sobrien# as presumably it is called from the overriding function. 8077319Sobrien# 8177319Sobrienif test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then 8277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 8377319Sobrien 8433965Sjdpstatic void 85130565Sobriengld${EMULATION_NAME}_before_parse (void) 8633965Sjdp{ 87130565Sobrien ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`); 88130565Sobrien config.dynamic_link = ${DYNAMIC_LINK-TRUE}; 89130565Sobrien config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; 9033965Sjdp} 9133965Sjdp 9277319SobrienEOF 9377319Sobrienfi 9433965Sjdp 95130565Sobrienif test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then 9677319Sobriencat >>e${EMULATION_NAME}.c <<EOF 97130565Sobrien/* Handle as_needed DT_NEEDED. */ 9877319Sobrien 99130565Sobrienstatic bfd_boolean 100130565Sobriengld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry) 101130565Sobrien{ 102130565Sobrien if (!entry->as_needed 103130565Sobrien || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0) 104130565Sobrien return FALSE; 105130565Sobrien 106130565Sobrien /* Tell the ELF linker that we don't want the output file to have a 107130565Sobrien DT_NEEDED entry for this file, unless it is used to resolve 108130565Sobrien references in a regular object. */ 109130565Sobrien bfd_elf_set_dyn_lib_class (entry->the_bfd, DYN_AS_NEEDED); 110130565Sobrien 111130565Sobrien /* Continue on with normal load_symbols processing. */ 112130565Sobrien return FALSE; 113130565Sobrien} 114130565SobrienEOF 115130565Sobrienfi 116130565Sobrien 117130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 118130565Sobrien 11977319Sobrien/* These variables are required to pass information back and forth 12077319Sobrien between after_open and check_needed and stat_needed and vercheck. */ 12177319Sobrien 12277319Sobrienstatic struct bfd_link_needed_list *global_needed; 12377319Sobrienstatic struct stat global_stat; 124130565Sobrienstatic bfd_boolean global_found; 12577319Sobrienstatic struct bfd_link_needed_list *global_vercheck_needed; 126130565Sobrienstatic bfd_boolean global_vercheck_failed; 12777319Sobrien 12877319Sobrien 12977319Sobrien/* On Linux, it's possible to have different versions of the same 13077319Sobrien shared library linked against different versions of libc. The 13177319Sobrien dynamic linker somehow tags which libc version to use in 13277319Sobrien /etc/ld.so.cache, and, based on the libc that it sees in the 13377319Sobrien executable, chooses which version of the shared library to use. 13477319Sobrien 13577319Sobrien We try to do a similar check here by checking whether this shared 13677319Sobrien library needs any other shared libraries which may conflict with 13777319Sobrien libraries we have already included in the link. If it does, we 13877319Sobrien skip it, and try to find another shared library farther on down the 13977319Sobrien link path. 14077319Sobrien 14177319Sobrien This is called via lang_for_each_input_file. 14277319Sobrien GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object 14377319Sobrien which we are checking. This sets GLOBAL_VERCHECK_FAILED if we find 14477319Sobrien a conflicting version. */ 14577319Sobrien 14677319Sobrienstatic void 147130565Sobriengld${EMULATION_NAME}_vercheck (lang_input_statement_type *s) 14877319Sobrien{ 14978841Sobrien const char *soname; 15077319Sobrien struct bfd_link_needed_list *l; 15177319Sobrien 15277319Sobrien if (global_vercheck_failed) 15377319Sobrien return; 15477319Sobrien if (s->the_bfd == NULL 15577319Sobrien || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0) 15677319Sobrien return; 15777319Sobrien 15877319Sobrien soname = bfd_elf_get_dt_soname (s->the_bfd); 15977319Sobrien if (soname == NULL) 16092835Sobrien soname = lbasename (bfd_get_filename (s->the_bfd)); 16177319Sobrien 16277319Sobrien for (l = global_vercheck_needed; l != NULL; l = l->next) 16377319Sobrien { 16477319Sobrien const char *suffix; 16577319Sobrien 16678841Sobrien if (strcmp (soname, l->name) == 0) 16777319Sobrien { 16877319Sobrien /* Probably can't happen, but it's an easy check. */ 16977319Sobrien continue; 17077319Sobrien } 17177319Sobrien 17277319Sobrien if (strchr (l->name, '/') != NULL) 17377319Sobrien continue; 17477319Sobrien 17577319Sobrien suffix = strstr (l->name, ".so."); 17677319Sobrien if (suffix == NULL) 17777319Sobrien continue; 17877319Sobrien 17977319Sobrien suffix += sizeof ".so." - 1; 18077319Sobrien 18178841Sobrien if (strncmp (soname, l->name, suffix - l->name) == 0) 18277319Sobrien { 18377319Sobrien /* Here we know that S is a dynamic object FOO.SO.VER1, and 184130565Sobrien the object we are considering needs a dynamic object 185130565Sobrien FOO.SO.VER2, and VER1 and VER2 are different. This 186130565Sobrien appears to be a version mismatch, so we tell the caller 187130565Sobrien to try a different version of this library. */ 188130565Sobrien global_vercheck_failed = TRUE; 18977319Sobrien return; 19077319Sobrien } 19177319Sobrien } 19277319Sobrien} 19377319Sobrien 19477319Sobrien 19577319Sobrien/* See if an input file matches a DT_NEEDED entry by running stat on 19677319Sobrien the file. */ 19777319Sobrien 19877319Sobrienstatic void 199130565Sobriengld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s) 20077319Sobrien{ 20177319Sobrien struct stat st; 20277319Sobrien const char *suffix; 20377319Sobrien const char *soname; 20477319Sobrien 20577319Sobrien if (global_found) 20677319Sobrien return; 20777319Sobrien if (s->the_bfd == NULL) 20877319Sobrien return; 20977319Sobrien 21077319Sobrien if (bfd_stat (s->the_bfd, &st) != 0) 21177319Sobrien { 21277319Sobrien einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd); 21377319Sobrien return; 21477319Sobrien } 21577319Sobrien 21677319Sobrien if (st.st_dev == global_stat.st_dev 21777319Sobrien && st.st_ino == global_stat.st_ino) 21877319Sobrien { 219130565Sobrien global_found = TRUE; 22077319Sobrien return; 22177319Sobrien } 22277319Sobrien 22377319Sobrien /* We issue a warning if it looks like we are including two 22477319Sobrien different versions of the same shared library. For example, 22577319Sobrien there may be a problem if -lc picks up libc.so.6 but some other 22677319Sobrien shared library has a DT_NEEDED entry of libc.so.5. This is a 22777319Sobrien heuristic test, and it will only work if the name looks like 22877319Sobrien NAME.so.VERSION. FIXME: Depending on file names is error-prone. 22977319Sobrien If we really want to issue warnings about mixing version numbers 23077319Sobrien of shared libraries, we need to find a better way. */ 23177319Sobrien 23277319Sobrien if (strchr (global_needed->name, '/') != NULL) 23377319Sobrien return; 23477319Sobrien suffix = strstr (global_needed->name, ".so."); 23577319Sobrien if (suffix == NULL) 23677319Sobrien return; 23777319Sobrien suffix += sizeof ".so." - 1; 23877319Sobrien 23977319Sobrien soname = bfd_elf_get_dt_soname (s->the_bfd); 24077319Sobrien if (soname == NULL) 24192835Sobrien soname = lbasename (s->filename); 24277319Sobrien 24389872Sobrien if (strncmp (soname, global_needed->name, suffix - global_needed->name) == 0) 24477319Sobrien einfo ("%P: warning: %s, needed by %B, may conflict with %s\n", 24578841Sobrien global_needed->name, global_needed->by, soname); 24677319Sobrien} 24777319Sobrien 24877319Sobrien 24977319Sobrien/* This function is called for each possible name for a dynamic object 25077319Sobrien named by a DT_NEEDED entry. The FORCE parameter indicates whether 25177319Sobrien to skip the check for a conflicting version. */ 25277319Sobrien 253130565Sobrienstatic bfd_boolean 254130565Sobriengld${EMULATION_NAME}_try_needed (const char *name, int force) 25533965Sjdp{ 25677319Sobrien bfd *abfd; 25777319Sobrien const char *soname; 25833965Sjdp 25977319Sobrien abfd = bfd_openr (name, bfd_get_target (output_bfd)); 26077319Sobrien if (abfd == NULL) 261130565Sobrien return FALSE; 26277319Sobrien if (! bfd_check_format (abfd, bfd_object)) 26377319Sobrien { 26489872Sobrien bfd_close (abfd); 265130565Sobrien return FALSE; 26677319Sobrien } 26777319Sobrien if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) 26877319Sobrien { 26989872Sobrien bfd_close (abfd); 270130565Sobrien return FALSE; 27177319Sobrien } 27233965Sjdp 273104847Sobrien /* For DT_NEEDED, they have to match. */ 274104847Sobrien if (abfd->xvec != output_bfd->xvec) 275104847Sobrien { 276104847Sobrien bfd_close (abfd); 277130565Sobrien return FALSE; 278104847Sobrien } 279104847Sobrien 28077319Sobrien /* Check whether this object would include any conflicting library 28177319Sobrien versions. If FORCE is set, then we skip this check; we use this 28277319Sobrien the second time around, if we couldn't find any compatible 28377319Sobrien instance of the shared library. */ 28433965Sjdp 28577319Sobrien if (! force) 28677319Sobrien { 28777319Sobrien struct bfd_link_needed_list *needed; 28833965Sjdp 28977319Sobrien if (! bfd_elf_get_bfd_needed_list (abfd, &needed)) 29077319Sobrien einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd); 29133965Sjdp 29277319Sobrien if (needed != NULL) 29377319Sobrien { 29477319Sobrien global_vercheck_needed = needed; 295130565Sobrien global_vercheck_failed = FALSE; 29677319Sobrien lang_for_each_input_file (gld${EMULATION_NAME}_vercheck); 29777319Sobrien if (global_vercheck_failed) 29877319Sobrien { 29989872Sobrien bfd_close (abfd); 300130565Sobrien /* Return FALSE to force the caller to move on to try 301130565Sobrien another file on the search path. */ 302130565Sobrien return FALSE; 30377319Sobrien } 30460525Sobrien 30577319Sobrien /* But wait! It gets much worse. On Linux, if a shared 306130565Sobrien library does not use libc at all, we are supposed to skip 307130565Sobrien it the first time around in case we encounter a shared 308130565Sobrien library later on with the same name which does use the 309130565Sobrien version of libc that we want. This is much too horrible 310130565Sobrien to use on any system other than Linux. */ 31177319Sobrien 31277319SobrienEOF 31377319Sobriencase ${target} in 31477319Sobrien *-*-linux-gnu*) 31577319Sobrien cat >>e${EMULATION_NAME}.c <<EOF 31677319Sobrien { 31777319Sobrien struct bfd_link_needed_list *l; 31877319Sobrien 31977319Sobrien for (l = needed; l != NULL; l = l->next) 32077319Sobrien if (strncmp (l->name, "libc.so", 7) == 0) 32177319Sobrien break; 32277319Sobrien if (l == NULL) 32377319Sobrien { 32489872Sobrien bfd_close (abfd); 325130565Sobrien return FALSE; 32677319Sobrien } 32777319Sobrien } 32877319Sobrien 32977319SobrienEOF 33077319Sobrien ;; 33177319Sobrienesac 33277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 33377319Sobrien } 33477319Sobrien } 33577319Sobrien 33677319Sobrien /* We've found a dynamic object matching the DT_NEEDED entry. */ 33777319Sobrien 33877319Sobrien /* We have already checked that there is no other input file of the 33977319Sobrien same name. We must now check again that we are not including the 34077319Sobrien same file twice. We need to do this because on many systems 34177319Sobrien libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will 34277319Sobrien reference libc.so.1. If we have already included libc.so, we 34377319Sobrien don't want to include libc.so.1 if they are the same file, and we 34477319Sobrien can only check that using stat. */ 34577319Sobrien 34677319Sobrien if (bfd_stat (abfd, &global_stat) != 0) 34777319Sobrien einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd); 34877319Sobrien 34977319Sobrien /* First strip off everything before the last '/'. */ 35092835Sobrien soname = lbasename (abfd->filename); 35177319Sobrien 35277319Sobrien if (trace_file_tries) 35377319Sobrien info_msg (_("found %s at %s\n"), soname, name); 35477319Sobrien 355130565Sobrien global_found = FALSE; 35677319Sobrien lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed); 35777319Sobrien if (global_found) 35833965Sjdp { 359130565Sobrien /* Return TRUE to indicate that we found the file, even though 360130565Sobrien we aren't going to do anything with it. */ 361130565Sobrien return TRUE; 36233965Sjdp } 36333965Sjdp 364130565Sobrien /* Specify the soname to use. */ 365130565Sobrien bfd_elf_set_dt_needed_name (abfd, soname); 36633965Sjdp 367130565Sobrien /* Tell the ELF linker that we don't want the output file to have a 368130565Sobrien DT_NEEDED entry for this file, unless it is used to resolve 369130565Sobrien references in a regular object. */ 370130565Sobrien bfd_elf_set_dyn_lib_class (abfd, DYN_DT_NEEDED); 37133965Sjdp 37277319Sobrien /* Add this file into the symbol table. */ 37377319Sobrien if (! bfd_link_add_symbols (abfd, &link_info)) 37477319Sobrien einfo ("%F%B: could not read symbols: %E\n", abfd); 37577319Sobrien 376130565Sobrien return TRUE; 37777319Sobrien} 37877319Sobrien 37977319Sobrien 38077319Sobrien/* Search for a needed file in a path. */ 38177319Sobrien 382130565Sobrienstatic bfd_boolean 383130565Sobriengld${EMULATION_NAME}_search_needed (const char *path, const char *name, int force) 38477319Sobrien{ 38577319Sobrien const char *s; 38677319Sobrien size_t len; 38777319Sobrien 38877319Sobrien if (name[0] == '/') 38977319Sobrien return gld${EMULATION_NAME}_try_needed (name, force); 39077319Sobrien 39177319Sobrien if (path == NULL || *path == '\0') 392130565Sobrien return FALSE; 39377319Sobrien len = strlen (name); 39477319Sobrien while (1) 39533965Sjdp { 39677319Sobrien char *filename, *sset; 39733965Sjdp 39877319Sobrien s = strchr (path, ':'); 39977319Sobrien if (s == NULL) 40077319Sobrien s = path + strlen (path); 40160525Sobrien 40277319Sobrien filename = (char *) xmalloc (s - path + len + 2); 40377319Sobrien if (s == path) 40477319Sobrien sset = filename; 40577319Sobrien else 40677319Sobrien { 40777319Sobrien memcpy (filename, path, s - path); 40877319Sobrien filename[s - path] = '/'; 40977319Sobrien sset = filename + (s - path) + 1; 41077319Sobrien } 41177319Sobrien strcpy (sset, name); 41260525Sobrien 41377319Sobrien if (gld${EMULATION_NAME}_try_needed (filename, force)) 414130565Sobrien return TRUE; 41560525Sobrien 41677319Sobrien free (filename); 41777319Sobrien 41877319Sobrien if (*s == '\0') 41977319Sobrien break; 42077319Sobrien path = s + 1; 42133965Sjdp } 42233965Sjdp 423130565Sobrien return FALSE; 42433965Sjdp} 42533965Sjdp 42633965SjdpEOF 427130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 428130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 429130565Sobrien 430130565Sobrien/* Add the sysroot to every entry in a colon-separated path. */ 431130565Sobrien 432130565Sobrienstatic char * 433130565Sobriengld${EMULATION_NAME}_add_sysroot (const char *path) 434130565Sobrien{ 435130565Sobrien int len, colons, i; 436130565Sobrien char *ret, *p; 437130565Sobrien 438130565Sobrien len = strlen (path); 439130565Sobrien colons = 0; 440130565Sobrien i = 0; 441130565Sobrien while (path[i]) 442130565Sobrien if (path[i++] == ':') 443130565Sobrien colons++; 444130565Sobrien 445130565Sobrien if (path[i]) 446130565Sobrien colons++; 447130565Sobrien 448130565Sobrien len = len + (colons + 1) * strlen (ld_sysroot); 449130565Sobrien ret = xmalloc (len + 1); 450130565Sobrien strcpy (ret, ld_sysroot); 451130565Sobrien p = ret + strlen (ret); 452130565Sobrien i = 0; 453130565Sobrien while (path[i]) 454130565Sobrien if (path[i] == ':') 455130565Sobrien { 456130565Sobrien *p++ = path[i++]; 457130565Sobrien strcpy (p, ld_sysroot); 458130565Sobrien p = p + strlen (p); 459130565Sobrien } 460130565Sobrien else 461130565Sobrien *p++ = path[i++]; 462130565Sobrien 463130565Sobrien *p = 0; 464130565Sobrien return ret; 465130565Sobrien} 466130565Sobrien 467130565SobrienEOF 468130565Sobrien case ${target} in 469130565Sobrien *-*-freebsd*) 470130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 47142372Speter/* 47242372Speter * Read the system search path the FreeBSD way rather than like Linux. 47342372Speter */ 47476232Sobrien#include <elf-hints.h> 47533965Sjdp 476130565Sobrienstatic bfd_boolean 477130565Sobriengld${EMULATION_NAME}_check_ld_elf_hints (const char *name, int force) 47842372Speter{ 479130565Sobrien static bfd_boolean initialized; 48042372Speter static char *ld_elf_hints; 48142372Speter 48242372Speter if (! initialized) 48342372Speter { 48442372Speter FILE *f; 485130565Sobrien char *tmppath; 48642372Speter 487130565Sobrien tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, NULL); 488130565Sobrien f = fopen (tmppath, FOPEN_RB); 489130565Sobrien free (tmppath); 49042372Speter if (f != NULL) 49142372Speter { 49242372Speter struct elfhints_hdr hdr; 49342372Speter 49442372Speter if (fread(&hdr, 1, sizeof(hdr), f) == sizeof(hdr) && 49542372Speter hdr.magic == ELFHINTS_MAGIC && 49642372Speter hdr.version == 1) 49742372Speter { 49842372Speter if (fseek(f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1) 49942372Speter { 50042372Speter char *b; 50142372Speter 50242372Speter b = (char *) xmalloc (hdr.dirlistlen + 1); 50342372Speter if (fread(b, 1, hdr.dirlistlen + 1, f) != 50442372Speter hdr.dirlistlen + 1) 50542372Speter { 50642372Speter free(b); 507130565Sobrien b = NULL; 50842372Speter } 50942372Speter else 51042372Speter { 511130565Sobrien ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b); 512130565Sobrien free (b); 51342372Speter } 51442372Speter } 51542372Speter } 51642372Speter fclose (f); 51742372Speter } 51842372Speter 519130565Sobrien initialized = TRUE; 52042372Speter } 52142372Speter 52242372Speter if (ld_elf_hints == NULL) 523130565Sobrien return FALSE; 52442372Speter 52542372Speter return gld${EMULATION_NAME}_search_needed (ld_elf_hints, name, force); 52642372Speter} 52742372SpeterEOF 528130565Sobrien # FreeBSD 529130565Sobrien ;; 53060525Sobrien 531130565Sobrien *-*-linux-gnu*) 532130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 53333965Sjdp/* For a native linker, check the file /etc/ld.so.conf for directories 53433965Sjdp in which we may find shared libraries. /etc/ld.so.conf is really 53560525Sobrien only meaningful on Linux. */ 53633965Sjdp 537130565Sobrienstatic bfd_boolean 538130565Sobriengld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force) 53933965Sjdp{ 540130565Sobrien static bfd_boolean initialized; 54133965Sjdp static char *ld_so_conf; 54233965Sjdp 54333965Sjdp if (! initialized) 54433965Sjdp { 54533965Sjdp FILE *f; 546130565Sobrien char *tmppath; 54733965Sjdp 548130565Sobrien tmppath = concat (ld_sysroot, "/etc/ld.so.conf", NULL); 549130565Sobrien f = fopen (tmppath, FOPEN_RT); 550130565Sobrien free (tmppath); 55133965Sjdp if (f != NULL) 55233965Sjdp { 55333965Sjdp char *b; 55433965Sjdp size_t len, alloc; 55533965Sjdp int c; 55633965Sjdp 55733965Sjdp len = 0; 55833965Sjdp alloc = 100; 55933965Sjdp b = (char *) xmalloc (alloc); 56033965Sjdp 56133965Sjdp while ((c = getc (f)) != EOF) 56233965Sjdp { 56333965Sjdp if (len + 1 >= alloc) 56433965Sjdp { 56533965Sjdp alloc *= 2; 56633965Sjdp b = (char *) xrealloc (b, alloc); 56733965Sjdp } 56833965Sjdp if (c != ':' 56933965Sjdp && c != ' ' 57033965Sjdp && c != '\t' 57133965Sjdp && c != '\n' 57233965Sjdp && c != ',') 57333965Sjdp { 57433965Sjdp b[len] = c; 57533965Sjdp ++len; 57633965Sjdp } 57733965Sjdp else 57833965Sjdp { 57933965Sjdp if (len > 0 && b[len - 1] != ':') 58033965Sjdp { 58133965Sjdp b[len] = ':'; 58233965Sjdp ++len; 58333965Sjdp } 58433965Sjdp } 58533965Sjdp } 58633965Sjdp 58733965Sjdp if (len > 0 && b[len - 1] == ':') 58833965Sjdp --len; 58933965Sjdp 59033965Sjdp if (len > 0) 59133965Sjdp b[len] = '\0'; 59233965Sjdp else 59333965Sjdp { 59433965Sjdp free (b); 59533965Sjdp b = NULL; 59633965Sjdp } 59733965Sjdp 59833965Sjdp fclose (f); 59933965Sjdp 600130565Sobrien if (b) 601130565Sobrien { 602130565Sobrien char *d = gld${EMULATION_NAME}_add_sysroot (b); 603130565Sobrien free (b); 604130565Sobrien b = d; 605130565Sobrien } 606130565Sobrien 60733965Sjdp ld_so_conf = b; 60833965Sjdp } 60933965Sjdp 610130565Sobrien initialized = TRUE; 61133965Sjdp } 61233965Sjdp 61333965Sjdp if (ld_so_conf == NULL) 614130565Sobrien return FALSE; 61533965Sjdp 61638889Sjdp return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force); 61733965Sjdp} 61860525Sobrien 61933965SjdpEOF 620130565Sobrien # Linux 621130565Sobrien ;; 62260525Sobrien esac 62333965Sjdpfi 62433965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 62533965Sjdp 62677319Sobrien/* See if an input file matches a DT_NEEDED entry by name. */ 62733965Sjdp 62877319Sobrienstatic void 629130565Sobriengld${EMULATION_NAME}_check_needed (lang_input_statement_type *s) 63077319Sobrien{ 63177319Sobrien if (global_found) 63277319Sobrien return; 63333965Sjdp 63477319Sobrien if (s->filename != NULL) 63577319Sobrien { 63677319Sobrien const char *f; 63777319Sobrien 63877319Sobrien if (strcmp (s->filename, global_needed->name) == 0) 63977319Sobrien { 640130565Sobrien global_found = TRUE; 64177319Sobrien return; 64277319Sobrien } 64377319Sobrien 64477319Sobrien if (s->search_dirs_flag) 64577319Sobrien { 64677319Sobrien f = strrchr (s->filename, '/'); 64777319Sobrien if (f != NULL 64877319Sobrien && strcmp (f + 1, global_needed->name) == 0) 64977319Sobrien { 650130565Sobrien global_found = TRUE; 65177319Sobrien return; 65277319Sobrien } 65377319Sobrien } 65477319Sobrien } 65577319Sobrien 65677319Sobrien if (s->the_bfd != NULL) 65777319Sobrien { 65877319Sobrien const char *soname; 65977319Sobrien 66077319Sobrien soname = bfd_elf_get_dt_soname (s->the_bfd); 66177319Sobrien if (soname != NULL 66277319Sobrien && strcmp (soname, global_needed->name) == 0) 66377319Sobrien { 664130565Sobrien global_found = TRUE; 66577319Sobrien return; 66677319Sobrien } 66777319Sobrien } 66877319Sobrien} 66977319Sobrien 67077319SobrienEOF 67177319Sobrien 67277319Sobrienif test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then 67377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 67477319Sobrien 67533965Sjdp/* This is called after all the input files have been opened. */ 67633965Sjdp 67733965Sjdpstatic void 678130565Sobriengld${EMULATION_NAME}_after_open (void) 67933965Sjdp{ 68033965Sjdp struct bfd_link_needed_list *needed, *l; 68133965Sjdp 68233965Sjdp /* We only need to worry about this when doing a final link. */ 683130565Sobrien if (link_info.relocatable || !link_info.executable) 68433965Sjdp return; 68533965Sjdp 68633965Sjdp /* Get the list of files which appear in DT_NEEDED entries in 68733965Sjdp dynamic objects included in the link (often there will be none). 68833965Sjdp For each such file, we want to track down the corresponding 68933965Sjdp library, and include the symbol table in the link. This is what 69033965Sjdp the runtime dynamic linker will do. Tracking the files down here 69133965Sjdp permits one dynamic object to include another without requiring 69233965Sjdp special action by the person doing the link. Note that the 69333965Sjdp needed list can actually grow while we are stepping through this 69433965Sjdp loop. */ 69533965Sjdp needed = bfd_elf_get_needed_list (output_bfd, &link_info); 69633965Sjdp for (l = needed; l != NULL; l = l->next) 69733965Sjdp { 69833965Sjdp struct bfd_link_needed_list *ll; 69938889Sjdp int force; 70033965Sjdp 70133965Sjdp /* If we've already seen this file, skip it. */ 70233965Sjdp for (ll = needed; ll != l; ll = ll->next) 70333965Sjdp if (strcmp (ll->name, l->name) == 0) 70433965Sjdp break; 70533965Sjdp if (ll != l) 70633965Sjdp continue; 70733965Sjdp 70833965Sjdp /* See if this file was included in the link explicitly. */ 70933965Sjdp global_needed = l; 710130565Sobrien global_found = FALSE; 71133965Sjdp lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); 71233965Sjdp if (global_found) 71333965Sjdp continue; 71433965Sjdp 71577319Sobrien if (trace_file_tries) 71677319Sobrien info_msg (_("%s needed by %B\n"), l->name, l->by); 71777319Sobrien 71833965Sjdp /* We need to find this file and include the symbol table. We 71933965Sjdp want to search for the file in the same way that the dynamic 72033965Sjdp linker will search. That means that we want to use 72133965Sjdp rpath_link, rpath, then the environment variable 72277319Sobrien LD_LIBRARY_PATH (native only), then the DT_RPATH/DT_RUNPATH 72377319Sobrien entries (native only), then the linker script LIB_SEARCH_DIRS. 72477319Sobrien We do not search using the -L arguments. 72538889Sjdp 72638889Sjdp We search twice. The first time, we skip objects which may 72738889Sjdp introduce version mismatches. The second time, we force 72838889Sjdp their use. See gld${EMULATION_NAME}_vercheck comment. */ 72938889Sjdp for (force = 0; force < 2; force++) 73033965Sjdp { 73138889Sjdp size_t len; 73238889Sjdp search_dirs_type *search; 73377319SobrienEOF 734130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 73577319Sobriencat >>e${EMULATION_NAME}.c <<EOF 73677319Sobrien const char *lib_path; 73777319Sobrien struct bfd_link_needed_list *rp; 73877319Sobrien int found; 73977319SobrienEOF 74077319Sobrienfi 74177319Sobriencat >>e${EMULATION_NAME}.c <<EOF 74238889Sjdp 74338889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, 74438889Sjdp l->name, force)) 74538889Sjdp break; 74677319SobrienEOF 747130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 74877319Sobriencat >>e${EMULATION_NAME}.c <<EOF 74938889Sjdp if (gld${EMULATION_NAME}_search_needed (command_line.rpath, 75038889Sjdp l->name, force)) 75138889Sjdp break; 752130565SobrienEOF 753130565Sobrienfi 754130565Sobrienif [ "x${NATIVE}" = xyes ] ; then 755130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 75638889Sjdp if (command_line.rpath_link == NULL 75738889Sjdp && command_line.rpath == NULL) 75838889Sjdp { 75938889Sjdp lib_path = (const char *) getenv ("LD_RUN_PATH"); 76038889Sjdp if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, 76138889Sjdp force)) 76238889Sjdp break; 76338889Sjdp } 76438889Sjdp lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); 76538889Sjdp if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force)) 76638889Sjdp break; 767130565SobrienEOF 768130565Sobrienfi 769130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 770130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 77177319Sobrien found = 0; 77277319Sobrien rp = bfd_elf_get_runpath_list (output_bfd, &link_info); 77377319Sobrien for (; !found && rp != NULL; rp = rp->next) 77477319Sobrien { 775130565Sobrien char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name); 77677319Sobrien found = (rp->by == l->by 777130565Sobrien && gld${EMULATION_NAME}_search_needed (tmpname, 77877319Sobrien l->name, 77977319Sobrien force)); 780130565Sobrien free (tmpname); 78177319Sobrien } 78277319Sobrien if (found) 78377319Sobrien break; 78477319Sobrien 78533965SjdpEOF 78633965Sjdpfi 78733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 78838889Sjdp len = strlen (l->name); 78938889Sjdp for (search = search_head; search != NULL; search = search->next) 79038889Sjdp { 79138889Sjdp char *filename; 79233965Sjdp 79338889Sjdp if (search->cmdline) 79438889Sjdp continue; 79538889Sjdp filename = (char *) xmalloc (strlen (search->name) + len + 2); 79638889Sjdp sprintf (filename, "%s/%s", search->name, l->name); 79738889Sjdp if (gld${EMULATION_NAME}_try_needed (filename, force)) 79838889Sjdp break; 79938889Sjdp free (filename); 80038889Sjdp } 80138889Sjdp if (search != NULL) 80233965Sjdp break; 80333965SjdpEOF 804130565Sobrienif [ "x${USE_LIBPATH}" = xyes ] ; then 805130565Sobrien case ${target} in 806130565Sobrien *-*-freebsd*) 807130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 80842372Speter if (gld${EMULATION_NAME}_check_ld_elf_hints (l->name, force)) 80942372Speter break; 81042372SpeterEOF 811130565Sobrien # FreeBSD 812130565Sobrien ;; 813130565Sobrien 814130565Sobrien *-*-linux-gnu*) 815130565Sobrien cat >>e${EMULATION_NAME}.c <<EOF 81638889Sjdp if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force)) 81738889Sjdp break; 81833965SjdpEOF 819130565Sobrien # Linux 820130565Sobrien ;; 82160525Sobrien esac 82233965Sjdpfi 82333965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 82438889Sjdp } 82533965Sjdp 82638889Sjdp if (force < 2) 82738889Sjdp continue; 82838889Sjdp 82968778Sobrien einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n", 83033965Sjdp l->name, l->by); 83133965Sjdp } 83233965Sjdp} 83333965Sjdp 83438889SjdpEOF 83577319Sobrienfi 83638889Sjdp 83738889Sjdpcat >>e${EMULATION_NAME}.c <<EOF 83838889Sjdp 83977319Sobrien/* Look through an expression for an assignment statement. */ 84033965Sjdp 84133965Sjdpstatic void 842130565Sobriengld${EMULATION_NAME}_find_exp_assignment (etree_type *exp) 84333965Sjdp{ 84477319Sobrien struct bfd_link_hash_entry *h; 84533965Sjdp 84677319Sobrien switch (exp->type.node_class) 84733965Sjdp { 84877319Sobrien case etree_provide: 84977319Sobrien h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, 850130565Sobrien FALSE, FALSE, FALSE); 85177319Sobrien if (h == NULL) 85277319Sobrien break; 85333965Sjdp 85477319Sobrien /* We call record_link_assignment even if the symbol is defined. 85577319Sobrien This is because if it is defined by a dynamic object, we 85677319Sobrien actually want to use the value defined by the linker script, 85777319Sobrien not the value from the dynamic object (because we are setting 85877319Sobrien symbols like etext). If the symbol is defined by a regular 85977319Sobrien object, then, as it happens, calling record_link_assignment 86077319Sobrien will do no harm. */ 86133965Sjdp 86277319Sobrien /* Fall through. */ 86377319Sobrien case etree_assign: 86477319Sobrien if (strcmp (exp->assign.dst, ".") != 0) 86533965Sjdp { 866130565Sobrien if (! (bfd_elf_record_link_assignment 86777319Sobrien (output_bfd, &link_info, exp->assign.dst, 868130565Sobrien exp->type.node_class == etree_provide ? TRUE : FALSE))) 86977319Sobrien einfo ("%P%F: failed to record assignment to %s: %E\n", 87077319Sobrien exp->assign.dst); 87133965Sjdp } 87277319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); 87377319Sobrien break; 87433965Sjdp 87577319Sobrien case etree_binary: 87677319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); 87777319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); 87877319Sobrien break; 87933965Sjdp 88077319Sobrien case etree_trinary: 88177319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); 88277319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); 88377319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); 88477319Sobrien break; 88533965Sjdp 88677319Sobrien case etree_unary: 88777319Sobrien gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); 88877319Sobrien break; 88933965Sjdp 89077319Sobrien default: 89177319Sobrien break; 89233965Sjdp } 89333965Sjdp} 89433965Sjdp 89538889Sjdp 89677319Sobrien/* This is called by the before_allocation routine via 89777319Sobrien lang_for_each_statement. It locates any assignment statements, and 89877319Sobrien tells the ELF backend about them, in case they are assignments to 89977319Sobrien symbols which are referred to by dynamic objects. */ 90038889Sjdp 90138889Sjdpstatic void 902130565Sobriengld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s) 90338889Sjdp{ 90477319Sobrien if (s->header.type == lang_assignment_statement_enum) 90577319Sobrien gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); 90677319Sobrien} 90738889Sjdp 90877319SobrienEOF 90938889Sjdp 91077319Sobrienif test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then 91189872Sobrien if test x"${ELF_INTERPRETER_NAME+set}" = xset; then 91289872Sobrien ELF_INTERPRETER_SET_DEFAULT=" 91389872Sobrien if (sinterp != NULL) 91489872Sobrien { 91589872Sobrien sinterp->contents = ${ELF_INTERPRETER_NAME}; 91689872Sobrien sinterp->_raw_size = strlen (sinterp->contents) + 1; 91789872Sobrien } 91889872Sobrien 91989872Sobrien" 92089872Sobrien else 92189872Sobrien ELF_INTERPRETER_SET_DEFAULT= 92289872Sobrien fi 92377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 92438889Sjdp 92533965Sjdp/* This is called after the sections have been attached to output 92633965Sjdp sections, but before any sizes or addresses have been set. */ 92733965Sjdp 92833965Sjdpstatic void 929130565Sobriengld${EMULATION_NAME}_before_allocation (void) 93033965Sjdp{ 93133965Sjdp const char *rpath; 93233965Sjdp asection *sinterp; 93333965Sjdp 934130565Sobrien if (link_info.hash->type == bfd_link_elf_hash_table) 935130565Sobrien _bfd_elf_tls_setup (output_bfd, &link_info); 936130565Sobrien 93733965Sjdp /* If we are going to make any variable assignments, we need to let 93833965Sjdp the ELF backend know about them in case the variables are 93933965Sjdp referred to by dynamic objects. */ 94033965Sjdp lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment); 94133965Sjdp 94233965Sjdp /* Let the ELF backend work out the sizes of any sections required 94333965Sjdp by dynamic linking. */ 94433965Sjdp rpath = command_line.rpath; 94533965Sjdp if (rpath == NULL) 94633965Sjdp rpath = (const char *) getenv ("LD_RUN_PATH"); 947130565Sobrien if (! (bfd_elf_size_dynamic_sections 948130565Sobrien (output_bfd, command_line.soname, rpath, 94989872Sobrien command_line.filter_shlib, 95033965Sjdp (const char * const *) command_line.auxiliary_filters, 95133965Sjdp &link_info, &sinterp, lang_elf_version_info))) 95233965Sjdp einfo ("%P%F: failed to set dynamic section sizes: %E\n"); 95389872Sobrien${ELF_INTERPRETER_SET_DEFAULT} 95433965Sjdp /* Let the user override the dynamic linker we are using. */ 95533965Sjdp if (command_line.interpreter != NULL 95633965Sjdp && sinterp != NULL) 95733965Sjdp { 95833965Sjdp sinterp->contents = (bfd_byte *) command_line.interpreter; 95933965Sjdp sinterp->_raw_size = strlen (command_line.interpreter) + 1; 96033965Sjdp } 96133965Sjdp 96233965Sjdp /* Look for any sections named .gnu.warning. As a GNU extensions, 96333965Sjdp we treat such sections as containing warning messages. We print 96433965Sjdp out the warning message, and then zero out the section size so 96533965Sjdp that it does not get copied into the output file. */ 96633965Sjdp 96733965Sjdp { 96833965Sjdp LANG_FOR_EACH_INPUT_STATEMENT (is) 96933965Sjdp { 97033965Sjdp asection *s; 97133965Sjdp bfd_size_type sz; 972130565Sobrien bfd_size_type prefix_len; 97333965Sjdp char *msg; 974130565Sobrien bfd_boolean ret; 975130565Sobrien const char * gnu_warning_prefix = _("warning: "); 97633965Sjdp 97733965Sjdp if (is->just_syms_flag) 97833965Sjdp continue; 97933965Sjdp 98033965Sjdp s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning"); 98133965Sjdp if (s == NULL) 98233965Sjdp continue; 98333965Sjdp 98433965Sjdp sz = bfd_section_size (is->the_bfd, s); 985130565Sobrien prefix_len = strlen (gnu_warning_prefix); 986130565Sobrien msg = xmalloc ((size_t) (prefix_len + sz + 1)); 987130565Sobrien strcpy (msg, gnu_warning_prefix); 988130565Sobrien if (! bfd_get_section_contents (is->the_bfd, s, msg + prefix_len, 989130565Sobrien (file_ptr) 0, sz)) 99033965Sjdp einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", 99133965Sjdp is->the_bfd); 992130565Sobrien msg[prefix_len + sz] = '\0'; 99333965Sjdp ret = link_info.callbacks->warning (&link_info, msg, 99433965Sjdp (const char *) NULL, 99533965Sjdp is->the_bfd, (asection *) NULL, 99633965Sjdp (bfd_vma) 0); 99733965Sjdp ASSERT (ret); 99833965Sjdp free (msg); 99933965Sjdp 100033965Sjdp /* Clobber the section size, so that we don't waste copying the 100133965Sjdp warning into the output file. */ 100233965Sjdp s->_raw_size = 0; 100333965Sjdp } 100433965Sjdp } 100533965Sjdp} 100633965Sjdp 100777319SobrienEOF 100877319Sobrienfi 100933965Sjdp 101077319Sobrienif test x"$LDEMUL_OPEN_DYNAMIC_ARCHIVE" != xgld"$EMULATION_NAME"_open_dynamic_archive; then 101177319Sobriencat >>e${EMULATION_NAME}.c <<EOF 101233965Sjdp 101377319Sobrien/* Try to open a dynamic archive. This is where we know that ELF 101477319Sobrien dynamic libraries have an extension of .so (or .sl on oddball systems 101577319Sobrien like hpux). */ 101633965Sjdp 1017130565Sobrienstatic bfd_boolean 1018130565Sobriengld${EMULATION_NAME}_open_dynamic_archive 1019130565Sobrien (const char *arch, search_dirs_type *search, lang_input_statement_type *entry) 102033965Sjdp{ 102177319Sobrien const char *filename; 102277319Sobrien char *string; 102333965Sjdp 102477319Sobrien if (! entry->is_archive) 1025130565Sobrien return FALSE; 102677319Sobrien 102777319Sobrien filename = entry->filename; 102877319Sobrien 102977319Sobrien /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION 103077319Sobrien is defined, but it does not seem worth the headache to optimize 103177319Sobrien away those two bytes of space. */ 103277319Sobrien string = (char *) xmalloc (strlen (search->name) 103377319Sobrien + strlen (filename) 103477319Sobrien + strlen (arch) 103577319Sobrien#ifdef EXTRA_SHLIB_EXTENSION 103677319Sobrien + strlen (EXTRA_SHLIB_EXTENSION) 103777319Sobrien#endif 103877319Sobrien + sizeof "/lib.so"); 103977319Sobrien 104077319Sobrien sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); 104177319Sobrien 104277319Sobrien#ifdef EXTRA_SHLIB_EXTENSION 104377319Sobrien /* Try the .so extension first. If that fails build a new filename 104477319Sobrien using EXTRA_SHLIB_EXTENSION. */ 104577319Sobrien if (! ldfile_try_open_bfd (string, entry)) 104677319Sobrien sprintf (string, "%s/lib%s%s%s", search->name, 104777319Sobrien filename, arch, EXTRA_SHLIB_EXTENSION); 104877319Sobrien#endif 104977319Sobrien 105077319Sobrien if (! ldfile_try_open_bfd (string, entry)) 105133965Sjdp { 105277319Sobrien free (string); 1053130565Sobrien return FALSE; 105477319Sobrien } 105533965Sjdp 105677319Sobrien entry->filename = string; 105733965Sjdp 105877319Sobrien /* We have found a dynamic object to include in the link. The ELF 105977319Sobrien backend linker will create a DT_NEEDED entry in the .dynamic 106077319Sobrien section naming this file. If this file includes a DT_SONAME 106177319Sobrien entry, it will be used. Otherwise, the ELF linker will just use 106277319Sobrien the name of the file. For an archive found by searching, like 106377319Sobrien this one, the DT_NEEDED entry should consist of just the name of 106477319Sobrien the file, without the path information used to find it. Note 106577319Sobrien that we only need to do this if we have a dynamic object; an 106677319Sobrien archive will never be referenced by a DT_NEEDED entry. 106733965Sjdp 106877319Sobrien FIXME: This approach--using bfd_elf_set_dt_needed_name--is not 106977319Sobrien very pretty. I haven't been able to think of anything that is 107077319Sobrien pretty, though. */ 107177319Sobrien if (bfd_check_format (entry->the_bfd, bfd_object) 107277319Sobrien && (entry->the_bfd->flags & DYNAMIC) != 0) 107377319Sobrien { 107477319Sobrien ASSERT (entry->is_archive && entry->search_dirs_flag); 107533965Sjdp 107677319Sobrien /* Rather than duplicating the logic above. Just use the 107778841Sobrien filename we recorded earlier. */ 107833965Sjdp 107992835Sobrien filename = lbasename (entry->filename); 108078841Sobrien bfd_elf_set_dt_needed_name (entry->the_bfd, filename); 108133965Sjdp } 108277319Sobrien 1083130565Sobrien return TRUE; 108433965Sjdp} 108533965Sjdp 108677319SobrienEOF 108777319Sobrienfi 108889872Sobrien 108989872Sobrienif test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then 109077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 109177319Sobrien 109268778Sobrien/* A variant of lang_output_section_find. Used by place_orphan. */ 109368778Sobrien 109468778Sobrienstatic lang_output_section_statement_type * 1095130565Sobrienoutput_rel_find (asection *sec, int isdyn) 109668778Sobrien{ 109768778Sobrien lang_statement_union_type *u; 109868778Sobrien lang_output_section_statement_type *lookup; 1099107499Sobrien lang_output_section_statement_type *last = NULL; 1100130565Sobrien lang_output_section_statement_type *last_alloc = NULL; 1101107499Sobrien lang_output_section_statement_type *last_rel = NULL; 1102107499Sobrien lang_output_section_statement_type *last_rel_alloc = NULL; 1103107499Sobrien int rela = sec->name[4] == 'a'; 110468778Sobrien 1105107499Sobrien for (u = lang_output_section_statement.head; u; u = lookup->next) 110668778Sobrien { 110768778Sobrien lookup = &u->output_section_statement; 1108107499Sobrien if (strncmp (".rel", lookup->name, 4) == 0) 110968778Sobrien { 1110107499Sobrien int lookrela = lookup->name[4] == 'a'; 1111107499Sobrien 1112130565Sobrien /* .rel.dyn must come before all other reloc sections, to suit 1113130565Sobrien GNU ld.so. */ 1114130565Sobrien if (isdyn) 1115107499Sobrien break; 1116130565Sobrien 1117130565Sobrien /* Don't place after .rel.plt as doing so results in wrong 1118130565Sobrien dynamic tags. */ 1119130565Sobrien if (strcmp (".plt", lookup->name + 4 + lookrela) == 0) 1120130565Sobrien break; 1121130565Sobrien 1122130565Sobrien if (rela == lookrela || last_rel == NULL) 1123107499Sobrien last_rel = lookup; 1124130565Sobrien if ((rela == lookrela || last_rel_alloc == NULL) 1125130565Sobrien && lookup->bfd_section != NULL 1126107499Sobrien && (lookup->bfd_section->flags & SEC_ALLOC) != 0) 1127107499Sobrien last_rel_alloc = lookup; 112868778Sobrien } 1129130565Sobrien 1130130565Sobrien last = lookup; 1131130565Sobrien if (lookup->bfd_section != NULL 1132130565Sobrien && (lookup->bfd_section->flags & SEC_ALLOC) != 0) 1133130565Sobrien last_alloc = lookup; 113468778Sobrien } 1135107499Sobrien 1136107499Sobrien if (last_rel_alloc) 1137107499Sobrien return last_rel_alloc; 1138107499Sobrien 1139107499Sobrien if (last_rel) 1140107499Sobrien return last_rel; 1141107499Sobrien 1142130565Sobrien if (last_alloc) 1143130565Sobrien return last_alloc; 1144130565Sobrien 1145107499Sobrien return last; 114668778Sobrien} 114768778Sobrien 114889872Sobrien/* Find the last output section before given output statement. 114989872Sobrien Used by place_orphan. */ 115077319Sobrien 115189872Sobrienstatic asection * 1152130565Sobrienoutput_prev_sec_find (lang_output_section_statement_type *os) 115389872Sobrien{ 115489872Sobrien asection *s = (asection *) NULL; 115589872Sobrien lang_statement_union_type *u; 115689872Sobrien lang_output_section_statement_type *lookup; 115777319Sobrien 115889872Sobrien for (u = lang_output_section_statement.head; 115989872Sobrien u != (lang_statement_union_type *) NULL; 116089872Sobrien u = lookup->next) 116189872Sobrien { 116289872Sobrien lookup = &u->output_section_statement; 116389872Sobrien if (lookup == os) 116489872Sobrien return s; 116589872Sobrien 116689872Sobrien if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL) 116789872Sobrien s = lookup->bfd_section; 116889872Sobrien } 116989872Sobrien 117089872Sobrien return NULL; 117189872Sobrien} 117289872Sobrien 117333965Sjdp/* Place an orphan section. We use this to put random SHF_ALLOC 117433965Sjdp sections in the right segment. */ 117533965Sjdp 117668778Sobrienstruct orphan_save { 117768778Sobrien lang_output_section_statement_type *os; 117868778Sobrien asection **section; 117968778Sobrien lang_statement_union_type **stmt; 1180130565Sobrien lang_statement_union_type **os_tail; 118168778Sobrien}; 118233965Sjdp 1183130565Sobrienstatic bfd_boolean 1184130565Sobriengld${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s) 118533965Sjdp{ 118668778Sobrien static struct orphan_save hold_text; 118768778Sobrien static struct orphan_save hold_rodata; 118868778Sobrien static struct orphan_save hold_data; 118968778Sobrien static struct orphan_save hold_bss; 119068778Sobrien static struct orphan_save hold_rel; 119168778Sobrien static struct orphan_save hold_interp; 119277319Sobrien static struct orphan_save hold_sdata; 119377319Sobrien static int count = 1; 119468778Sobrien struct orphan_save *place; 119533965Sjdp lang_statement_list_type *old; 119633965Sjdp lang_statement_list_type add; 119733965Sjdp etree_type *address; 119868778Sobrien const char *secname; 119968778Sobrien const char *ps = NULL; 120033965Sjdp lang_output_section_statement_type *os; 1201130565Sobrien lang_statement_union_type **os_tail; 1202130565Sobrien etree_type *load_base; 1203107499Sobrien int isdyn = 0; 120433965Sjdp 120568778Sobrien secname = bfd_get_section_name (s->owner, s); 1206130565Sobrien if (! link_info.relocatable 1207107499Sobrien && link_info.combreloc 1208107499Sobrien && (s->flags & SEC_ALLOC) 1209107499Sobrien && strncmp (secname, ".rel", 4) == 0) 1210107499Sobrien { 1211107499Sobrien if (secname[4] == 'a') 1212107499Sobrien secname = ".rela.dyn"; 1213107499Sobrien else 1214107499Sobrien secname = ".rel.dyn"; 1215107499Sobrien isdyn = 1; 1216107499Sobrien } 121733965Sjdp 1218107499Sobrien if (isdyn || (!config.unique_orphan_sections && !unique_section_p (secname))) 121977319Sobrien { 122077319Sobrien /* Look through the script to see where to place this section. */ 122177319Sobrien os = lang_output_section_find (secname); 122233965Sjdp 122377319Sobrien if (os != NULL 122489872Sobrien && (os->bfd_section == NULL 122589872Sobrien || ((s->flags ^ os->bfd_section->flags) 122689872Sobrien & (SEC_LOAD | SEC_ALLOC)) == 0)) 122777319Sobrien { 122889872Sobrien /* We already have an output section statement with this 122989872Sobrien name, and its bfd section, if any, has compatible flags. */ 123089872Sobrien lang_add_section (&os->children, s, os, file); 1231130565Sobrien return TRUE; 123277319Sobrien } 123333965Sjdp } 123433965Sjdp 123568778Sobrien if (hold_text.os == NULL) 123668778Sobrien hold_text.os = lang_output_section_find (".text"); 123733965Sjdp 123833965Sjdp /* If this is a final link, then always put .gnu.warning.SYMBOL 123933965Sjdp sections into the .text section to get them out of the way. */ 1240130565Sobrien if (link_info.executable 1241130565Sobrien && ! link_info.relocatable 124233965Sjdp && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 124368778Sobrien && hold_text.os != NULL) 124433965Sjdp { 124589872Sobrien lang_add_section (&hold_text.os->children, s, hold_text.os, file); 1246130565Sobrien return TRUE; 124733965Sjdp } 124833965Sjdp 124933965Sjdp /* Decide which segment the section should go in based on the 125033965Sjdp section name and section flags. We put loadable .note sections 125133965Sjdp right after the .interp section, so that the PT_NOTE segment is 125233965Sjdp stored right after the program headers where the OS can read it 125333965Sjdp in the first page. */ 125468778Sobrien#define HAVE_SECTION(hold, name) \ 125568778Sobrien(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL) 125668778Sobrien 1257130565Sobrien if ((s->flags & SEC_EXCLUDE) != 0 && !link_info.relocatable) 125889872Sobrien { 125989872Sobrien if (s->output_section == NULL) 126089872Sobrien s->output_section = bfd_abs_section_ptr; 1261130565Sobrien return TRUE; 126289872Sobrien } 126368778Sobrien 126468778Sobrien place = NULL; 126568778Sobrien if ((s->flags & SEC_ALLOC) == 0) 126668778Sobrien ; 126760525Sobrien else if ((s->flags & SEC_LOAD) != 0 126877319Sobrien && strncmp (secname, ".note", 5) == 0 126968778Sobrien && HAVE_SECTION (hold_interp, ".interp")) 127068778Sobrien place = &hold_interp; 127133965Sjdp else if ((s->flags & SEC_HAS_CONTENTS) == 0 127268778Sobrien && HAVE_SECTION (hold_bss, ".bss")) 127368778Sobrien place = &hold_bss; 127477319Sobrien else if ((s->flags & SEC_SMALL_DATA) != 0 127577319Sobrien && HAVE_SECTION (hold_sdata, ".sdata")) 127677319Sobrien place = &hold_sdata; 127733965Sjdp else if ((s->flags & SEC_READONLY) == 0 127868778Sobrien && HAVE_SECTION (hold_data, ".data")) 127968778Sobrien place = &hold_data; 128033965Sjdp else if (strncmp (secname, ".rel", 4) == 0 1281107499Sobrien && (s->flags & SEC_LOAD) != 0 128268778Sobrien && (hold_rel.os != NULL 1283130565Sobrien || (hold_rel.os = output_rel_find (s, isdyn)) != NULL)) 1284107499Sobrien place = &hold_rel; 128568778Sobrien else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY 128668778Sobrien && HAVE_SECTION (hold_rodata, ".rodata")) 128768778Sobrien place = &hold_rodata; 128868778Sobrien else if ((s->flags & (SEC_CODE | SEC_READONLY)) == (SEC_CODE | SEC_READONLY) 128968778Sobrien && hold_text.os != NULL) 129068778Sobrien place = &hold_text; 129133965Sjdp 129268778Sobrien#undef HAVE_SECTION 129368778Sobrien 129433965Sjdp /* Choose a unique name for the section. This will be needed if the 129533965Sjdp same section name appears in the input file with different 129677319Sobrien loadable or allocatable characteristics. */ 1297107499Sobrien if (bfd_get_section_by_name (output_bfd, secname) != NULL) 129833965Sjdp { 1299107499Sobrien secname = bfd_get_unique_section_name (output_bfd, secname, &count); 1300107499Sobrien if (secname == NULL) 130177319Sobrien einfo ("%F%P: place_orphan failed: %E\n"); 130233965Sjdp } 130333965Sjdp 130468778Sobrien /* Start building a list of statements for this section. 130568778Sobrien First save the current statement pointer. */ 130668778Sobrien old = stat_ptr; 130768778Sobrien 130868778Sobrien /* If we have found an appropriate place for the output section 130968778Sobrien statements for this orphan, add them to our own private list, 131068778Sobrien inserting them later into the global statement list. */ 131168778Sobrien if (place != NULL) 131233965Sjdp { 131368778Sobrien stat_ptr = &add; 131468778Sobrien lang_list_init (stat_ptr); 131533965Sjdp } 131633965Sjdp 131768778Sobrien if (config.build_constructors) 131833965Sjdp { 131968778Sobrien /* If the name of the section is representable in C, then create 132068778Sobrien symbols to mark the start and the end of the section. */ 1321107499Sobrien for (ps = secname; *ps != '\0'; ps++) 132289872Sobrien if (! ISALNUM (*ps) && *ps != '_') 132368778Sobrien break; 132468778Sobrien if (*ps == '\0') 132568778Sobrien { 132668778Sobrien char *symname; 132768778Sobrien etree_type *e_align; 132833965Sjdp 1329107499Sobrien symname = (char *) xmalloc (ps - secname + sizeof "__start_"); 1330107499Sobrien sprintf (symname, "__start_%s", secname); 133168778Sobrien e_align = exp_unop (ALIGN_K, 133268778Sobrien exp_intop ((bfd_vma) 1 << s->alignment_power)); 133368778Sobrien lang_add_assignment (exp_assop ('=', symname, e_align)); 133468778Sobrien } 133533965Sjdp } 133633965Sjdp 1337130565Sobrien address = NULL; 1338130565Sobrien if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) 133968778Sobrien address = exp_intop ((bfd_vma) 0); 134033965Sjdp 1341130565Sobrien load_base = NULL; 1342130565Sobrien if (place != NULL && place->os->load_base != NULL) 1343130565Sobrien { 1344130565Sobrien etree_type *lma_from_vma; 1345130565Sobrien lma_from_vma = exp_binop ('-', place->os->load_base, 1346130565Sobrien exp_nameop (ADDR, place->os->name)); 1347130565Sobrien load_base = exp_binop ('+', lma_from_vma, 1348130565Sobrien exp_nameop (ADDR, secname)); 1349130565Sobrien } 1350130565Sobrien 1351130565Sobrien os_tail = lang_output_section_statement.tail; 1352107499Sobrien os = lang_enter_output_section_statement (secname, address, 0, 135368778Sobrien (etree_type *) NULL, 135468778Sobrien (etree_type *) NULL, 1355130565Sobrien load_base); 135633965Sjdp 135789872Sobrien lang_add_section (&os->children, s, os, file); 135833965Sjdp 135933965Sjdp lang_leave_output_section_statement 136068778Sobrien ((bfd_vma) 0, "*default*", 1361104847Sobrien (struct lang_output_section_phdr_list *) NULL, NULL); 136233965Sjdp 136368778Sobrien if (config.build_constructors && *ps == '\0') 136433965Sjdp { 136533965Sjdp char *symname; 136633965Sjdp 136768778Sobrien /* lang_leave_ouput_section_statement resets stat_ptr. Put 136868778Sobrien stat_ptr back where we want it. */ 136968778Sobrien if (place != NULL) 137068778Sobrien stat_ptr = &add; 137168778Sobrien 1372107499Sobrien symname = (char *) xmalloc (ps - secname + sizeof "__stop_"); 1373107499Sobrien sprintf (symname, "__stop_%s", secname); 137433965Sjdp lang_add_assignment (exp_assop ('=', symname, 137533965Sjdp exp_nameop (NAME, "."))); 137633965Sjdp } 137733965Sjdp 137868778Sobrien /* Restore the global list pointer. */ 137933965Sjdp stat_ptr = old; 138033965Sjdp 1381104847Sobrien if (place != NULL && os->bfd_section != NULL) 138268778Sobrien { 138368778Sobrien asection *snew, **pps; 138433965Sjdp 138568778Sobrien snew = os->bfd_section; 138689872Sobrien 138789872Sobrien /* Shuffle the bfd section list to make the output file look 138889872Sobrien neater. This is really only cosmetic. */ 138989872Sobrien if (place->section == NULL) 139068778Sobrien { 139189872Sobrien asection *bfd_section = place->os->bfd_section; 139233965Sjdp 139389872Sobrien /* If the output statement hasn't been used to place 139489872Sobrien any input sections (and thus doesn't have an output 139589872Sobrien bfd_section), look for the closest prior output statement 139689872Sobrien having an output section. */ 139789872Sobrien if (bfd_section == NULL) 139889872Sobrien bfd_section = output_prev_sec_find (place->os); 139989872Sobrien 140089872Sobrien if (bfd_section != NULL && bfd_section != snew) 140189872Sobrien place->section = &bfd_section->next; 140289872Sobrien } 140389872Sobrien 140489872Sobrien if (place->section != NULL) 140589872Sobrien { 140689872Sobrien /* Unlink the section. */ 140768778Sobrien for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) 140868778Sobrien ; 140989872Sobrien bfd_section_list_remove (output_bfd, pps); 141033965Sjdp 141168778Sobrien /* Now tack it on to the "place->os" section list. */ 141289872Sobrien bfd_section_list_insert (output_bfd, place->section, snew); 141368778Sobrien } 141433965Sjdp 141589872Sobrien /* Save the end of this list. Further ophans of this type will 141689872Sobrien follow the one we've just added. */ 141789872Sobrien place->section = &snew->next; 141889872Sobrien 141989872Sobrien /* The following is non-cosmetic. We try to put the output 142089872Sobrien statements in some sort of reasonable order here, because 142189872Sobrien they determine the final load addresses of the orphan 142289872Sobrien sections. In addition, placing output statements in the 142389872Sobrien wrong order may require extra segments. For instance, 142489872Sobrien given a typical situation of all read-only sections placed 142589872Sobrien in one segment and following that a segment containing all 142689872Sobrien the read-write sections, we wouldn't want to place an orphan 142789872Sobrien read/write section before or amongst the read-only ones. */ 142868778Sobrien if (add.head != NULL) 142968778Sobrien { 1430130565Sobrien lang_statement_union_type *newly_added_os; 1431130565Sobrien 143268778Sobrien if (place->stmt == NULL) 143368778Sobrien { 143468778Sobrien /* Put the new statement list right at the head. */ 143568778Sobrien *add.tail = place->os->header.next; 143668778Sobrien place->os->header.next = add.head; 1437130565Sobrien 1438130565Sobrien place->os_tail = &place->os->next; 143968778Sobrien } 144068778Sobrien else 144168778Sobrien { 144268778Sobrien /* Put it after the last orphan statement we added. */ 144368778Sobrien *add.tail = *place->stmt; 144468778Sobrien *place->stmt = add.head; 144568778Sobrien } 144633965Sjdp 144768778Sobrien /* Fix the global list pointer if we happened to tack our 144868778Sobrien new list at the tail. */ 144968778Sobrien if (*old->tail == add.head) 145068778Sobrien old->tail = add.tail; 145168778Sobrien 145268778Sobrien /* Save the end of this list. */ 145368778Sobrien place->stmt = add.tail; 1454130565Sobrien 1455130565Sobrien /* Do the same for the list of output section statements. */ 1456130565Sobrien newly_added_os = *os_tail; 1457130565Sobrien *os_tail = NULL; 1458130565Sobrien newly_added_os->output_section_statement.next = *place->os_tail; 1459130565Sobrien *place->os_tail = newly_added_os; 1460130565Sobrien place->os_tail = &newly_added_os->output_section_statement.next; 1461130565Sobrien 1462130565Sobrien /* Fixing the global list pointer here is a little different. 1463130565Sobrien We added to the list in lang_enter_output_section_statement, 1464130565Sobrien trimmed off the new output_section_statment above when 1465130565Sobrien assigning *os_tail = NULL, but possibly added it back in 1466130565Sobrien the same place when assigning *place->os_tail. */ 1467130565Sobrien if (*os_tail == NULL) 1468130565Sobrien lang_output_section_statement.tail = os_tail; 146968778Sobrien } 147068778Sobrien } 147168778Sobrien 1472130565Sobrien return TRUE; 147333965Sjdp} 147489872SobrienEOF 147589872Sobrienfi 147633965Sjdp 147789872Sobrienif test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then 147889872Sobriencat >>e${EMULATION_NAME}.c <<EOF 147989872Sobrien 148089872Sobrienstatic void 1481130565Sobriengld${EMULATION_NAME}_finish (void) 148289872Sobrien{ 1483130565Sobrien if (bfd_elf_discard_info (output_bfd, &link_info)) 148489872Sobrien { 148591055Sobrien lang_reset_memory_regions (); 148691055Sobrien 148789872Sobrien /* Resize the sections. */ 148889872Sobrien lang_size_sections (stat_ptr->head, abs_output_section, 1489130565Sobrien &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); 149089872Sobrien 149189872Sobrien /* Redo special stuff. */ 149289872Sobrien ldemul_after_allocation (); 149389872Sobrien 149489872Sobrien /* Do the assignments again. */ 149589872Sobrien lang_do_assignments (stat_ptr->head, abs_output_section, 1496104847Sobrien (fill_type *) 0, (bfd_vma) 0); 149789872Sobrien } 149889872Sobrien} 149977319SobrienEOF 150077319Sobrienfi 150177319Sobrien 150277319Sobrienif test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then 150377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 150477319Sobrien 150533965Sjdpstatic char * 1506130565Sobriengld${EMULATION_NAME}_get_script (int *isfile) 150733965SjdpEOF 150833965Sjdp 150933965Sjdpif test -n "$COMPILE_IN" 151033965Sjdpthen 151133965Sjdp# Scripts compiled in. 151233965Sjdp 151333965Sjdp# sed commands to quote an ld script as a C string. 151460525Sobriensc="-f stringify.sed" 151533965Sjdp 151633965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 151777319Sobrien{ 151833965Sjdp *isfile = 0; 151933965Sjdp 1520130565Sobrien if (link_info.relocatable && config.build_constructors) 152160525Sobrien return 152233965SjdpEOF 1523130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c 1524130565Sobrienecho ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c 1525130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c 1526130565Sobrienecho ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c 1527130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c 152889872Sobrienif cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; else 1529130565Sobrienecho ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c 1530130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c 153189872Sobrienfi 1532130565Sobrienif test -n "$GENERATE_PIE_SCRIPT" ; then 1533130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1534130565Sobrienecho ' ; else if (link_info.pie && link_info.combreloc) return' >> e${EMULATION_NAME}.c 1535130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c 1536130565Sobrienfi 1537130565Sobrienecho ' ; else if (link_info.pie) return' >> e${EMULATION_NAME}.c 1538130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c 1539130565Sobrienfi 154060525Sobrienif test -n "$GENERATE_SHLIB_SCRIPT" ; then 1541104847Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 154289872Sobrienecho ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c 1543130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c 1544104847Sobrienfi 1545130565Sobrienecho ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c 1546130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c 154760525Sobrienfi 1548104847Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1549130565Sobrienecho ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c 1550130565Sobriensed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c 1551104847Sobrienfi 1552130565Sobrienecho ' ; else return' >> e${EMULATION_NAME}.c 1553130565Sobriensed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c 1554130565Sobrienecho '; }' >> e${EMULATION_NAME}.c 155560525Sobrien 155633965Sjdpelse 155733965Sjdp# Scripts read from the filesystem. 155833965Sjdp 155933965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 156077319Sobrien{ 156133965Sjdp *isfile = 1; 156233965Sjdp 1563130565Sobrien if (link_info.relocatable && config.build_constructors) 156433965Sjdp return "ldscripts/${EMULATION_NAME}.xu"; 1565130565Sobrien else if (link_info.relocatable) 156633965Sjdp return "ldscripts/${EMULATION_NAME}.xr"; 156733965Sjdp else if (!config.text_read_only) 156833965Sjdp return "ldscripts/${EMULATION_NAME}.xbn"; 1569130565SobrienEOF 1570130565Sobrienif cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : 1571130565Sobrienelse 1572130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 157333965Sjdp else if (!config.magic_demand_paged) 157433965Sjdp return "ldscripts/${EMULATION_NAME}.xn"; 1575130565SobrienEOF 1576130565Sobrienfi 1577130565Sobrienif test -n "$GENERATE_PIE_SCRIPT" ; then 1578130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1579130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1580130565Sobrien else if (link_info.pie && link_info.combreloc) 1581130565Sobrien return "ldscripts/${EMULATION_NAME}.xdc"; 1582130565SobrienEOF 1583130565Sobrienfi 1584130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1585130565Sobrien else if (link_info.pie) 1586130565Sobrien return "ldscripts/${EMULATION_NAME}.xd"; 1587130565SobrienEOF 1588130565Sobrienfi 1589130565Sobrienif test -n "$GENERATE_SHLIB_SCRIPT" ; then 1590130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1591130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1592130565Sobrien else if (link_info.shared && link_info.combreloc) 1593130565Sobrien return "ldscripts/${EMULATION_NAME}.xsc"; 1594130565SobrienEOF 1595130565Sobrienfi 1596130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 159733965Sjdp else if (link_info.shared) 159833965Sjdp return "ldscripts/${EMULATION_NAME}.xs"; 1599130565SobrienEOF 1600130565Sobrienfi 1601130565Sobrienif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then 1602130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 1603130565Sobrien else if (link_info.combreloc) 1604130565Sobrien return "ldscripts/${EMULATION_NAME}.xc"; 1605130565SobrienEOF 1606130565Sobrienfi 1607130565Sobriencat >>e${EMULATION_NAME}.c <<EOF 160833965Sjdp else 160933965Sjdp return "ldscripts/${EMULATION_NAME}.x"; 161033965Sjdp} 161177319Sobrien 161233965SjdpEOF 161377319Sobrienfi 161477319Sobrienfi 161533965Sjdp 161677319Sobrienif test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then 161777319Sobrien 161877319Sobrienif test -n "$PARSE_AND_LIST_PROLOGUE" ; then 161977319Sobriencat >>e${EMULATION_NAME}.c <<EOF 162077319Sobrien $PARSE_AND_LIST_PROLOGUE 162177319SobrienEOF 162233965Sjdpfi 162333965Sjdp 162433965Sjdpcat >>e${EMULATION_NAME}.c <<EOF 162533965Sjdp 162677319Sobrien#define OPTION_DISABLE_NEW_DTAGS (400) 162777319Sobrien#define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1) 162878841Sobrien#define OPTION_GROUP (OPTION_ENABLE_NEW_DTAGS + 1) 162989872Sobrien#define OPTION_EH_FRAME_HDR (OPTION_GROUP + 1) 163077319Sobrien 1631130565Sobrienstatic void 1632130565Sobriengld${EMULATION_NAME}_add_options 1633130565Sobrien (int ns, char **shortopts, int nl, struct option **longopts, 1634130565Sobrien int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED) 163577319Sobrien{ 1636130565Sobrien static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:"; 1637130565Sobrien static const struct option xtra_long[] = { 163860525SobrienEOF 163960525Sobrien 164077319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 164160525Sobriencat >>e${EMULATION_NAME}.c <<EOF 1642130565Sobrien {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS}, 1643130565Sobrien {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS}, 1644130565Sobrien {"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR}, 1645130565Sobrien {"Bgroup", no_argument, NULL, OPTION_GROUP}, 164660525SobrienEOF 164777319Sobrienfi 164860525Sobrien 164977319Sobrienif test -n "$PARSE_AND_LIST_LONGOPTS" ; then 165077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 1651130565Sobrien $PARSE_AND_LIST_LONGOPTS 165277319SobrienEOF 165360525Sobrienfi 165460525Sobrien 165560525Sobriencat >>e${EMULATION_NAME}.c <<EOF 1656130565Sobrien {NULL, no_argument, NULL, 0} 1657130565Sobrien }; 165860525Sobrien 1659130565Sobrien *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short)); 1660130565Sobrien memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short)); 1661130565Sobrien *longopts = (struct option *) 1662130565Sobrien xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); 1663130565Sobrien memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); 1664130565Sobrien} 166577319Sobrien 1666130565Sobrienstatic bfd_boolean 1667130565Sobriengld${EMULATION_NAME}_handle_option (int optc) 166833965Sjdp{ 166977319Sobrien switch (optc) 167077319Sobrien { 167177319Sobrien default: 1672130565Sobrien return FALSE; 167377319Sobrien 167477319SobrienEOF 167577319Sobrien 167677319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 167777319Sobriencat >>e${EMULATION_NAME}.c <<EOF 167877319Sobrien case OPTION_DISABLE_NEW_DTAGS: 1679130565Sobrien link_info.new_dtags = FALSE; 168077319Sobrien break; 168177319Sobrien 168277319Sobrien case OPTION_ENABLE_NEW_DTAGS: 1683130565Sobrien link_info.new_dtags = TRUE; 168477319Sobrien break; 168577319Sobrien 168689872Sobrien case OPTION_EH_FRAME_HDR: 1687130565Sobrien link_info.eh_frame_hdr = TRUE; 168889872Sobrien break; 168989872Sobrien 169078841Sobrien case OPTION_GROUP: 169178841Sobrien link_info.flags_1 |= (bfd_vma) DF_1_GROUP; 169278841Sobrien /* Groups must be self-contained. */ 1693130565Sobrien link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR; 1694130565Sobrien link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR; 169578841Sobrien break; 169678841Sobrien 169777319Sobrien case 'z': 169877319Sobrien if (strcmp (optarg, "initfirst") == 0) 169977319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST; 170077319Sobrien else if (strcmp (optarg, "interpose") == 0) 170177319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_INTERPOSE; 170277319Sobrien else if (strcmp (optarg, "loadfltr") == 0) 170377319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_LOADFLTR; 170477319Sobrien else if (strcmp (optarg, "nodefaultlib") == 0) 170577319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODEFLIB; 170677319Sobrien else if (strcmp (optarg, "nodelete") == 0) 170777319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODELETE; 170877319Sobrien else if (strcmp (optarg, "nodlopen") == 0) 170977319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NOOPEN; 171077319Sobrien else if (strcmp (optarg, "nodump") == 0) 171177319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NODUMP; 171277319Sobrien else if (strcmp (optarg, "now") == 0) 171377319Sobrien { 171477319Sobrien link_info.flags |= (bfd_vma) DF_BIND_NOW; 171577319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_NOW; 171677319Sobrien } 171777319Sobrien else if (strcmp (optarg, "origin") == 0) 171877319Sobrien { 171977319Sobrien link_info.flags |= (bfd_vma) DF_ORIGIN; 172077319Sobrien link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN; 172177319Sobrien } 172278841Sobrien else if (strcmp (optarg, "defs") == 0) 1723130565Sobrien link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR; 1724104847Sobrien else if (strcmp (optarg, "muldefs") == 0) 1725130565Sobrien link_info.allow_multiple_definition = TRUE; 172689872Sobrien else if (strcmp (optarg, "combreloc") == 0) 1727130565Sobrien link_info.combreloc = TRUE; 172889872Sobrien else if (strcmp (optarg, "nocombreloc") == 0) 1729130565Sobrien link_info.combreloc = FALSE; 173089872Sobrien else if (strcmp (optarg, "nocopyreloc") == 0) 1731130565Sobrien link_info.nocopyreloc = TRUE; 1732130565Sobrien else if (strcmp (optarg, "execstack") == 0) 1733130565Sobrien { 1734130565Sobrien link_info.execstack = TRUE; 1735130565Sobrien link_info.noexecstack = FALSE; 1736130565Sobrien } 1737130565Sobrien else if (strcmp (optarg, "noexecstack") == 0) 1738130565Sobrien { 1739130565Sobrien link_info.noexecstack = TRUE; 1740130565Sobrien link_info.execstack = FALSE; 1741130565Sobrien } 174277319Sobrien /* What about the other Solaris -z options? FIXME. */ 174377319Sobrien break; 174477319SobrienEOF 174577319Sobrienfi 174677319Sobrien 174777319Sobrienif test -n "$PARSE_AND_LIST_ARGS_CASES" ; then 174877319Sobriencat >>e${EMULATION_NAME}.c <<EOF 174977319Sobrien $PARSE_AND_LIST_ARGS_CASES 175077319SobrienEOF 175177319Sobrienfi 175277319Sobrien 175377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 175477319Sobrien } 175577319Sobrien 1756130565Sobrien return TRUE; 175777319Sobrien} 175877319Sobrien 175977319SobrienEOF 176077319Sobrien 176177319Sobrienif test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then 176277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 176377319Sobrien 176477319Sobrienstatic void 1765130565Sobriengld${EMULATION_NAME}_list_options (FILE * file) 176677319Sobrien{ 176777319SobrienEOF 176877319Sobrien 176977319Sobrienif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then 177077319Sobriencat >>e${EMULATION_NAME}.c <<EOF 177178841Sobrien fprintf (file, _(" -Bgroup\t\tSelects group name lookup rules for DSO\n")); 177277319Sobrien fprintf (file, _(" --disable-new-dtags\tDisable new dynamic tags\n")); 177377319Sobrien fprintf (file, _(" --enable-new-dtags\tEnable new dynamic tags\n")); 177489872Sobrien fprintf (file, _(" --eh-frame-hdr\tCreate .eh_frame_hdr section\n")); 177589872Sobrien fprintf (file, _(" -z combreloc\t\tMerge dynamic relocs into one section and sort\n")); 1776130565Sobrien fprintf (file, _(" -z defs\t\tReport unresolved symbols in object files.\n")); 1777130565Sobrien fprintf (file, _(" -z execstack\t\tMark executable as requiring executable stack\n")); 177877319Sobrien fprintf (file, _(" -z initfirst\t\tMark DSO to be initialized first at runtime\n")); 177977319Sobrien fprintf (file, _(" -z interpose\t\tMark object to interpose all DSOs but executable\n")); 178077319Sobrien fprintf (file, _(" -z loadfltr\t\tMark object requiring immediate process\n")); 1781104847Sobrien fprintf (file, _(" -z muldefs\t\tAllow multiple definitions\n")); 178289872Sobrien fprintf (file, _(" -z nocombreloc\tDon't merge dynamic relocs into one section\n")); 178389872Sobrien fprintf (file, _(" -z nocopyreloc\tDon't create copy relocs\n")); 178477319Sobrien fprintf (file, _(" -z nodefaultlib\tMark object not to use default search paths\n")); 178577319Sobrien fprintf (file, _(" -z nodelete\t\tMark DSO non-deletable at runtime\n")); 178677319Sobrien fprintf (file, _(" -z nodlopen\t\tMark DSO not available to dlopen\n")); 178777319Sobrien fprintf (file, _(" -z nodump\t\tMark DSO not available to dldump\n")); 1788130565Sobrien fprintf (file, _(" -z noexecstack\tMark executable as not requiring executable stack\n")); 178977319Sobrien fprintf (file, _(" -z now\t\tMark object non-lazy runtime binding\n")); 179089872Sobrien fprintf (file, _(" -z origin\t\tMark object requiring immediate \$ORIGIN processing\n\t\t\t at runtime\n")); 179177319Sobrien fprintf (file, _(" -z KEYWORD\t\tIgnored for Solaris compatibility\n")); 179277319SobrienEOF 179377319Sobrienfi 179477319Sobrien 179577319Sobrienif test -n "$PARSE_AND_LIST_OPTIONS" ; then 179677319Sobriencat >>e${EMULATION_NAME}.c <<EOF 179777319Sobrien $PARSE_AND_LIST_OPTIONS 179877319SobrienEOF 179977319Sobrienfi 180077319Sobrien 180177319Sobriencat >>e${EMULATION_NAME}.c <<EOF 180277319Sobrien} 180377319SobrienEOF 180477319Sobrien 180577319Sobrienif test -n "$PARSE_AND_LIST_EPILOGUE" ; then 180677319Sobriencat >>e${EMULATION_NAME}.c <<EOF 180777319Sobrien $PARSE_AND_LIST_EPILOGUE 180877319SobrienEOF 180977319Sobrienfi 181077319Sobrienfi 181177319Sobrienelse 181277319Sobriencat >>e${EMULATION_NAME}.c <<EOF 1813130565Sobrien#define gld${EMULATION_NAME}_add_options NULL 1814130565Sobrien#define gld${EMULATION_NAME}_handle_option NULL 181577319SobrienEOF 181677319Sobrienif test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then 181777319Sobriencat >>e${EMULATION_NAME}.c <<EOF 181877319Sobrien#define gld${EMULATION_NAME}_list_options NULL 181977319SobrienEOF 182077319Sobrienfi 182177319Sobrienfi 182277319Sobrien 182377319Sobriencat >>e${EMULATION_NAME}.c <<EOF 182477319Sobrien 182577319Sobrienstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 182677319Sobrien{ 182777319Sobrien ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse}, 182877319Sobrien ${LDEMUL_SYSLIB-syslib_default}, 182977319Sobrien ${LDEMUL_HLL-hll_default}, 183077319Sobrien ${LDEMUL_AFTER_PARSE-after_parse_default}, 183177319Sobrien ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open}, 183277319Sobrien ${LDEMUL_AFTER_ALLOCATION-after_allocation_default}, 183377319Sobrien ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default}, 183477319Sobrien ${LDEMUL_CHOOSE_TARGET-ldemul_default_target}, 183577319Sobrien ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation}, 183677319Sobrien ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, 183733965Sjdp "${EMULATION_NAME}", 183833965Sjdp "${OUTPUT_FORMAT}", 183989872Sobrien ${LDEMUL_FINISH-gld${EMULATION_NAME}_finish}, 184077319Sobrien ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, 184177319Sobrien ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive}, 184277319Sobrien ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan}, 184377319Sobrien ${LDEMUL_SET_SYMBOLS-NULL}, 1844130565Sobrien ${LDEMUL_PARSE_ARGS-NULL}, 1845130565Sobrien gld${EMULATION_NAME}_add_options, 1846130565Sobrien gld${EMULATION_NAME}_handle_option, 184777319Sobrien ${LDEMUL_UNRECOGNIZED_FILE-NULL}, 184877319Sobrien ${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options}, 1849130565Sobrien ${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols}, 185077319Sobrien ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL}, 1851104847Sobrien ${LDEMUL_NEW_VERS_PATTERN-NULL} 185233965Sjdp}; 185333965SjdpEOF 1854