diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2004-05-17 21:54:57 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2004-05-17 21:54:57 +0000 |
commit | 631eeff208608ed7b44459bd6c8ae905bcd7e8b6 (patch) | |
tree | 7be124105a0929655708fbbc134f9c2e3189c3f3 /gnu/usr.bin/binutils/ld/emultempl | |
parent | a7c8e0ae4a4b349099d02bc9d56bcf1979c0f0c3 (diff) |
Resolve merge conflicts, adjust method of W^X handing (.sh files)
remove testsuites (not useable) remove mmalloc (not part of new binutils).
Diffstat (limited to 'gnu/usr.bin/binutils/ld/emultempl')
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/aix.em | 852 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/elf32.em | 755 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/elfobsd.em | 1036 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/generic.em | 90 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/gld960.em | 49 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/gld960c.em | 53 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/hppaelf.em | 210 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/linux.em | 68 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/lnk960.em | 192 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em | 49 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/pe.em | 1122 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/sunos.em | 111 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/ld/emultempl/vanilla.em | 13 |
13 files changed, 2285 insertions, 2315 deletions
diff --git a/gnu/usr.bin/binutils/ld/emultempl/aix.em b/gnu/usr.bin/binutils/ld/emultempl/aix.em index de07f297f47..910f831b897 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/aix.em +++ b/gnu/usr.bin/binutils/ld/emultempl/aix.em @@ -1,13 +1,19 @@ # This shell script emits a C file. -*- C -*- # It does some substitutions. +if [ -z "$MACHINE" ]; then + OUTPUT_ARCH=${ARCH} +else + OUTPUT_ARCH=${ARCH}:${MACHINE} +fi cat >e${EMULATION_NAME}.c <<EOF /* This file is is generated by a shell script. DO NOT EDIT! */ /* AIX emulation code for ${EMULATION_NAME} - Copyright 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2001 + Copyright 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Written by Steve Chamberlain <sac@cygnus.com> AIX support by Ian Lance Taylor <ian@cygnus.com> + AIX 64 bit support by Tom Rix <trix@redhat.com> This file is part of GLD, the Gnu Linker. @@ -30,12 +36,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" #include "libiberty.h" +#include "safe-ctype.h" #include "getopt.h" #include "obstack.h" #include "bfdlink.h" -#include <ctype.h> - #include "ld.h" #include "ldmain.h" #include "ldmisc.h" @@ -44,18 +49,47 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ldfile.h" #include "ldemul.h" #include "ldctor.h" -#include "ldgram.h" - -static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); -static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **)); -static void gld${EMULATION_NAME}_after_open PARAMS ((void)); -static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); -static void gld${EMULATION_NAME}_read_file PARAMS ((const char *, boolean)); -static void gld${EMULATION_NAME}_free PARAMS ((PTR)); +#include <ldgram.h> + +#include "coff/internal.h" +#include "coff/xcoff.h" +#include "libcoff.h" +#include "libxcoff.h" + +static void gld${EMULATION_NAME}_before_parse + PARAMS ((void)); +static bfd_boolean gld${EMULATION_NAME}_parse_args + PARAMS ((int, char **)); +static void gld${EMULATION_NAME}_add_options + PARAMS ((int, char **, int, struct option **, int, struct option **)); +static bfd_boolean gld${EMULATION_NAME}_handle_option + PARAMS ((int)); +static void gld${EMULATION_NAME}_after_open + PARAMS ((void)); +static char *gld${EMULATION_NAME}_choose_target + PARAMS ((int, char **)); +static void gld${EMULATION_NAME}_before_allocation + PARAMS ((void)); +static void gld${EMULATION_NAME}_read_file + PARAMS ((const char *, bfd_boolean)); +static void gld${EMULATION_NAME}_free + PARAMS ((PTR)); static void gld${EMULATION_NAME}_find_relocs PARAMS ((lang_statement_union_type *)); -static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); -static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); +static void gld${EMULATION_NAME}_find_exp_assignment + PARAMS ((etree_type *)); +static char *gld${EMULATION_NAME}_get_script + PARAMS ((int *isfile)); +static bfd_boolean gld${EMULATION_NAME}_unrecognized_file + PARAMS ((lang_input_statement_type *)); +static void gld${EMULATION_NAME}_create_output_section_statements + PARAMS ((void)); +static void gld${EMULATION_NAME}_set_output_arch + PARAMS ((void)); +static int is_syscall + PARAMS ((char *, unsigned int *)); +static int change_symbol_mode + PARAMS ((char *)); /* The file alignment required for each section. */ static unsigned long file_align; @@ -97,55 +131,104 @@ struct export_symbol_list { struct export_symbol_list *next; const char *name; - boolean syscall; }; static struct export_symbol_list *export_symbols; +/* Maintains the 32 or 64 bit mode state of import file */ +static unsigned int symbol_mode = 0x04; + +/* Which symbol modes are valid */ +static unsigned int symbol_mode_mask = 0x0d; + +/* Whether this is a 64 bit link */ +static int is_64bit = 0; + +/* Which syscalls from import file are valid */ +static unsigned int syscall_mask = 0x77; + +/* fake file for -binitfini support */ +static lang_input_statement_type *initfini_file; + +/* Whether to do run time linking + -brtl enables, -bnortl and -bnortllib disable. */ +static int rtld; + +/* Explicit command line library path, -blibpath */ +static char *command_line_blibpath = NULL; + /* This routine is called before anything else is done. */ static void -gld${EMULATION_NAME}_before_parse() +gld${EMULATION_NAME}_before_parse () { -#ifndef TARGET_ /* I.e., if not generic. */ - ldfile_output_architecture = bfd_arch_${ARCH}; -#endif /* not TARGET_ */ - config.has_shared = true; + const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}"); + if (arch) + { + ldfile_output_architecture = arch->arch; + ldfile_output_machine = arch->mach; + ldfile_output_machine_name = arch->printable_name; + } + else + ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; + + config.has_shared = TRUE; + + /* The link_info.[init|fini]_functions are initialized in ld/lexsup.c. + Override them here so we can use the link_info.init_function as a + state flag that lets the backend know that -binitfini has been done. */ + + link_info.init_function = NULL; + link_info.fini_function = NULL; } /* Handle AIX specific options. */ -static int -gld${EMULATION_NAME}_parse_args (argc, argv) - int argc; - char **argv; +enum + { + OPTION_IGNORE = 300, + OPTION_AUTOIMP, + OPTION_ERNOTOK, + OPTION_EROK, + OPTION_EXPORT, + OPTION_IMPORT, + OPTION_INITFINI, + OPTION_LOADMAP, + OPTION_MAXDATA, + OPTION_MAXSTACK, + OPTION_MODTYPE, + OPTION_NOAUTOIMP, + OPTION_NOSTRCMPCT, + OPTION_PD, + OPTION_PT, + OPTION_STRCMPCT, + OPTION_UNIX, + OPTION_32, + OPTION_64, + OPTION_LIBPATH, + OPTION_NOLIBPATH, + }; + +static void +gld${EMULATION_NAME}_add_options (ns, shortopts, nl, longopts, nrl, really_longopts) + int ns; + char **shortopts; + int nl; + struct option **longopts; + int nrl ATTRIBUTE_UNUSED; + struct option **really_longopts ATTRIBUTE_UNUSED; { - int prevoptind = optind; - int prevopterr = opterr; - int indx; - int longind; - int optc; - long val; - char *end; - -#define OPTION_IGNORE (300) -#define OPTION_AUTOIMP (OPTION_IGNORE + 1) -#define OPTION_ERNOTOK (OPTION_AUTOIMP + 1) -#define OPTION_EROK (OPTION_ERNOTOK + 1) -#define OPTION_EXPORT (OPTION_EROK + 1) -#define OPTION_IMPORT (OPTION_EXPORT + 1) -#define OPTION_LOADMAP (OPTION_IMPORT + 1) -#define OPTION_MAXDATA (OPTION_LOADMAP + 1) -#define OPTION_MAXSTACK (OPTION_MAXDATA + 1) -#define OPTION_MODTYPE (OPTION_MAXSTACK + 1) -#define OPTION_NOAUTOIMP (OPTION_MODTYPE + 1) -#define OPTION_NOSTRCMPCT (OPTION_NOAUTOIMP + 1) -#define OPTION_PD (OPTION_NOSTRCMPCT + 1) -#define OPTION_PT (OPTION_PD + 1) -#define OPTION_STRCMPCT (OPTION_PT + 1) -#define OPTION_UNIX (OPTION_STRCMPCT + 1) - - static struct option longopts[] = { + static const char xtra_short[] = "D:H:KT:z"; + static const struct option xtra_long[] = { + /* -binitfini has special handling in the linker backend. The native linker + uses the arguemnts to generate a table of init and fini functions for + the executable. The important use for this option is to support aix 4.2+ + c++ constructors and destructors. This is tied into gcc via collect2.c. + + The function table is accessed by the runtime linker/loader by checking if + the first symbol in the loader symbol table is __rtinit. The gnu linker + generates this symbol and makes it the first loader symbol. */ + {"basis", no_argument, NULL, OPTION_IGNORE}, {"bautoimp", no_argument, NULL, OPTION_AUTOIMP}, {"bcomprld", no_argument, NULL, OPTION_IGNORE}, @@ -163,6 +246,7 @@ gld${EMULATION_NAME}_parse_args (argc, argv) {"bhalt", required_argument, NULL, OPTION_IGNORE}, {"bI", required_argument, NULL, OPTION_IMPORT}, {"bimport", required_argument, NULL, OPTION_IMPORT}, + {"binitfini", required_argument, NULL, OPTION_INITFINI}, {"bl", required_argument, NULL, OPTION_LOADMAP}, {"bloadmap", required_argument, NULL, OPTION_LOADMAP}, {"bmaxdata", required_argument, NULL, OPTION_MAXDATA}, @@ -180,12 +264,19 @@ gld${EMULATION_NAME}_parse_args (argc, argv) {"bpD", required_argument, NULL, OPTION_PD}, {"bpT", required_argument, NULL, OPTION_PT}, {"bro", no_argument, &textro, 1}, + {"brtl", no_argument, &rtld, 1}, + {"bnortl", no_argument, &rtld, 0}, + {"bnortllib", no_argument, &rtld, 0}, {"bS", required_argument, NULL, OPTION_MAXSTACK}, {"bso", no_argument, NULL, OPTION_AUTOIMP}, {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT}, {"btextro", no_argument, &textro, 1}, + {"b32", no_argument, NULL, OPTION_32}, + {"b64", no_argument, NULL, OPTION_64}, {"static", no_argument, NULL, OPTION_NOAUTOIMP}, {"unix", no_argument, NULL, OPTION_UNIX}, + {"blibpath", required_argument, NULL, OPTION_LIBPATH}, + {"bnolibpath", required_argument, NULL, OPTION_NOLIBPATH}, {NULL, no_argument, NULL, 0} }; @@ -198,12 +289,27 @@ gld${EMULATION_NAME}_parse_args (argc, argv) -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk, -bx, -bX, -bxref. */ + *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short)); + memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short)); + *longopts = (struct option *) + xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); + memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); +} + +static bfd_boolean +gld${EMULATION_NAME}_parse_args (argc, argv) + int argc; + char **argv; +{ + int indx; + /* If the current option starts with -b, change the first : to an =. The AIX linker uses : to separate the option from the argument; changing it to = lets us treat it as a getopt option. */ indx = optind; if (indx == 0) indx = 1; + if (indx < argc && strncmp (argv[indx], "-b", 2) == 0) { char *s; @@ -217,28 +323,27 @@ gld${EMULATION_NAME}_parse_args (argc, argv) } } } + return FALSE; +} - /* We add s and u so to the short options list so that -s and -u on - the command line do not match -static and -unix. */ - - opterr = 0; - optc = getopt_long_only (argc, argv, "-D:H:KT:zsu", longopts, &longind); - opterr = prevopterr; +static bfd_boolean +gld${EMULATION_NAME}_handle_option (optc) + int optc; +{ + bfd_signed_vma val; + const char *end; switch (optc) { - case 's': - case 'u': default: - optind = prevoptind; - return 0; + return FALSE; case 0: /* Long option which just sets a flag. */ break; case 'D': - val = strtol (optarg, &end, 0); + val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') einfo ("%P: warning: ignoring invalid -D number %s\n", optarg); else if (val != -1) @@ -246,9 +351,8 @@ gld${EMULATION_NAME}_parse_args (argc, argv) break; case 'H': - val = strtoul (optarg, &end, 0); - if (*end != '\0' - || (val & (val - 1)) != 0) + val = bfd_scan_vma (optarg, &end, 0); + if (*end != '\0' || (val & (val - 1)) != 0) einfo ("%P: warning: ignoring invalid -H number %s\n", optarg); else file_align = val; @@ -262,35 +366,69 @@ gld${EMULATION_NAME}_parse_args (argc, argv) case 'T': /* On AIX this is the same as GNU ld -Ttext. When we see -T - number, we assume the AIX option is intended. Otherwise, we - assume the usual GNU ld -T option is intended. We can't just - ignore the AIX option, because gcc passes it to the linker. */ - val = strtoul (optarg, &end, 0); + number, we assume the AIX option is intended. Otherwise, we + assume the usual GNU ld -T option is intended. We can't just + ignore the AIX option, because gcc passes it to the linker. */ + val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') - { - optind = prevoptind; - return 0; - } + return FALSE; lang_section_start (".text", exp_intop (val)); break; case OPTION_IGNORE: break; + case OPTION_INITFINI: + { + /* + * The aix linker init fini has the format : + * + * -binitfini:[ Initial][:Termination][:Priority] + * + * it allows the Termination and Priority to be optional. + * + * Since we support only one init/fini pair, we ignore the Priority. + * + * Define the special symbol __rtinit. + * + * strtok does not correctly handle the case of -binitfini::fini: so + * do it by hand + */ + char *t, *i, *f; + + i = t = optarg; + while (*t && ':' != *t) + t++; + if (*t) + *t++ = 0; + + if (0 != strlen (i)) + link_info.init_function = i; + + f = t; + while (*t && ':' != *t) + t++; + *t = 0; + + if (0 != strlen (f)) + link_info.fini_function = f; + } + break; + case OPTION_AUTOIMP: - link_info.static_link = false; + link_info.static_link = FALSE; break; case OPTION_ERNOTOK: - force_make_executable = false; + force_make_executable = FALSE; break; case OPTION_EROK: - force_make_executable = true; + force_make_executable = TRUE; break; case OPTION_EXPORT: - gld${EMULATION_NAME}_read_file (optarg, false); + gld${EMULATION_NAME}_read_file (optarg, FALSE); break; case OPTION_IMPORT: @@ -313,16 +451,15 @@ gld${EMULATION_NAME}_parse_args (argc, argv) break; case OPTION_MAXDATA: - val = strtoul (optarg, &end, 0); + val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') - einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n", - optarg); + einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n", optarg); else maxdata = val; break; case OPTION_MAXSTACK: - val = strtoul (optarg, &end, 0); + val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n", optarg); @@ -333,7 +470,7 @@ gld${EMULATION_NAME}_parse_args (argc, argv) case OPTION_MODTYPE: if (*optarg == 'S') { - link_info.shared = true; + link_info.shared = TRUE; ++optarg; } if (*optarg == '\0' || optarg[1] == '\0') @@ -343,19 +480,19 @@ gld${EMULATION_NAME}_parse_args (argc, argv) break; case OPTION_NOAUTOIMP: - link_info.static_link = true; + link_info.static_link = TRUE; break; case OPTION_NOSTRCMPCT: - link_info.traditional_format = true; + link_info.traditional_format = TRUE; break; case OPTION_PD: /* This sets the page that the .data section is supposed to - start on. The offset within the page should still be the - offset within the file, so we need to build an appropriate - expression. */ - val = strtoul (optarg, &end, 0); + start on. The offset within the page should still be the + offset within the file, so we need to build an appropriate + expression. */ + val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') einfo ("%P: warning: ignoring invalid -pD number %s\n", optarg); else @@ -369,16 +506,16 @@ gld${EMULATION_NAME}_parse_args (argc, argv) exp_intop (0xfff))); t = exp_binop ('&', exp_binop ('+', t, exp_intop (31)), - exp_intop (~ (bfd_vma) 31)); + exp_intop (~(bfd_vma) 31)); lang_section_start (".data", t); } break; case OPTION_PT: /* This set the page that the .text section is supposed to start - on. The offset within the page should still be the offset - within the file. */ - val = strtoul (optarg, &end, 0); + on. The offset within the page should still be the offset + within the file. */ + val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') einfo ("%P: warning: ignoring invalid -pT number %s\n", optarg); else @@ -390,39 +527,60 @@ gld${EMULATION_NAME}_parse_args (argc, argv) exp_nameop (SIZEOF_HEADERS, NULL)); t = exp_binop ('&', exp_binop ('+', t, exp_intop (31)), - exp_intop (~ (bfd_vma) 31)); + exp_intop (~(bfd_vma) 31)); lang_section_start (".text", t); } break; case OPTION_STRCMPCT: - link_info.traditional_format = false; + link_info.traditional_format = FALSE; break; case OPTION_UNIX: - unix_ld = true; + unix_ld = TRUE; + break; + + case OPTION_32: + is_64bit = 0; + syscall_mask = 0x77; + symbol_mode_mask = 0x0d; + break; + + case OPTION_64: + is_64bit = 1; + syscall_mask = 0xcc; + symbol_mode_mask = 0x0e; + break; + + case OPTION_LIBPATH: + command_line_blibpath = optarg; break; + + case OPTION_NOLIBPATH: + command_line_blibpath = NULL; + break; + } - return 1; + return TRUE; } /* This is called when an input file can not be recognized as a BFD object or an archive. If the file starts with #!, we must treat it as an import file. This is for AIX compatibility. */ -static boolean +static bfd_boolean gld${EMULATION_NAME}_unrecognized_file (entry) lang_input_statement_type *entry; { FILE *e; - boolean ret; + bfd_boolean ret; e = fopen (entry->filename, FOPEN_RT); if (e == NULL) - return false; + return FALSE; - ret = false; + ret = FALSE; if (getc (e) == '#' && getc (e) == '!') { @@ -437,8 +595,8 @@ gld${EMULATION_NAME}_unrecognized_file (entry) flpp = &(*flpp)->next; *flpp = n; - ret = true; - entry->loaded = true; + ret = TRUE; + entry->loaded = TRUE; } fclose (e); @@ -451,7 +609,7 @@ gld${EMULATION_NAME}_unrecognized_file (entry) static void gld${EMULATION_NAME}_after_open () { - boolean r; + bfd_boolean r; struct set_info *p; /* Call ldctor_build_sets, after pretending that this is a @@ -461,7 +619,7 @@ gld${EMULATION_NAME}_after_open () producing an XCOFF output file. */ r = link_info.relocateable; if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL) - link_info.relocateable = true; + link_info.relocateable = TRUE; ldctor_build_sets (); link_info.relocateable = r; @@ -485,7 +643,7 @@ gld${EMULATION_NAME}_after_open () } size = (p->count + 2) * 4; - if (! bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size)) + if (!bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size)) einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n"); } } @@ -499,20 +657,20 @@ gld${EMULATION_NAME}_before_allocation () struct filelist *fl; struct export_symbol_list *el; char *libpath; - asection *special_sections[6]; + asection *special_sections[XCOFF_NUMBER_OF_SPECIAL_SECTIONS]; int i; /* Handle the import and export files, if any. */ for (fl = import_files; fl != NULL; fl = fl->next) - gld${EMULATION_NAME}_read_file (fl->name, true); + gld${EMULATION_NAME}_read_file (fl->name, TRUE); for (el = export_symbols; el != NULL; el = el->next) { struct bfd_link_hash_entry *h; - h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false); + h = bfd_link_hash_lookup (link_info.hash, el->name, FALSE, FALSE, FALSE); if (h == NULL) einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n"); - if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, el->syscall)) + if (!bfd_xcoff_export_symbol (output_bfd, &link_info, h)) einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n"); } @@ -522,10 +680,13 @@ gld${EMULATION_NAME}_before_allocation () .loader relocs for them. */ lang_for_each_statement (gld${EMULATION_NAME}_find_relocs); - /* We need to build LIBPATH from the -L arguments. If any -rpath - arguments were used, though, we use -rpath instead, as a GNU - extension. */ - if (command_line.rpath != NULL) + /* Precedence of LIBPATH + -blibpath: native support always first + -rpath: gnu extension + -L build from command line -L's */ + if (command_line_blibpath != NULL) + libpath = command_line_blibpath; + else if (command_line.rpath != NULL) libpath = command_line.rpath; else if (search_head == NULL) libpath = (char *) ""; @@ -550,101 +711,108 @@ gld${EMULATION_NAME}_before_allocation () } /* Let the XCOFF backend set up the .loader section. */ - if (! bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath, - entry_symbol, file_align, - maxstack, maxdata, - gc && ! unix_ld ? true : false, - modtype, - textro ? true : false, - unix_ld, - special_sections)) + if (!bfd_xcoff_size_dynamic_sections + (output_bfd, &link_info, libpath, entry_symbol.name, file_align, + maxstack, maxdata, gc && !unix_ld ? TRUE : FALSE, + modtype, textro ? TRUE : FALSE, unix_ld, special_sections, + rtld ? TRUE : FALSE)) einfo ("%P%F: failed to set dynamic section sizes: %E\n"); /* Look through the special sections, and put them in the right place in the link ordering. This is especially magic. */ - for (i = 0; i < 6; i++) + for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++) { asection *sec; lang_output_section_statement_type *os; lang_statement_union_type **pls; lang_input_section_type *is; const char *oname; - boolean start; + bfd_boolean start; sec = special_sections[i]; if (sec == NULL) continue; /* Remove this section from the list of the output section. - This assumes we know what the script looks like. */ + This assumes we know what the script looks like. */ is = NULL; os = lang_output_section_find (sec->output_section->name); if (os == NULL) einfo ("%P%F: can't find output section %s\n", sec->output_section->name); - for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->next) + + for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->header.next) { if ((*pls)->header.type == lang_input_section_enum && (*pls)->input_section.section == sec) { - is = (lang_input_section_type *) *pls; - *pls = (*pls)->next; + is = (lang_input_section_type *) * pls; + *pls = (*pls)->header.next; break; } + if ((*pls)->header.type == lang_wild_statement_enum) { lang_statement_union_type **pwls; for (pwls = &(*pls)->wild_statement.children.head; - *pwls != NULL; - pwls = &(*pwls)->next) + *pwls != NULL; pwls = &(*pwls)->header.next) { + if ((*pwls)->header.type == lang_input_section_enum && (*pwls)->input_section.section == sec) { - is = (lang_input_section_type *) *pwls; - *pwls = (*pwls)->next; + is = (lang_input_section_type *) * pwls; + *pwls = (*pwls)->header.next; break; } } + if (is != NULL) break; } - } + } if (is == NULL) - einfo ("%P%F: can't find %s in output section\n", - bfd_get_section_name (sec->owner, sec)); + { + einfo ("%P%F: can't find %s in output section\n", + bfd_get_section_name (sec->owner, sec)); + } /* Now figure out where the section should go. */ switch (i) { - default: /* to avoid warnings */ - case 0: + + default: /* to avoid warnings */ + case XCOFF_SPECIAL_SECTION_TEXT: /* _text */ oname = ".text"; - start = true; + start = TRUE; break; - case 1: + + case XCOFF_SPECIAL_SECTION_ETEXT: /* _etext */ oname = ".text"; - start = false; + start = FALSE; break; - case 2: + + case XCOFF_SPECIAL_SECTION_DATA: /* _data */ oname = ".data"; - start = true; + start = TRUE; break; - case 3: + + case XCOFF_SPECIAL_SECTION_EDATA: /* _edata */ oname = ".data"; - start = false; + start = FALSE; break; - case 4: - case 5: + + case XCOFF_SPECIAL_SECTION_END: + case XCOFF_SPECIAL_SECTION_END2: /* _end and end */ oname = ".bss"; - start = false; + start = FALSE; break; } @@ -665,20 +833,140 @@ gld${EMULATION_NAME}_before_allocation () } } +static char * +gld${EMULATION_NAME}_choose_target (argc, argv) + int argc; + char **argv; +{ + int i, j, jmax; + static char *from_outside; + static char *from_inside; + static char *argv_to_target[][2] = { + {NULL, "${OUTPUT_FORMAT}"}, + {"-b32", "${OUTPUT_FORMAT_32BIT}"}, + {"-b64", "${OUTPUT_FORMAT_64BIT}"}, + }; + + jmax = 3; + + from_outside = getenv (TARGET_ENVIRON); + if (from_outside != (char *) NULL) + return from_outside; + + /* Set to default. */ + from_inside = argv_to_target[0][1]; + for (i = 1; i < argc; i++) + { + for (j = 1; j < jmax; j++) + { + if (0 == strcmp (argv[i], argv_to_target[j][0])) + from_inside = argv_to_target[j][1]; + } + } + + return from_inside; +} + +/* Returns + 1 : state changed + 0 : no change */ +static int +change_symbol_mode (input) + char *input; +{ + char *symbol_mode_string[] = { + "# 32", /* 0x01 */ + "# 64", /* 0x02 */ + "# no32", /* 0x04 */ + "# no64", /* 0x08 */ + NULL, + }; + + unsigned int bit; + char *string; + + for (bit = 0;; bit++) + { + string = symbol_mode_string[bit]; + if (string == NULL) + return 0; + + if (0 == strcmp (input, string)) + { + symbol_mode = (1 << bit); + return 1; + } + } + /* should not be here */ + return 0; +} + +/* Returns + 1 : yes + 0 : ignore + -1 : error, try something else */ +static int +is_syscall (input, flag) + char *input; + unsigned int *flag; +{ + unsigned int bit; + char *string; + + struct sc { + char *syscall_string; + unsigned int flag; + } s [] = { + { "svc" /* 0x01 */, XCOFF_SYSCALL32 }, + { "svc32" /* 0x02 */, XCOFF_SYSCALL32 }, + { "svc3264" /* 0x04 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 }, + { "svc64" /* 0x08 */, XCOFF_SYSCALL64 }, + { "syscall" /* 0x10 */, XCOFF_SYSCALL32 }, + { "syscall32" /* 0x20 */, XCOFF_SYSCALL32 }, + { "syscall3264" /* 0x40 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 }, + { "syscall64" /* 0x80 */, XCOFF_SYSCALL64 }, + { NULL, 0 }, + }; + + *flag = 0; + + for (bit = 0;; bit++) + { + string = s[bit].syscall_string; + if (string == NULL) + return -1; + + if (0 == strcmp (input, string)) + { + if (1 << bit & syscall_mask) + { + *flag = s[bit].flag; + return 1; + } + else + { + return 0; + } + } + } + /* should not be here */ + return -1; +} + /* Read an import or export file. For an import file, this is called by the before_allocation emulation routine. For an export file, - this is called by the parse_args emulation routine. */ + this is called by the handle_option emulation routine. */ static void gld${EMULATION_NAME}_read_file (filename, import) const char *filename; - boolean import; + bfd_boolean import; { struct obstack *o; FILE *f; int lineno; int c; - boolean keep; + bfd_boolean keep; const char *imppath; const char *impfile; const char *impmember; @@ -693,18 +981,26 @@ gld${EMULATION_NAME}_read_file (filename, import) einfo ("%F%s: %E\n", filename); } - keep = false; + keep = FALSE; imppath = NULL; impfile = NULL; impmember = NULL; lineno = 0; + + /* Default to 32 and 64 bit mode + symbols at top of /lib/syscalls.exp do not have a mode modifier and they + are not repeated, assume 64 bit routines also want to use them. + See the routine change_symbol_mode for more information. */ + + symbol_mode = 0x04; + while ((c = getc (f)) != EOF) { char *s; char *symname; - boolean syscall; + unsigned int syscall_flag = 0; bfd_vma address; struct bfd_link_hash_entry *h; @@ -718,12 +1014,13 @@ gld${EMULATION_NAME}_read_file (filename, import) ++lineno; s = (char *) obstack_base (o); - while (isspace ((unsigned char) *s)) + while (ISSPACE (*s)) ++s; if (*s == '\0' || *s == '*' + || change_symbol_mode (s) || (*s == '#' && s[1] == ' ') - || (! import && *s == '#' && s[1] == '!')) + || (!import && *s == '#' && s[1] == '!')) { obstack_free (o, obstack_base (o)); continue; @@ -732,7 +1029,7 @@ gld${EMULATION_NAME}_read_file (filename, import) if (*s == '#' && s[1] == '!') { s += 2; - while (isspace ((unsigned char) *s)) + while (ISSPACE (*s)) ++s; if (*s == '\0') { @@ -750,10 +1047,10 @@ gld${EMULATION_NAME}_read_file (filename, import) char *file; (void) obstack_finish (o); - keep = true; + keep = TRUE; imppath = s; file = NULL; - while (! isspace ((unsigned char) *s) && *s != '(' && *s != '\0') + while (!ISSPACE (*s) && *s != '(' && *s != '\0') { if (*s == '/') file = s + 1; @@ -773,7 +1070,7 @@ gld${EMULATION_NAME}_read_file (filename, import) } cs = *s; *s = '\0'; - while (isspace ((unsigned char) cs)) + while (ISSPACE (cs)) { ++s; cs = *s; @@ -802,84 +1099,88 @@ gld${EMULATION_NAME}_read_file (filename, import) continue; } - /* This is a symbol to be imported or exported. */ - symname = s; - syscall = false; - address = (bfd_vma) -1; - - while (! isspace ((unsigned char) *s) && *s != '\0') - ++s; - if (*s != '\0') + if (symbol_mode & symbol_mode_mask) { - char *se; + /* This is a symbol to be imported or exported. */ + symname = s; + syscall_flag = 0; + address = (bfd_vma) -1; - *s++ = '\0'; - - while (isspace ((unsigned char) *s)) + while (!ISSPACE (*s) && *s != '\0') ++s; - - se = s; - while (! isspace ((unsigned char) *se) && *se != '\0') - ++se; - if (*se != '\0') + if (*s != '\0') { - *se++ = '\0'; - while (isspace ((unsigned char) *se)) + char *se; + + *s++ = '\0'; + + while (ISSPACE (*s)) + ++s; + + se = s; + while (!ISSPACE (*se) && *se != '\0') ++se; if (*se != '\0') - einfo ("%s%d: warning: syntax error in import/export file\n", - filename, lineno); - } + { + *se++ = '\0'; + while (ISSPACE (*se)) + ++se; + if (*se != '\0') + einfo ("%s%d: warning: syntax error in import/export file\n", + filename, lineno); + } - if (s == se) - { - /* There was no address after all. */ - } - else if (strcasecmp (s, "svc") == 0 - || strcasecmp (s, "syscall") == 0) - syscall = true; - else - { - char *end; + if (s != se) + { + int status; + const char *end; + + status = is_syscall (s, &syscall_flag); - address = strtoul (s, &end, 0); - if (*end != '\0') - einfo ("%s:%d: warning: syntax error in import/export file\n", - filename, lineno); + if (0 > status) + { + /* not a system call, check for address */ + address = bfd_scan_vma (s, &end, 0); + if (*end != '\0') + { + einfo ("%s:%d: warning: syntax error in import/export file\n", + filename, lineno); + + } + } + } } - } - if (! import) - { - struct export_symbol_list *n; - - ldlang_add_undef (symname); - n = ((struct export_symbol_list *) - xmalloc (sizeof (struct export_symbol_list))); - n->next = export_symbols; - n->name = xstrdup (symname); - n->syscall = syscall; - export_symbols = n; - } - else - { - h = bfd_link_hash_lookup (link_info.hash, symname, false, false, - true); - if (h == NULL || h->type == bfd_link_hash_new) + if (!import) { - /* We can just ignore attempts to import an unreferenced - symbol. */ + struct export_symbol_list *n; + + ldlang_add_undef (symname); + n = ((struct export_symbol_list *) + xmalloc (sizeof (struct export_symbol_list))); + n->next = export_symbols; + n->name = xstrdup (symname); + export_symbols = n; } else { - if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h, - address, imppath, impfile, - impmember)) - einfo ("%X%s:%d: failed to import symbol %s: %E\n", - filename, lineno, symname); + h = bfd_link_hash_lookup (link_info.hash, symname, FALSE, FALSE, + TRUE); + if (h == NULL || h->type == bfd_link_hash_new) + { + /* We can just ignore attempts to import an unreferenced + symbol. */ + } + else + { + if (!bfd_xcoff_import_symbol (output_bfd, &link_info, h, + address, imppath, impfile, + impmember, syscall_flag)) + einfo ("%X%s:%d: failed to import symbol %s: %E\n", + filename, lineno, symname); + } } } - obstack_free (o, obstack_base (o)); } @@ -890,7 +1191,7 @@ gld${EMULATION_NAME}_read_file (filename, import) obstack_free (o, obstack_base (o)); } - if (! keep) + if (!keep) { obstack_free (o, NULL); free (o); @@ -921,7 +1222,7 @@ gld${EMULATION_NAME}_find_relocs (s) rs = &s->reloc_statement; if (rs->name == NULL) einfo ("%F%P: only relocations against symbols are permitted\n"); - if (! bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name)) + if (!bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name)) einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n"); } @@ -941,15 +1242,15 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) { case etree_provide: h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, - false, false, false); + FALSE, FALSE, FALSE); if (h == NULL) break; /* Fall through. */ case etree_assign: if (strcmp (exp->assign.dst, ".") != 0) { - if (! bfd_xcoff_record_link_assignment (output_bfd, &link_info, - exp->assign.dst)) + if (!bfd_xcoff_record_link_assignment (output_bfd, &link_info, + exp->assign.dst)) einfo ("%P%F: failed to record assignment to %s: %E\n", exp->assign.dst); } @@ -977,7 +1278,7 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) } static char * -gld${EMULATION_NAME}_get_script(isfile) +gld${EMULATION_NAME}_get_script (isfile) int *isfile; EOF @@ -986,36 +1287,36 @@ then # Scripts compiled in. # sed commands to quote an ld script as a C string. -sc="-f stringify.sed" +sc="-f ${srcdir}/emultempl/ostring.sed" cat >>e${EMULATION_NAME}.c <<EOF -{ +{ *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. cat >>e${EMULATION_NAME}.c <<EOF -{ +{ *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; @@ -1030,27 +1331,82 @@ fi cat >>e${EMULATION_NAME}.c <<EOF -struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +static void +gld${EMULATION_NAME}_create_output_section_statements () +{ + /* __rtinit */ + if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour) + && (link_info.init_function != NULL + || link_info.fini_function != NULL + || rtld)) + { + initfini_file = lang_add_input_file ("initfini", + lang_input_file_is_file_enum, + NULL); + + initfini_file->the_bfd = bfd_create ("initfini", output_bfd); + if (initfini_file->the_bfd == NULL + || ! bfd_set_arch_mach (initfini_file->the_bfd, + bfd_get_arch (output_bfd), + bfd_get_mach (output_bfd))) + { + einfo ("%X%P: can not create BFD %E\n"); + return; + } + + /* Call backend to fill in the rest */ + if (! bfd_xcoff_link_generate_rtinit (initfini_file->the_bfd, + link_info.init_function, + link_info.fini_function, + rtld)) + { + einfo ("%X%P: can not create BFD %E\n"); + return; + } + + /* __rtld defined in /lib/librtl.a */ + if (rtld) + lang_add_input_file ("rtl", lang_input_file_is_l_enum, NULL); + } +} + +static void +gld${EMULATION_NAME}_set_output_arch () { + bfd_set_arch_mach (output_bfd, + bfd_xcoff_architecture (output_bfd), + bfd_xcoff_machine (output_bfd)); + + ldfile_output_architecture = bfd_get_arch (output_bfd); + ldfile_output_machine = bfd_get_mach (output_bfd); + ldfile_output_machine_name = bfd_printable_name (output_bfd); +} + +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { gld${EMULATION_NAME}_before_parse, syslib_default, hll_default, after_parse_default, gld${EMULATION_NAME}_after_open, after_allocation_default, - set_output_arch_default, - ldemul_default_target, + gld${EMULATION_NAME}_set_output_arch, + gld${EMULATION_NAME}_choose_target, gld${EMULATION_NAME}_before_allocation, gld${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", - 0, /* finish */ - 0, /* create_output_section_statements */ - 0, /* open_dynamic_archive */ - 0, /* place_orphan */ - 0, /* set_symbols */ + 0, /* finish */ + gld${EMULATION_NAME}_create_output_section_statements, + 0, /* open_dynamic_archive */ + 0, /* place_orphan */ + 0, /* set_symbols */ gld${EMULATION_NAME}_parse_args, + gld${EMULATION_NAME}_add_options, + gld${EMULATION_NAME}_handle_option, gld${EMULATION_NAME}_unrecognized_file, - NULL /* find_potential_libraries */ + NULL, /* list_options */ + NULL, /* recognized_file */ + NULL, /* find potential_libraries */ + NULL /* new_vers_pattern */ }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/elf32.em b/gnu/usr.bin/binutils/ld/emultempl/elf32.em index 15965570155..a67a81baf3e 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/elf32.em +++ b/gnu/usr.bin/binutils/ld/emultempl/elf32.em @@ -3,12 +3,17 @@ # This file is now misnamed, because it supports both 32 bit and 64 bit # ELF emulations. test -z "${ELFSIZE}" && ELFSIZE=32 +if [ -z "$MACHINE" ]; then + OUTPUT_ARCH=${ARCH} +else + OUTPUT_ARCH=${ARCH}:${MACHINE} +fi cat >e${EMULATION_NAME}.c <<EOF /* This file is is generated by a shell script. DO NOT EDIT! */ /* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME} - Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003 Free Software Foundation, Inc. Written by Steve Chamberlain <sac@cygnus.com> ELF support by Ian Lance Taylor <ian@cygnus.com> @@ -33,8 +38,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" #include "libiberty.h" - -#include <ctype.h> +#include "safe-ctype.h" +#include "getopt.h" #include "bfdlink.h" @@ -45,30 +50,41 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ldlang.h" #include "ldfile.h" #include "ldemul.h" -#include "ldgram.h" +#include <ldgram.h> #include "elf/common.h" -static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); +static void gld${EMULATION_NAME}_before_parse + PARAMS ((void)); static void gld${EMULATION_NAME}_vercheck PARAMS ((lang_input_statement_type *)); static void gld${EMULATION_NAME}_stat_needed PARAMS ((lang_input_statement_type *)); -static boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, int)); -static boolean gld${EMULATION_NAME}_search_needed +static bfd_boolean gld${EMULATION_NAME}_try_needed + PARAMS ((const char *, int)); +static bfd_boolean gld${EMULATION_NAME}_search_needed PARAMS ((const char *, const char *, int)); static void gld${EMULATION_NAME}_check_needed PARAMS ((lang_input_statement_type *)); -static void gld${EMULATION_NAME}_after_open PARAMS ((void)); -static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); +static void gld${EMULATION_NAME}_after_open + PARAMS ((void)); +static void gld${EMULATION_NAME}_find_exp_assignment + PARAMS ((etree_type *)); static void gld${EMULATION_NAME}_find_statement_assignment PARAMS ((lang_statement_union_type *)); -static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); -static boolean gld${EMULATION_NAME}_open_dynamic_archive +static void gld${EMULATION_NAME}_before_allocation + PARAMS ((void)); +static bfd_boolean gld${EMULATION_NAME}_open_dynamic_archive PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); -static lang_output_section_statement_type *output_rel_find PARAMS ((void)); -static boolean gld${EMULATION_NAME}_place_orphan +static lang_output_section_statement_type *output_rel_find + PARAMS ((asection *)); +static asection *output_prev_sec_find + PARAMS ((lang_output_section_statement_type *)); +static bfd_boolean gld${EMULATION_NAME}_place_orphan PARAMS ((lang_input_statement_type *, asection *)); -static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); +static void gld${EMULATION_NAME}_finish + PARAMS ((void)); +static char *gld${EMULATION_NAME}_get_script + PARAMS ((int *isfile)); EOF case ${target} in @@ -152,13 +168,13 @@ gld${EMULATION_NAME}_search_dir (dirname, filename) if (entry->d_name[6 + len] == '\0') ; else if (entry->d_name[6 + len] == '.' - && isdigit ((unsigned char) entry->d_name[7 + len])) + && ISDIGIT ((unsigned char) entry->d_name[7 + len])) ; else continue; for (s = entry->d_name + 6 + len; *s != '\0'; s++) - if (*s != '.' && ! isdigit ((unsigned char) *s)) + if (*s != '.' && ! ISDIGIT ((unsigned char) *s)) break; if (*s != '\0') continue; @@ -243,9 +259,17 @@ cat >>e${EMULATION_NAME}.c <<EOF static void gld${EMULATION_NAME}_before_parse () { - ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; - config.dynamic_link = ${DYNAMIC_LINK-true}; - config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`; + const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}"); + if (arch) + { + ldfile_output_architecture = arch->arch; + ldfile_output_machine = arch->mach; + ldfile_output_machine_name = arch->printable_name; + } + else + ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; + config.dynamic_link = ${DYNAMIC_LINK-TRUE}; + config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; } EOF @@ -258,9 +282,9 @@ cat >>e${EMULATION_NAME}.c <<EOF static struct bfd_link_needed_list *global_needed; static struct stat global_stat; -static boolean global_found; +static bfd_boolean global_found; static struct bfd_link_needed_list *global_vercheck_needed; -static boolean global_vercheck_failed; +static bfd_boolean global_vercheck_failed; /* On Linux, it's possible to have different versions of the same @@ -295,7 +319,7 @@ gld${EMULATION_NAME}_vercheck (s) soname = bfd_elf_get_dt_soname (s->the_bfd); if (soname == NULL) - soname = basename (bfd_get_filename (s->the_bfd)); + soname = lbasename (bfd_get_filename (s->the_bfd)); for (l = global_vercheck_needed; l != NULL; l = l->next) { @@ -323,7 +347,7 @@ gld${EMULATION_NAME}_vercheck (s) FOO.SO.VER2, and VER1 and VER2 are different. This appears to be a version mismatch, so we tell the caller to try a different version of this library. */ - global_vercheck_failed = true; + global_vercheck_failed = TRUE; return; } } @@ -355,7 +379,7 @@ gld${EMULATION_NAME}_stat_needed (s) if (st.st_dev == global_stat.st_dev && st.st_ino == global_stat.st_ino) { - global_found = true; + global_found = TRUE; return; } @@ -377,10 +401,9 @@ gld${EMULATION_NAME}_stat_needed (s) soname = bfd_elf_get_dt_soname (s->the_bfd); if (soname == NULL) - soname = basename (s->filename); + soname = lbasename (s->filename); - if (strncmp (soname, global_needed->name, - suffix - global_needed->name) == 0) + if (strncmp (soname, global_needed->name, suffix - global_needed->name) == 0) einfo ("%P: warning: %s, needed by %B, may conflict with %s\n", global_needed->name, global_needed->by, soname); } @@ -390,7 +413,7 @@ gld${EMULATION_NAME}_stat_needed (s) named by a DT_NEEDED entry. The FORCE parameter indicates whether to skip the check for a conflicting version. */ -static boolean +static bfd_boolean gld${EMULATION_NAME}_try_needed (name, force) const char *name; int force; @@ -400,16 +423,23 @@ gld${EMULATION_NAME}_try_needed (name, force) abfd = bfd_openr (name, bfd_get_target (output_bfd)); if (abfd == NULL) - return false; + return FALSE; if (! bfd_check_format (abfd, bfd_object)) { - (void) bfd_close (abfd); - return false; + bfd_close (abfd); + return FALSE; } if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) { - (void) bfd_close (abfd); - return false; + bfd_close (abfd); + return FALSE; + } + + /* For DT_NEEDED, they have to match. */ + if (abfd->xvec != output_bfd->xvec) + { + bfd_close (abfd); + return FALSE; } /* Check whether this object would include any conflicting library @@ -427,14 +457,14 @@ gld${EMULATION_NAME}_try_needed (name, force) if (needed != NULL) { global_vercheck_needed = needed; - global_vercheck_failed = false; + global_vercheck_failed = FALSE; lang_for_each_input_file (gld${EMULATION_NAME}_vercheck); if (global_vercheck_failed) { - (void) bfd_close (abfd); - /* Return false to force the caller to move on to try + bfd_close (abfd); + /* Return FALSE to force the caller to move on to try another file on the search path. */ - return false; + return FALSE; } /* But wait! It gets much worse. On Linux, if a shared @@ -456,8 +486,8 @@ case ${target} in break; if (l == NULL) { - (void) bfd_close (abfd); - return false; + bfd_close (abfd); + return FALSE; } } @@ -482,19 +512,19 @@ cat >>e${EMULATION_NAME}.c <<EOF einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd); /* First strip off everything before the last '/'. */ - soname = xstrdup (basename (abfd->filename)); + soname = xstrdup (lbasename (abfd->filename)); if (trace_file_tries) info_msg (_("found %s at %s\n"), soname, name); - global_found = false; + global_found = FALSE; lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed); if (global_found) { - /* Return true to indicate that we found the file, even though + /* Return TRUE to indicate that we found the file, even though we aren't going to do anything with it. */ - free (soname); - return true; + free(soname); + return TRUE; } /* Tell the ELF backend that we don't want the output file to have a @@ -510,13 +540,13 @@ cat >>e${EMULATION_NAME}.c <<EOF if (! bfd_link_add_symbols (abfd, &link_info)) einfo ("%F%B: could not read symbols: %E\n", abfd); - return true; + return TRUE; } /* Search for a needed file in a path. */ -static boolean +static bfd_boolean gld${EMULATION_NAME}_search_needed (path, name, force) const char *path; const char *name; @@ -529,7 +559,7 @@ gld${EMULATION_NAME}_search_needed (path, name, force) return gld${EMULATION_NAME}_try_needed (name, force); if (path == NULL || *path == '\0') - return false; + return FALSE; len = strlen (name); while (1) { @@ -551,7 +581,7 @@ gld${EMULATION_NAME}_search_needed (path, name, force) strcpy (sset, name); if (gld${EMULATION_NAME}_try_needed (filename, force)) - return true; + return TRUE; free (filename); @@ -560,37 +590,80 @@ gld${EMULATION_NAME}_search_needed (path, name, force) path = s + 1; } - return false; + return FALSE; } EOF -if [ "x${host}" = "x${target}" ] ; then - case " ${EMULATION_LIBPATH} " in - *" ${EMULATION_NAME} "*) - case ${target} in - *-*-linux-gnu*) - cat >>e${EMULATION_NAME}.c <<EOF +if [ "x${USE_LIBPATH}" = xyes ] ; then + cat >>e${EMULATION_NAME}.c <<EOF + +/* Add the sysroot to every entry in a colon-separated path. */ +static char * gld${EMULATION_NAME}_add_sysroot PARAMS ((const char *)); + +static char * +gld${EMULATION_NAME}_add_sysroot (path) + const char *path; +{ + int len, colons, i; + char *ret, *p; + + len = strlen (path); + colons = 0; + i = 0; + while (path[i]) + if (path[i++] == ':') + colons++; + + if (path[i]) + colons++; + + len = len + (colons + 1) * strlen (ld_sysroot); + ret = xmalloc (len + 1); + strcpy (ret, ld_sysroot); + p = ret + strlen (ret); + i = 0; + while (path[i]) + if (path[i] == ':') + { + *p++ = path[i++]; + strcpy (p, ld_sysroot); + p = p + strlen (p); + } + else + *p++ = path[i++]; + + *p = 0; + return ret; +} + +EOF + case ${target} in + *-*-linux-gnu*) + cat >>e${EMULATION_NAME}.c <<EOF /* For a native linker, check the file /etc/ld.so.conf for directories in which we may find shared libraries. /etc/ld.so.conf is really only meaningful on Linux. */ -static boolean gld${EMULATION_NAME}_check_ld_so_conf +static bfd_boolean gld${EMULATION_NAME}_check_ld_so_conf PARAMS ((const char *, int)); -static boolean +static bfd_boolean gld${EMULATION_NAME}_check_ld_so_conf (name, force) const char *name; int force; { - static boolean initialized; + static bfd_boolean initialized; static char *ld_so_conf; if (! initialized) { FILE *f; + char *tmppath; - f = fopen ("/etc/ld.so.conf", FOPEN_RT); + tmppath = concat (ld_sysroot, "/etc/ld.so.conf", NULL); + f = fopen (tmppath, FOPEN_RT); + free (tmppath); if (f != NULL) { char *b; @@ -640,22 +713,28 @@ gld${EMULATION_NAME}_check_ld_so_conf (name, force) fclose (f); + if (b) + { + char *d = gld${EMULATION_NAME}_add_sysroot (b); + free (b); + b = d; + } + ld_so_conf = b; } - initialized = true; + initialized = TRUE; } if (ld_so_conf == NULL) - return false; + return FALSE; return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force); } EOF - # Linux - ;; - esac + # Linux + ;; esac fi cat >>e${EMULATION_NAME}.c <<EOF @@ -675,7 +754,7 @@ gld${EMULATION_NAME}_check_needed (s) if (strcmp (s->filename, global_needed->name) == 0) { - global_found = true; + global_found = TRUE; return; } @@ -685,7 +764,7 @@ gld${EMULATION_NAME}_check_needed (s) if (f != NULL && strcmp (f + 1, global_needed->name) == 0) { - global_found = true; + global_found = TRUE; return; } } @@ -699,7 +778,7 @@ gld${EMULATION_NAME}_check_needed (s) if (soname != NULL && strcmp (soname, global_needed->name) == 0) { - global_found = true; + global_found = TRUE; return; } } @@ -745,7 +824,7 @@ gld${EMULATION_NAME}_after_open () /* See if this file was included in the link explicitly. */ global_needed = l; - global_found = false; + global_found = FALSE; lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); if (global_found) continue; @@ -769,16 +848,12 @@ gld${EMULATION_NAME}_after_open () size_t len; search_dirs_type *search; EOF -if [ "x${host}" = "x${target}" ] ; then - case " ${EMULATION_LIBPATH} " in - *" ${EMULATION_NAME} "*) +if [ "x${USE_LIBPATH}" = xyes ] ; then cat >>e${EMULATION_NAME}.c <<EOF char *lib_path; struct bfd_link_needed_list *rp; int found; EOF - ;; - esac fi cat >>e${EMULATION_NAME}.c <<EOF @@ -786,13 +861,15 @@ cat >>e${EMULATION_NAME}.c <<EOF l->name, force)) break; EOF -if [ "x${host}" = "x${target}" ] ; then - case " ${EMULATION_LIBPATH} " in - *" ${EMULATION_NAME} "*) +if [ "x${USE_LIBPATH}" = xyes ] ; then cat >>e${EMULATION_NAME}.c <<EOF if (gld${EMULATION_NAME}_search_needed (command_line.rpath, l->name, force)) break; +EOF +fi +if [ "x${NATIVE}" = xyes ] ; then +cat >>e${EMULATION_NAME}.c <<EOF if (getenv("LD_RUN_PATH") != NULL && command_line.rpath_link == NULL && command_line.rpath == NULL) @@ -827,22 +904,25 @@ cat >>e${EMULATION_NAME}.c <<EOF lib_path = getenv ("LD_LIBRARY_PATH"); if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force)) break; - +EOF +fi +if [ "x${USE_LIBPATH}" = xyes ] ; then +cat >>e${EMULATION_NAME}.c <<EOF found = 0; rp = bfd_elf_get_runpath_list (output_bfd, &link_info); for (; !found && rp != NULL; rp = rp->next) { + char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name); found = (rp->by == l->by - && gld${EMULATION_NAME}_search_needed (rp->name, + && gld${EMULATION_NAME}_search_needed (tmpname, l->name, force)); + free (tmpname); } if (found) break; EOF - ;; - esac fi cat >>e${EMULATION_NAME}.c <<EOF len = strlen (l->name); @@ -861,19 +941,15 @@ cat >>e${EMULATION_NAME}.c <<EOF if (search != NULL) break; EOF -if [ "x${host}" = "x${target}" ] ; then - case " ${EMULATION_LIBPATH} " in - *" ${EMULATION_NAME} "*) - case ${target} in - *-*-linux-gnu*) - cat >>e${EMULATION_NAME}.c <<EOF +if [ "x${USE_LIBPATH}" = xyes ] ; then + case ${target} in + *-*-linux-gnu*) + cat >>e${EMULATION_NAME}.c <<EOF if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force)) break; EOF - # Linux - ;; - esac - ;; + # Linux + ;; esac fi cat >>e${EMULATION_NAME}.c <<EOF @@ -904,7 +980,7 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) { case etree_provide: h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, - false, false, false); + FALSE, FALSE, FALSE); if (h == NULL) break; @@ -922,7 +998,7 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) { if (! (bfd_elf${ELFSIZE}_record_link_assignment (output_bfd, &link_info, exp->assign.dst, - exp->type.node_class == etree_provide ? true : false))) + exp->type.node_class == etree_provide ? TRUE : FALSE))) einfo ("%P%F: failed to record assignment to %s: %E\n", exp->assign.dst); } @@ -966,6 +1042,18 @@ gld${EMULATION_NAME}_find_statement_assignment (s) EOF if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then + if test x"${ELF_INTERPRETER_NAME+set}" = xset; then + ELF_INTERPRETER_SET_DEFAULT=" + if (sinterp != NULL) + { + sinterp->contents = ${ELF_INTERPRETER_NAME}; + sinterp->_raw_size = strlen (sinterp->contents) + 1; + } + +" + else + ELF_INTERPRETER_SET_DEFAULT= + fi cat >>e${EMULATION_NAME}.c <<EOF /* This is called after the sections have been attached to output @@ -989,11 +1077,11 @@ gld${EMULATION_NAME}_before_allocation () rpath = (const char *) getenv ("LD_RUN_PATH"); if (! (bfd_elf${ELFSIZE}_size_dynamic_sections (output_bfd, command_line.soname, rpath, - command_line.export_dynamic, command_line.filter_shlib, + command_line.filter_shlib, (const char * const *) command_line.auxiliary_filters, &link_info, &sinterp, lang_elf_version_info))) einfo ("%P%F: failed to set dynamic section sizes: %E\n"); - +${ELF_INTERPRETER_SET_DEFAULT} /* Let the user override the dynamic linker we are using. */ if (command_line.interpreter != NULL && sinterp != NULL) @@ -1013,7 +1101,7 @@ gld${EMULATION_NAME}_before_allocation () asection *s; bfd_size_type sz; char *msg; - boolean ret; + bfd_boolean ret; if (is->just_syms_flag) continue; @@ -1052,7 +1140,7 @@ cat >>e${EMULATION_NAME}.c <<EOF dynamic libraries have an extension of .so (or .sl on oddball systems like hpux). */ -static boolean +static bfd_boolean gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) const char *arch; search_dirs_type *search; @@ -1062,7 +1150,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) char *string; if (! entry->is_archive) - return false; + return FALSE; filename = entry->filename; EOF @@ -1071,7 +1159,7 @@ case ${target} in cat >>e${EMULATION_NAME}.c <<EOF string = gld${EMULATION_NAME}_search_dir(search->name, filename); if (string == NULL) - return false; + return FALSE; EOF ;; *) @@ -1104,7 +1192,7 @@ cat >>e${EMULATION_NAME}.c <<EOF if (! ldfile_try_open_bfd (string, entry)) { free (string); - return false; + return FALSE; } entry->filename = string; @@ -1130,44 +1218,89 @@ cat >>e${EMULATION_NAME}.c <<EOF /* Rather than duplicating the logic above. Just use the filename we recorded earlier. */ - filename = xstrdup (basename (entry->filename)); + filename = lbasename (entry->filename); bfd_elf_set_dt_needed_name (entry->the_bfd, filename); } - return true; + return TRUE; } EOF fi + +if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then cat >>e${EMULATION_NAME}.c <<EOF /* A variant of lang_output_section_find. Used by place_orphan. */ static lang_output_section_statement_type * -output_rel_find () +output_rel_find (sec) + asection *sec; { lang_statement_union_type *u; lang_output_section_statement_type *lookup; + lang_output_section_statement_type *last = NULL; + lang_output_section_statement_type *last_rel = NULL; + lang_output_section_statement_type *last_rel_alloc = NULL; + int rela = sec->name[4] == 'a'; - for (u = lang_output_section_statement.head; - u != (lang_statement_union_type *) NULL; - u = lookup->next) + for (u = lang_output_section_statement.head; u; u = lookup->next) { lookup = &u->output_section_statement; - if (strncmp (".rel", lookup->name, 4) == 0 - && lookup->bfd_section != NULL - && (lookup->bfd_section->flags & SEC_ALLOC) != 0) + if (strncmp (".rel", lookup->name, 4) == 0) { - return lookup; + /* Don't place after .rel.plt as doing so results in wrong + dynamic tags. Also, place allocated reloc sections before + non-allocated. */ + int lookrela = lookup->name[4] == 'a'; + + if (strcmp (".plt", lookup->name + 4 + lookrela) == 0 + || (lookup->bfd_section != NULL + && (lookup->bfd_section->flags & SEC_ALLOC) == 0)) + break; + last = lookup; + if (rela == lookrela) + last_rel = lookup; + if (lookup->bfd_section != NULL + && (lookup->bfd_section->flags & SEC_ALLOC) != 0) + last_rel_alloc = lookup; } } - return (lang_output_section_statement_type *) NULL; + + if (last_rel_alloc) + return last_rel_alloc; + + if (last_rel) + return last_rel; + + return last; } -EOF +/* Find the last output section before given output statement. + Used by place_orphan. */ -if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then -cat >>e${EMULATION_NAME}.c <<EOF +static asection * +output_prev_sec_find (os) + lang_output_section_statement_type *os; +{ + asection *s = (asection *) NULL; + lang_statement_union_type *u; + lang_output_section_statement_type *lookup; + + for (u = lang_output_section_statement.head; + u != (lang_statement_union_type *) NULL; + u = lookup->next) + { + lookup = &u->output_section_statement; + if (lookup == os) + return s; + + if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL) + s = lookup->bfd_section; + } + + return NULL; +} /* Place an orphan section. We use this to put random SHF_ALLOC sections in the right segment. */ @@ -1176,9 +1309,10 @@ struct orphan_save { lang_output_section_statement_type *os; asection **section; lang_statement_union_type **stmt; + lang_statement_union_type **os_tail; }; -static boolean +static bfd_boolean gld${EMULATION_NAME}_place_orphan (file, s) lang_input_statement_type *file; asection *s; @@ -1196,25 +1330,39 @@ gld${EMULATION_NAME}_place_orphan (file, s) lang_statement_list_type add; etree_type *address; const char *secname; - const char *outsecname; const char *ps = NULL; lang_output_section_statement_type *os; + lang_statement_union_type **os_tail; + etree_type *load_base; + int isdyn = 0; secname = bfd_get_section_name (s->owner, s); + if (! link_info.relocateable + && link_info.combreloc + && (s->flags & SEC_ALLOC) + && strncmp (secname, ".rel", 4) == 0) + { + if (secname[4] == 'a') + secname = ".rela.dyn"; + else + secname = ".rel.dyn"; + isdyn = 1; + } - if (! config.unique_orphan_sections && ! unique_section_p (secname)) + if (isdyn || (!config.unique_orphan_sections && !unique_section_p (secname))) { /* Look through the script to see where to place this section. */ os = lang_output_section_find (secname); if (os != NULL - && os->bfd_section != NULL - && ((s->flags ^ os->bfd_section->flags) - & (SEC_LOAD | SEC_ALLOC)) == 0) + && (os->bfd_section == NULL + || ((s->flags ^ os->bfd_section->flags) + & (SEC_LOAD | SEC_ALLOC)) == 0)) { - /* We have already placed a section with this name. */ - wild_doit (&os->children, s, os, file); - return true; + /* We already have an output section statement with this + name, and its bfd section, if any, has compatible flags. */ + lang_add_section (&os->children, s, os, file); + return TRUE; } } @@ -1228,8 +1376,8 @@ gld${EMULATION_NAME}_place_orphan (file, s) && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 && hold_text.os != NULL) { - wild_doit (&hold_text.os->children, s, hold_text.os, file); - return true; + lang_add_section (&hold_text.os->children, s, hold_text.os, file); + return TRUE; } /* Decide which segment the section should go in based on the @@ -1240,8 +1388,12 @@ gld${EMULATION_NAME}_place_orphan (file, s) #define HAVE_SECTION(hold, name) \ (hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL) - if (s->flags & SEC_EXCLUDE) - return false; + if ((s->flags & SEC_EXCLUDE) != 0 && !link_info.relocateable) + { + if (s->output_section == NULL) + s->output_section = bfd_abs_section_ptr; + return TRUE; + } place = NULL; if ((s->flags & SEC_ALLOC) == 0) @@ -1260,8 +1412,9 @@ gld${EMULATION_NAME}_place_orphan (file, s) && HAVE_SECTION (hold_data, ".data")) place = &hold_data; else if (strncmp (secname, ".rel", 4) == 0 + && (s->flags & SEC_LOAD) != 0 && (hold_rel.os != NULL - || (hold_rel.os = output_rel_find ()) != NULL)) + || (hold_rel.os = output_rel_find (s)) != NULL)) place = &hold_rel; else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY && HAVE_SECTION (hold_rodata, ".rodata")) @@ -1275,13 +1428,10 @@ gld${EMULATION_NAME}_place_orphan (file, s) /* Choose a unique name for the section. This will be needed if the same section name appears in the input file with different loadable or allocatable characteristics. */ - outsecname = secname; - if (bfd_get_section_by_name (output_bfd, outsecname) != NULL) + if (bfd_get_section_by_name (output_bfd, secname) != NULL) { - outsecname = bfd_get_unique_section_name (output_bfd, - outsecname, - &count); - if (outsecname == NULL) + secname = bfd_get_unique_section_name (output_bfd, secname, &count); + if (secname == NULL) einfo ("%F%P: place_orphan failed: %E\n"); } @@ -1302,38 +1452,48 @@ gld${EMULATION_NAME}_place_orphan (file, s) { /* If the name of the section is representable in C, then create symbols to mark the start and the end of the section. */ - for (ps = outsecname; *ps != '\0'; ps++) - if (! isalnum ((unsigned char) *ps) && *ps != '_') + for (ps = secname; *ps != '\0'; ps++) + if (! ISALNUM (*ps) && *ps != '_') break; if (*ps == '\0') { char *symname; etree_type *e_align; - symname = (char *) xmalloc (ps - outsecname + sizeof "__start_"); - sprintf (symname, "__start_%s", outsecname); + symname = (char *) xmalloc (ps - secname + sizeof "__start_"); + sprintf (symname, "__start_%s", secname); e_align = exp_unop (ALIGN_K, exp_intop ((bfd_vma) 1 << s->alignment_power)); lang_add_assignment (exp_assop ('=', symname, e_align)); } } + address = NULL; if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) address = exp_intop ((bfd_vma) 0); - else - address = NULL; - os = lang_enter_output_section_statement (outsecname, address, 0, + load_base = NULL; + if (place != NULL && place->os->load_base != NULL) + { + etree_type *lma_from_vma; + lma_from_vma = exp_binop ('-', place->os->load_base, + exp_nameop (ADDR, place->os->name)); + load_base = exp_binop ('+', lma_from_vma, + exp_nameop (ADDR, secname)); + } + + os_tail = lang_output_section_statement.tail; + os = lang_enter_output_section_statement (secname, address, 0, (bfd_vma) 0, (etree_type *) NULL, (etree_type *) NULL, - (etree_type *) NULL); + load_base); - wild_doit (&os->children, s, os, file); + lang_add_section (&os->children, s, os, file); lang_leave_output_section_statement ((bfd_vma) 0, "*default*", - (struct lang_output_section_phdr_list *) NULL, "*default*"); + (struct lang_output_section_phdr_list *) NULL, NULL); if (config.build_constructors && *ps == '\0') { @@ -1344,8 +1504,8 @@ gld${EMULATION_NAME}_place_orphan (file, s) if (place != NULL) stat_ptr = &add; - symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_"); - sprintf (symname, "__stop_%s", outsecname); + symname = (char *) xmalloc (ps - secname + sizeof "__stop_"); + sprintf (symname, "__stop_%s", secname); lang_add_assignment (exp_assop ('=', symname, exp_nameop (NAME, "."))); } @@ -1353,55 +1513,64 @@ gld${EMULATION_NAME}_place_orphan (file, s) /* Restore the global list pointer. */ stat_ptr = old; - if (place != NULL) + if (place != NULL && os->bfd_section != NULL) { asection *snew, **pps; snew = os->bfd_section; - if (place->section != NULL - || (place->os->bfd_section != NULL - && place->os->bfd_section != snew)) + + /* Shuffle the bfd section list to make the output file look + neater. This is really only cosmetic. */ + if (place->section == NULL) { - /* Shuffle the section to make the output file look neater. - This is really only cosmetic. */ - if (place->section == NULL) - { -#if 0 - /* Finding the end of the list is a little tricky. We - make a wild stab at it by comparing section flags. */ - flagword first_flags = place->os->bfd_section->flags; - for (pps = &place->os->bfd_section->next; - *pps != NULL && (*pps)->flags == first_flags; - pps = &(*pps)->next) - ; - place->section = pps; -#else - /* Put orphans after the first section on the list. */ - place->section = &place->os->bfd_section->next; -#endif - } + asection *bfd_section = place->os->bfd_section; + + /* If the output statement hasn't been used to place + any input sections (and thus doesn't have an output + bfd_section), look for the closest prior output statement + having an output section. */ + if (bfd_section == NULL) + bfd_section = output_prev_sec_find (place->os); + + if (bfd_section != NULL && bfd_section != snew) + place->section = &bfd_section->next; + } - /* Unlink the section. */ + if (place->section != NULL) + { + /* Unlink the section. */ for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) ; - *pps = snew->next; + bfd_section_list_remove (output_bfd, pps); /* Now tack it on to the "place->os" section list. */ - snew->next = *place->section; - *place->section = snew; + bfd_section_list_insert (output_bfd, place->section, snew); } - place->section = &snew->next; /* Save the end of this list. */ + /* Save the end of this list. Further ophans of this type will + follow the one we've just added. */ + place->section = &snew->next; + + /* The following is non-cosmetic. We try to put the output + statements in some sort of reasonable order here, because + they determine the final load addresses of the orphan + sections. In addition, placing output statements in the + wrong order may require extra segments. For instance, + given a typical situation of all read-only sections placed + in one segment and following that a segment containing all + the read-write sections, we wouldn't want to place an orphan + read/write section before or amongst the read-only ones. */ if (add.head != NULL) { - /* We try to put the output statements in some sort of - reasonable order here, because they determine the final - load addresses of the orphan sections. */ + lang_statement_union_type *newly_added_os; + if (place->stmt == NULL) { /* Put the new statement list right at the head. */ *add.tail = place->os->header.next; place->os->header.next = add.head; + + place->os_tail = &place->os->next; } else { @@ -1417,12 +1586,51 @@ gld${EMULATION_NAME}_place_orphan (file, s) /* Save the end of this list. */ place->stmt = add.tail; + + /* Do the same for the list of output section statements. */ + newly_added_os = *os_tail; + *os_tail = NULL; + newly_added_os->output_section_statement.next = *place->os_tail; + *place->os_tail = newly_added_os; + place->os_tail = &newly_added_os->output_section_statement.next; + + /* Fixing the global list pointer here is a little different. + We added to the list in lang_enter_output_section_statement, + trimmed off the new output_section_statment above when + assigning *os_tail = NULL, but possibly added it back in + the same place when assigning *place->os_tail. */ + if (*os_tail == NULL) + lang_output_section_statement.tail = os_tail; } } - return true; + return TRUE; } +EOF +fi + +if test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then +cat >>e${EMULATION_NAME}.c <<EOF + +static void +gld${EMULATION_NAME}_finish () +{ + if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info)) + { + lang_reset_memory_regions (); + + /* Resize the sections. */ + lang_size_sections (stat_ptr->head, abs_output_section, + &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); + /* Redo special stuff. */ + ldemul_after_allocation (); + + /* Do the assignments again. */ + lang_do_assignments (stat_ptr->head, abs_output_section, + (fill_type *) 0, (bfd_vma) 0); + } +} EOF fi @@ -1445,27 +1653,35 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c - +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; else +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +fi if test -n "$GENERATE_SHLIB_SCRIPT" ; then -echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c +if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +echo ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c fi - -echo ' ; else if (config.data_bss_contig == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xz >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c +fi +echo ' ; else if (config.data_bss_contig == TRUE) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xz >> e${EMULATION_NAME}.c +if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +echo ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c +fi +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. @@ -1474,18 +1690,43 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; +EOF +if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : +else +cat >>e${EMULATION_NAME}.c <<EOF else if (!config.magic_demand_paged) return "ldscripts/${EMULATION_NAME}.xn"; +EOF +fi +if test -n "$GENERATE_SHLIB_SCRIPT" ; then +if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +cat >>e${EMULATION_NAME}.c <<EOF + else if (link_info.shared && link_info.combreloc) + return "ldscripts/${EMULATION_NAME}.xsc"; +EOF +fi +cat >>e${EMULATION_NAME}.c <<EOF else if (link_info.shared) return "ldscripts/${EMULATION_NAME}.xs"; - else if (config.data_bss_contig == true) +EOF +fi +cat >>e${EMULATION_NAME}.c <<EOF + else if (config.data_bss_contig == TRUE) return "ldscripts/${EMULATION_NAME}.xz"; +EOF +if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +cat >>e${EMULATION_NAME}.c <<EOF + else if (link_info.combreloc) + return "ldscripts/${EMULATION_NAME}.xc"; +EOF +fi +cat >>e${EMULATION_NAME}.c <<EOF else return "ldscripts/${EMULATION_NAME}.x"; } @@ -1496,8 +1737,6 @@ fi if test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then -if test x"$LDEMUL_PARSE_ARGS" != xgld"$EMULATION_NAME"_parse_args; then - if test -n "$PARSE_AND_LIST_PROLOGUE" ; then cat >>e${EMULATION_NAME}.c <<EOF $PARSE_AND_LIST_PROLOGUE @@ -1506,88 +1745,85 @@ fi cat >>e${EMULATION_NAME}.c <<EOF -#include "getopt.h" - #define OPTION_DISABLE_NEW_DTAGS (400) #define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1) #define OPTION_GROUP (OPTION_ENABLE_NEW_DTAGS + 1) +#define OPTION_EH_FRAME_HDR (OPTION_GROUP + 1) + +static void gld${EMULATION_NAME}_add_options + PARAMS ((int, char **, int, struct option **, int, struct option **)); -static struct option longopts[] = +static void +gld${EMULATION_NAME}_add_options (ns, shortopts, nl, longopts, nrl, really_longopts) + int ns; + char **shortopts; + int nl; + struct option **longopts; + int nrl ATTRIBUTE_UNUSED; + struct option **really_longopts ATTRIBUTE_UNUSED; { + static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:"; + static const struct option xtra_long[] = { EOF if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then cat >>e${EMULATION_NAME}.c <<EOF - /* getopt allows abbreviations, so we do this to stop it from - treating -d/-e as abbreviations for these options. */ - {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS}, - {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS}, - {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS}, - {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS}, - {"Bgroup", no_argument, NULL, OPTION_GROUP}, - {"Bgroup", no_argument, NULL, OPTION_GROUP}, + {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS}, + {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS}, + {"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR}, + {"Bgroup", no_argument, NULL, OPTION_GROUP}, EOF fi if test -n "$PARSE_AND_LIST_LONGOPTS" ; then cat >>e${EMULATION_NAME}.c <<EOF - $PARSE_AND_LIST_LONGOPTS + $PARSE_AND_LIST_LONGOPTS EOF fi cat >>e${EMULATION_NAME}.c <<EOF - {NULL, no_argument, NULL, 0} -}; - + {NULL, no_argument, NULL, 0} + }; + + *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short)); + memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short)); + *longopts = (struct option *) + xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); + memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); +} -static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **)); +static bfd_boolean gld${EMULATION_NAME}_handle_option + PARAMS ((int)); -static int -gld${EMULATION_NAME}_parse_args (argc, argv) - int argc; - char ** argv; +static bfd_boolean +gld${EMULATION_NAME}_handle_option (optc) + int optc; { - int longind; - int optc; - static int prevoptind = -1; - int prevopterr = opterr; - int wanterror; - - if (prevoptind != optind) - opterr = 0; - - wanterror = opterr; - prevoptind = optind; - - optc = getopt_long_only (argc, argv, - "-${PARSE_AND_LIST_SHORTOPTS}z:", longopts, - &longind); - opterr = prevopterr; - switch (optc) { default: - if (wanterror) - xexit (1); - optind = prevoptind; - return 0; + return FALSE; EOF if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then cat >>e${EMULATION_NAME}.c <<EOF case OPTION_DISABLE_NEW_DTAGS: - link_info.new_dtags = false; + link_info.new_dtags = FALSE; break; case OPTION_ENABLE_NEW_DTAGS: - link_info.new_dtags = true; + link_info.new_dtags = TRUE; + break; + + case OPTION_EH_FRAME_HDR: + link_info.eh_frame_hdr = TRUE; break; case OPTION_GROUP: link_info.flags_1 |= (bfd_vma) DF_1_GROUP; /* Groups must be self-contained. */ - link_info.no_undefined = true; + link_info.no_undefined = TRUE; break; case 'z': @@ -1616,7 +1852,15 @@ cat >>e${EMULATION_NAME}.c <<EOF link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN; } else if (strcmp (optarg, "defs") == 0) - link_info.no_undefined = true; + link_info.no_undefined = TRUE; + else if (strcmp (optarg, "muldefs") == 0) + link_info.allow_multiple_definition = TRUE; + else if (strcmp (optarg, "combreloc") == 0) + link_info.combreloc = TRUE; + else if (strcmp (optarg, "nocombreloc") == 0) + link_info.combreloc = FALSE; + else if (strcmp (optarg, "nocopyreloc") == 0) + link_info.nocopyreloc = TRUE; /* What about the other Solaris -z options? FIXME. */ break; EOF @@ -1631,11 +1875,10 @@ fi cat >>e${EMULATION_NAME}.c <<EOF } - return 1; + return TRUE; } EOF -fi if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then cat >>e${EMULATION_NAME}.c <<EOF @@ -1653,17 +1896,21 @@ cat >>e${EMULATION_NAME}.c <<EOF fprintf (file, _(" -Bgroup\t\tSelects group name lookup rules for DSO\n")); fprintf (file, _(" --disable-new-dtags\tDisable new dynamic tags\n")); fprintf (file, _(" --enable-new-dtags\tEnable new dynamic tags\n")); + fprintf (file, _(" --eh-frame-hdr\tCreate .eh_frame_hdr section\n")); + fprintf (file, _(" -z combreloc\t\tMerge dynamic relocs into one section and sort\n")); fprintf (file, _(" -z defs\t\tDisallows undefined symbols\n")); fprintf (file, _(" -z initfirst\t\tMark DSO to be initialized first at runtime\n")); fprintf (file, _(" -z interpose\t\tMark object to interpose all DSOs but executable\n")); fprintf (file, _(" -z loadfltr\t\tMark object requiring immediate process\n")); + fprintf (file, _(" -z muldefs\t\tAllow multiple definitions\n")); + fprintf (file, _(" -z nocombreloc\tDon't merge dynamic relocs into one section\n")); + fprintf (file, _(" -z nocopyreloc\tDon't create copy relocs\n")); fprintf (file, _(" -z nodefaultlib\tMark object not to use default search paths\n")); fprintf (file, _(" -z nodelete\t\tMark DSO non-deletable at runtime\n")); fprintf (file, _(" -z nodlopen\t\tMark DSO not available to dlopen\n")); fprintf (file, _(" -z nodump\t\tMark DSO not available to dldump\n")); fprintf (file, _(" -z now\t\tMark object non-lazy runtime binding\n")); - fprintf (file, _(" -z origin\t\tMark object requiring immediate \$ORIGIN processing\n")); - fprintf (file, _("\t\t\t at runtime\n")); + fprintf (file, _(" -z origin\t\tMark object requiring immediate \$ORIGIN processing\n\t\t\t at runtime\n")); fprintf (file, _(" -z KEYWORD\t\tIgnored for Solaris compatibility\n")); EOF fi @@ -1685,11 +1932,10 @@ EOF fi fi else -if test x"$LDEMUL_PARSE_ARGS" != xgld"$EMULATION_NAME"_parse_args; then cat >>e${EMULATION_NAME}.c <<EOF -#define gld${EMULATION_NAME}_parse_args NULL +#define gld${EMULATION_NAME}_add_options NULL +#define gld${EMULATION_NAME}_handle_option NULL EOF -fi if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then cat >>e${EMULATION_NAME}.c <<EOF #define gld${EMULATION_NAME}_list_options NULL @@ -1713,15 +1959,18 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", - ${LDEMUL_FINISH-NULL}, + ${LDEMUL_FINISH-gld${EMULATION_NAME}_finish}, ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive}, ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan}, ${LDEMUL_SET_SYMBOLS-NULL}, - ${LDEMUL_PARSE_ARGS-gld${EMULATION_NAME}_parse_args}, + ${LDEMUL_PARSE_ARGS-NULL}, + gld${EMULATION_NAME}_add_options, + gld${EMULATION_NAME}_handle_option, ${LDEMUL_UNRECOGNIZED_FILE-NULL}, ${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options}, ${LDEMUL_RECOGNIZED_FILE-NULL}, ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL}, + ${LDEMUL_NEW_VERS_PATTERN-NULL} }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/elfobsd.em b/gnu/usr.bin/binutils/ld/emultempl/elfobsd.em deleted file mode 100644 index 1981519fb2a..00000000000 --- a/gnu/usr.bin/binutils/ld/emultempl/elfobsd.em +++ /dev/null @@ -1,1036 +0,0 @@ -# This shell script emits a C file. -*- C -*- -# It does some substitutions. -# This file is now misnamed, because it supports both 32 bit and 64 bit -# ELF emulations. -test -z "${ELFSIZE}" && ELFSIZE=32 -cat >e${EMULATION_NAME}.c <<EOF -/* This file is is generated by a shell script. DO NOT EDIT! */ - -/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME} - Copyright (C) 1991, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Steve Chamberlain <sac@cygnus.com> - ELF support by Ian Lance Taylor <ian@cygnus.com> - -This file is part of GLD, the Gnu Linker. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define TARGET_IS_${EMULATION_NAME} - -#include "bfd.h" -#include "sysdep.h" - -#include <ctype.h> -#include <dirent.h> - -#include "bfdlink.h" - -#include "ld.h" -#include "ldmain.h" -#include "ldemul.h" -#include "ldfile.h" -#include "ldmisc.h" -#include "ldexp.h" -#include "ldlang.h" -#include "ldgram.h" - -static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); -static boolean gld${EMULATION_NAME}_open_dynamic_archive - PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); -static void gld${EMULATION_NAME}_after_open PARAMS ((void)); -static void gld${EMULATION_NAME}_check_needed - PARAMS ((lang_input_statement_type *)); -static void gld${EMULATION_NAME}_stat_needed - PARAMS ((lang_input_statement_type *)); -static boolean gld${EMULATION_NAME}_search_needed - PARAMS ((const char *, const char *)); -static boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *)); -static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); -static void gld${EMULATION_NAME}_find_statement_assignment - PARAMS ((lang_statement_union_type *)); -static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *)); -static boolean gld${EMULATION_NAME}_place_orphan - PARAMS ((lang_input_statement_type *, asection *)); -static void gld${EMULATION_NAME}_place_section - PARAMS ((lang_statement_union_type *)); -static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); - -static void -gld${EMULATION_NAME}_before_parse() -{ - ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; - config.dynamic_link = ${DYNAMIC_LINK-true}; -} - -/* Try to open a dynamic archive. This is where we know that ELF - dynamic libraries have an extension of .so. */ -/* Library not found as plain .so. Scan version numbers. Note that so.1 is - prefered before so.1.n because the first form is assumed to be a symlink - created by ldconfig to the configured version */ -static char * -findshlib(arch, search, entry) - const char *arch; - search_dirs_type *search; - lang_input_statement_type *entry; -{ - DIR *dd = opendir(search->name); - struct dirent *dp; - char *string; - int len; - int version = -1; - int subversion = -1; - - - if(dd == NULL) - return(NULL); - - string = (char *)xmalloc(strlen (search->name) - + strlen (entry->filename) - + strlen (arch) - + sizeof "/lib.so." - + 16); /* XXX 16 would be sufficient for a version no */ - sprintf(string, "lib%s%s.so.", entry->filename, arch); - len = strlen(string); - - while((dp = readdir(dd)) != NULL) { - if(dp->d_namlen < len) - continue; - if(strncmp(string, dp->d_name, len) == 0) { - char *cp = &dp->d_name[len]; - int v; - if(!isdigit(*cp)) - continue; - v = strtol(cp, &cp, 10); - if(*cp == 0 && v >= version) { - version = v; - subversion = -1; - } - if(*cp++ == '.' && v > version) { - version = v; - subversion = strtol(cp, &cp, 10); - } - } - } - closedir(dd); - - if(version < 0) { - free(string); - return(NULL); - } - if(subversion < 0) - sprintf (string, "%s/lib%s%s.so.%d", search->name, entry->filename, arch, version); - else - sprintf (string, "%s/lib%s%s.so.%d.%d", search->name, entry->filename, arch, version, subversion); - return(string); -} - -static boolean -gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) - const char *arch; - search_dirs_type *search; - lang_input_statement_type *entry; -{ - const char *filename; - char *string; - - if (! entry->is_archive) - return false; - - filename = entry->filename; - - string = (char *) xmalloc (strlen (search->name) - + strlen (filename) - + strlen (arch) - + sizeof "/lib.so"); - - sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); - - if (! ldfile_try_open_bfd (string, entry)) - { - free (string); - string = findshlib(arch, search, entry); - if(!string || !ldfile_try_open_bfd (string, entry)) { - free (string); - return false; - } - } - - entry->filename = string; - - /* We have found a dynamic object to include in the link. The ELF - backend linker will create a DT_NEEDED entry in the .dynamic - section naming this file. If this file includes a DT_SONAME - entry, it will be used. Otherwise, the ELF linker will just use - the name of the file. For an archive found by searching, like - this one, the DT_NEEDED entry should consist of just the name of - the file, without the path information used to find it. Note - that we only need to do this if we have a dynamic object; an - archive will never be referenced by a DT_NEEDED entry. - - FIXME: This approach--using bfd_elf_set_dt_needed_name--is not - very pretty. I haven't been able to think of anything that is - pretty, though. */ - if (bfd_check_format (entry->the_bfd, bfd_object) - && (entry->the_bfd->flags & DYNAMIC) != 0) - { - char *needed_name; - - ASSERT (entry->is_archive && entry->search_dirs_flag); - needed_name = (char *) xmalloc (strlen (filename) - + strlen (arch) - + sizeof "lib.so"); - sprintf (needed_name, "lib%s%s.so", filename, arch); - bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name); - } - - return true; -} - -EOF -if [ "x${host}" = "x${target}" ] ; then - if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then -cat >>e${EMULATION_NAME}.c <<EOF - -/* For a native linker, check the file /etc/ld.so.conf for directories - in which we may find shared libraries. /etc/ld.so.conf is really - only meaningful on Linux, but we check it on other systems anyhow. */ - -static boolean gld${EMULATION_NAME}_check_ld_so_conf PARAMS ((const char *)); - -static boolean -gld${EMULATION_NAME}_check_ld_so_conf (name) - const char *name; -{ - static boolean initialized; - static char *ld_so_conf; - - if (! initialized) - { - FILE *f; - - f = fopen ("/etc/ld.so.conf", FOPEN_RT); - if (f != NULL) - { - char *b; - size_t len, alloc; - int c; - - len = 0; - alloc = 100; - b = (char *) xmalloc (alloc); - - while ((c = getc (f)) != EOF) - { - if (len + 1 >= alloc) - { - alloc *= 2; - b = (char *) xrealloc (b, alloc); - } - if (c != ':' - && c != ' ' - && c != '\t' - && c != '\n' - && c != ',') - { - b[len] = c; - ++len; - } - else - { - if (len > 0 && b[len - 1] != ':') - { - b[len] = ':'; - ++len; - } - } - } - - if (len > 0 && b[len - 1] == ':') - --len; - - if (len > 0) - b[len] = '\0'; - else - { - free (b); - b = NULL; - } - - fclose (f); - - ld_so_conf = b; - } - - initialized = true; - } - - if (ld_so_conf == NULL) - return false; - - return gld${EMULATION_NAME}_search_needed (ld_so_conf, name); -} - -EOF - fi -fi -cat >>e${EMULATION_NAME}.c <<EOF - -/* These variables are required to pass information back and forth - between after_open and check_needed and stat_needed. */ - -static struct bfd_link_needed_list *global_needed; -static struct stat global_stat; -static boolean global_found; - -/* This is called after all the input files have been opened. */ - -static void -gld${EMULATION_NAME}_after_open () -{ - struct bfd_link_needed_list *needed, *l; - - /* We only need to worry about this when doing a final link. */ - if (link_info.relocateable || link_info.shared) - return; - - /* Get the list of files which appear in DT_NEEDED entries in - dynamic objects included in the link (often there will be none). - For each such file, we want to track down the corresponding - library, and include the symbol table in the link. This is what - the runtime dynamic linker will do. Tracking the files down here - permits one dynamic object to include another without requiring - special action by the person doing the link. Note that the - needed list can actually grow while we are stepping through this - loop. */ - needed = bfd_elf_get_needed_list (output_bfd, &link_info); - for (l = needed; l != NULL; l = l->next) - { - struct bfd_link_needed_list *ll; - const char *lib_path; - size_t len; - search_dirs_type *search; - - /* If we've already seen this file, skip it. */ - for (ll = needed; ll != l; ll = ll->next) - if (strcmp (ll->name, l->name) == 0) - break; - if (ll != l) - continue; - - /* See if this file was included in the link explicitly. */ - global_needed = l; - global_found = false; - lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); - if (global_found) - continue; - - /* We need to find this file and include the symbol table. We - want to search for the file in the same way that the dynamic - linker will search. That means that we want to use - rpath_link, rpath, then the environment variable - LD_LIBRARY_PATH (native only), then the linker script - LIB_SEARCH_DIRS. We do not search using the -L arguments. */ - if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link, - l->name)) - continue; - if (gld${EMULATION_NAME}_search_needed (command_line.rpath, l->name)) - continue; - if (command_line.rpath_link == NULL - && command_line.rpath == NULL) - { - lib_path = (const char *) getenv ("LD_RUN_PATH"); - if (gld${EMULATION_NAME}_search_needed (lib_path, l->name)) - continue; - } -EOF -if [ "x${host}" = "x${target}" ] ; then - if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then -cat >>e${EMULATION_NAME}.c <<EOF - lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); - if (gld${EMULATION_NAME}_search_needed (lib_path, l->name)) - continue; -EOF - fi -fi -cat >>e${EMULATION_NAME}.c <<EOF - len = strlen (l->name); - for (search = search_head; search != NULL; search = search->next) - { - char *filename; - - if (search->cmdline) - continue; - filename = (char *) xmalloc (strlen (search->name) + len + 2); - sprintf (filename, "%s/%s", search->name, l->name); - if (gld${EMULATION_NAME}_try_needed (filename)) - break; - free (filename); - } - if (search != NULL) - continue; -EOF -if [ "x${host}" = "x${target}" ] ; then - if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then -cat >>e${EMULATION_NAME}.c <<EOF - if (gld${EMULATION_NAME}_check_ld_so_conf (l->name)) - continue; -EOF - fi -fi -cat >>e${EMULATION_NAME}.c <<EOF - - einfo ("%P: warning: %s, needed by %B, not found\n", - l->name, l->by); - } -} - -/* Search for a needed file in a path. */ - -static boolean -gld${EMULATION_NAME}_search_needed (path, name) - const char *path; - const char *name; -{ - const char *s; - size_t len; - - if (path == NULL || *path == '\0') - return false; - len = strlen (name); - while (1) - { - char *filename, *sset; - - s = strchr (path, ':'); - if (s == NULL) - s = path + strlen (path); - - filename = (char *) xmalloc (s - path + len + 2); - if (s == path) - sset = filename; - else - { - memcpy (filename, path, s - path); - filename[s - path] = '/'; - sset = filename + (s - path) + 1; - } - strcpy (sset, name); - - if (gld${EMULATION_NAME}_try_needed (filename)) - return true; - - free (filename); - - if (*s == '\0') - break; - path = s + 1; - } - - return false; -} - -/* This function is called for each possible name for a dynamic object - named by a DT_NEEDED entry. */ - -static boolean -gld${EMULATION_NAME}_try_needed (name) - const char *name; -{ - bfd *abfd; - - abfd = bfd_openr (name, bfd_get_target (output_bfd)); - if (abfd == NULL) - return false; - if (! bfd_check_format (abfd, bfd_object)) - { - (void) bfd_close (abfd); - return false; - } - if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) - { - (void) bfd_close (abfd); - return false; - } - - /* We've found a dynamic object matching the DT_NEEDED entry. */ - - /* We have already checked that there is no other input file of the - same name. We must now check again that we are not including the - same file twice. We need to do this because on many systems - libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will - reference libc.so.1. If we have already included libc.so, we - don't want to include libc.so.1 if they are the same file, and we - can only check that using stat. */ - - if (bfd_stat (abfd, &global_stat) != 0) - einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd); - global_found = false; - lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed); - if (global_found) - { - /* Return true to indicate that we found the file, even though - we aren't going to do anything with it. */ - return true; - } - - /* Tell the ELF backend that don't want the output file to have a - DT_NEEDED entry for this file. */ - bfd_elf_set_dt_needed_name (abfd, ""); - - /* Add this file into the symbol table. */ - if (! bfd_link_add_symbols (abfd, &link_info)) - einfo ("%F%B: could not read symbols: %E\n", abfd); - - return true; -} - -/* See if an input file matches a DT_NEEDED entry by name. */ - -static void -gld${EMULATION_NAME}_check_needed (s) - lang_input_statement_type *s; -{ - if (global_found) - return; - - if (s->filename != NULL - && strcmp (s->filename, global_needed->name) == 0) - { - global_found = true; - return; - } - - if (s->the_bfd != NULL) - { - const char *soname; - - soname = bfd_elf_get_dt_soname (s->the_bfd); - if (soname != NULL - && strcmp (soname, global_needed->name) == 0) - { - global_found = true; - return; - } - } - - if (s->search_dirs_flag - && s->filename != NULL - && strchr (global_needed->name, '/') == NULL) - { - const char *f; - - f = strrchr (s->filename, '/'); - if (f != NULL - && strcmp (f + 1, global_needed->name) == 0) - { - global_found = true; - return; - } - } -} - -/* See if an input file matches a DT_NEEDED entry by running stat on - the file. */ - -static void -gld${EMULATION_NAME}_stat_needed (s) - lang_input_statement_type *s; -{ - struct stat st; - const char *suffix; - const char *soname; - const char *f; - - if (global_found) - return; - if (s->the_bfd == NULL) - return; - - if (bfd_stat (s->the_bfd, &st) != 0) - { - einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd); - return; - } - - if (st.st_dev == global_stat.st_dev - && st.st_ino == global_stat.st_ino) - { - global_found = true; - return; - } - - /* We issue a warning if it looks like we are including two - different versions of the same shared library. For example, - there may be a problem if -lc picks up libc.so.6 but some other - shared library has a DT_NEEDED entry of libc.so.5. This is a - hueristic test, and it will only work if the name looks like - NAME.so.VERSION. FIXME: Depending on file names is error-prone. - If we really want to issue warnings about mixing version numbers - of shared libraries, we need to find a better way. */ - - if (strchr (global_needed->name, '/') != NULL) - return; - suffix = strstr (global_needed->name, ".so."); - if (suffix == NULL) - return; - suffix += sizeof ".so." - 1; - - soname = bfd_elf_get_dt_soname (s->the_bfd); - if (soname == NULL) - soname = s->filename; - - f = strrchr (soname, '/'); - if (f != NULL) - ++f; - else - f = soname; - - if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0) - einfo ("%P: warning: %s, needed by %B, may conflict with %s\n", - global_needed->name, global_needed->by, f); -} - -/* This is called after the sections have been attached to output - sections, but before any sizes or addresses have been set. */ - -static void -gld${EMULATION_NAME}_before_allocation () -{ - const char *rpath; - asection *sinterp; - - /* If we are going to make any variable assignments, we need to let - the ELF backend know about them in case the variables are - referred to by dynamic objects. */ - lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment); - - /* Let the ELF backend work out the sizes of any sections required - by dynamic linking. */ - rpath = command_line.rpath; - if (rpath == NULL) - rpath = (const char *) getenv ("LD_RUN_PATH"); - if (! bfd_elf${ELFSIZE}_size_dynamic_sections (output_bfd, - command_line.soname, - rpath, - command_line.export_dynamic, - &link_info, - &sinterp)) - einfo ("%P%F: failed to set dynamic section sizes: %E\n"); - - /* Let the user override the dynamic linker we are using. */ - if (command_line.interpreter != NULL - && sinterp != NULL) - { - sinterp->contents = (bfd_byte *) command_line.interpreter; - sinterp->_raw_size = strlen (command_line.interpreter) + 1; - } - - /* Look for any sections named .gnu.warning. As a GNU extensions, - we treat such sections as containing warning messages. We print - out the warning message, and then zero out the section size so - that it does not get copied into the output file. */ - - { - LANG_FOR_EACH_INPUT_STATEMENT (is) - { - asection *s; - bfd_size_type sz; - char *msg; - boolean ret; - - if (is->just_syms_flag) - continue; - - s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning"); - if (s == NULL) - continue; - - sz = bfd_section_size (is->the_bfd, s); - msg = xmalloc ((size_t) sz + 1); - if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz)) - einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", - is->the_bfd); - msg[sz] = '\0'; - ret = link_info.callbacks->warning (&link_info, msg, - (const char *) NULL, - is->the_bfd, (asection *) NULL, - (bfd_vma) 0); - ASSERT (ret); - free (msg); - - /* Clobber the section size, so that we don't waste copying the - warning into the output file. */ - s->_raw_size = 0; - } - } - - /* For MIPS ELF the .reginfo section requires special handling. - Each input section is 24 bytes, and the final output section must - also be 24 bytes. We handle this by clobbering all but the first - input section size to 0. The .reginfo section is handled - specially by the backend code anyhow. */ - { - boolean found = false; - LANG_FOR_EACH_INPUT_STATEMENT (is) - { - asection *s; - - if (is->just_syms_flag) - continue; - - s = bfd_get_section_by_name (is->the_bfd, ".reginfo"); - if (s == NULL) - continue; - - if (! found) - { - found = true; - continue; - } - - s->_raw_size = 0; - s->_cooked_size = 0; - } - } -} - -/* This is called by the before_allocation routine via - lang_for_each_statement. It locates any assignment statements, and - tells the ELF backend about them, in case they are assignments to - symbols which are referred to by dynamic objects. */ - -static void -gld${EMULATION_NAME}_find_statement_assignment (s) - lang_statement_union_type *s; -{ - if (s->header.type == lang_assignment_statement_enum) - gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); -} - -/* Look through an expression for an assignment statement. */ - -static void -gld${EMULATION_NAME}_find_exp_assignment (exp) - etree_type *exp; -{ - struct bfd_link_hash_entry *h; - - switch (exp->type.node_class) - { - case etree_provide: - h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst, - false, false, false); - if (h == NULL) - break; - - /* We call record_link_assignment even if the symbol is defined. - This is because if it is defined by a dynamic object, we - actually want to use the value defined by the linker script, - not the value from the dynamic object (because we are setting - symbols like etext). If the symbol is defined by a regular - object, then, as it happens, calling record_link_assignment - will do no harm. */ - - /* Fall through. */ - case etree_assign: - if (strcmp (exp->assign.dst, ".") != 0) - { - if (! (bfd_elf${ELFSIZE}_record_link_assignment - (output_bfd, &link_info, exp->assign.dst, - exp->type.node_class == etree_provide ? true : false))) - einfo ("%P%F: failed to record assignment to %s: %E\n", - exp->assign.dst); - } - gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src); - break; - - case etree_binary: - gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs); - gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs); - break; - - case etree_trinary: - gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond); - gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs); - gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs); - break; - - case etree_unary: - gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child); - break; - - default: - break; - } -} - -/* Place an orphan section. We use this to put random SHF_ALLOC - sections in the right segment. */ - -static asection *hold_section; -static lang_output_section_statement_type *hold_use; -static lang_output_section_statement_type *hold_text; -static lang_output_section_statement_type *hold_rodata; -static lang_output_section_statement_type *hold_data; -static lang_output_section_statement_type *hold_bss; -static lang_output_section_statement_type *hold_rel; - -/*ARGSUSED*/ -static boolean -gld${EMULATION_NAME}_place_orphan (file, s) - lang_input_statement_type *file; - asection *s; -{ - lang_output_section_statement_type *place; - asection *snew, **pps; - lang_statement_list_type *old; - lang_statement_list_type add; - etree_type *address; - const char *secname, *ps; - lang_output_section_statement_type *os; - - if ((s->flags & SEC_ALLOC) == 0) - return false; - - /* Look through the script to see where to place this section. */ - hold_section = s; - hold_use = NULL; - lang_for_each_statement (gld${EMULATION_NAME}_place_section); - - if (hold_use != NULL) - { - /* We have already placed a section with this name. */ - wild_doit (&hold_use->children, s, hold_use, file); - return true; - } - - secname = bfd_get_section_name (s->owner, s); - - /* If this is a final link, then always put .gnu.warning.SYMBOL - sections into the .text section to get them out of the way. */ - if (! link_info.shared - && ! link_info.relocateable - && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 - && hold_text != NULL) - { - wild_doit (&hold_text->children, s, hold_text, file); - return true; - } - - /* Decide which segment the section should go in based on the - section name and section flags. */ - place = NULL; - if ((s->flags & SEC_HAS_CONTENTS) == 0 - && hold_bss != NULL) - place = hold_bss; - else if ((s->flags & SEC_READONLY) == 0 - && hold_data != NULL) - place = hold_data; - else if (strncmp (secname, ".rel", 4) == 0 - && hold_rel != NULL) - place = hold_rel; - else if ((s->flags & SEC_CODE) == 0 - && (s->flags & SEC_READONLY) != 0 - && hold_rodata != NULL) - place = hold_rodata; - else if ((s->flags & SEC_READONLY) != 0 - && hold_text != NULL) - place = hold_text; - if (place == NULL) - return false; - - /* Create the section in the output file, and put it in the right - place. This shuffling is to make the output file look neater. */ - snew = bfd_make_section (output_bfd, secname); - if (snew == NULL) - einfo ("%P%F: output format %s cannot represent section called %s\n", - output_bfd->xvec->name, secname); - if (place->bfd_section != NULL) - { - for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) - ; - *pps = snew->next; - snew->next = place->bfd_section->next; - place->bfd_section->next = snew; - } - - /* Start building a list of statements for this section. */ - old = stat_ptr; - stat_ptr = &add; - lang_list_init (stat_ptr); - - /* If the name of the section is representable in C, then create - symbols to mark the start and the end of the section. */ - for (ps = secname; *ps != '\0'; ps++) - if (! isalnum (*ps) && *ps != '_') - break; - if (*ps == '\0' && config.build_constructors) - { - char *symname; - - symname = (char *) xmalloc (ps - secname + sizeof "__start_"); - sprintf (symname, "__start_%s", secname); - lang_add_assignment (exp_assop ('=', symname, - exp_unop (ALIGN_K, - exp_intop ((bfd_vma) 1 - << s->alignment_power)))); - } - - if (! link_info.relocateable) - address = NULL; - else - address = exp_intop ((bfd_vma) 0); - - lang_enter_output_section_statement (secname, address, 0, - (bfd_vma) 0, - (etree_type *) NULL, - (etree_type *) NULL, - (etree_type *) NULL); - - os = lang_output_section_statement_lookup (secname); - wild_doit (&os->children, s, os, file); - - lang_leave_output_section_statement - ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL); - stat_ptr = &add; - - if (*ps == '\0' && config.build_constructors) - { - char *symname; - - symname = (char *) xmalloc (ps - secname + sizeof "__stop_"); - sprintf (symname, "__stop_%s", secname); - lang_add_assignment (exp_assop ('=', symname, - exp_nameop (NAME, "."))); - } - - /* Now stick the new statement list right after PLACE. */ - *add.tail = place->header.next; - place->header.next = add.head; - - stat_ptr = old; - - return true; -} - -static void -gld${EMULATION_NAME}_place_section (s) - lang_statement_union_type *s; -{ - lang_output_section_statement_type *os; - - if (s->header.type != lang_output_section_statement_enum) - return; - - os = &s->output_section_statement; - - if (strcmp (os->name, hold_section->name) == 0) - hold_use = os; - - if (strcmp (os->name, ".text") == 0) - hold_text = os; - else if (strcmp (os->name, ".rodata") == 0) - hold_rodata = os; - else if (strcmp (os->name, ".data") == 0) - hold_data = os; - else if (strcmp (os->name, ".bss") == 0) - hold_bss = os; - else if (hold_rel == NULL - && os->bfd_section != NULL - && strncmp (os->name, ".rel", 4) == 0) - hold_rel = os; -} - -static char * -gld${EMULATION_NAME}_get_script(isfile) - int *isfile; -EOF - -if test -n "$COMPILE_IN" -then -# Scripts compiled in. - -# sed commands to quote an ld script as a C string. -sc='s/["\\]/\\&/g -s/$/\\n\\/ -1s/^/"/ -$s/$/n"/ -' - -cat >>e${EMULATION_NAME}.c <<EOF -{ - *isfile = 0; - - if (link_info.relocateable == true && config.build_constructors == true) - return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`; - else if (link_info.relocateable == true) - return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`; - else if (!config.text_read_only) - return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`; - else if (!config.magic_demand_paged) - return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`; - else if (link_info.shared) - return `sed "$sc" ldscripts/${EMULATION_NAME}.xs`; - else - return `sed "$sc" ldscripts/${EMULATION_NAME}.x`; -} -EOF - -else -# Scripts read from the filesystem. - -cat >>e${EMULATION_NAME}.c <<EOF -{ - *isfile = 1; - - if (link_info.relocateable == true && config.build_constructors == true) - return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) - return "ldscripts/${EMULATION_NAME}.xr"; - else if (!config.text_read_only) - return "ldscripts/${EMULATION_NAME}.xbn"; - else if (!config.magic_demand_paged) - return "ldscripts/${EMULATION_NAME}.xn"; - else if (link_info.shared) - return "ldscripts/${EMULATION_NAME}.xs"; - else - return "ldscripts/${EMULATION_NAME}.x"; -} -EOF - -fi - -cat >>e${EMULATION_NAME}.c <<EOF - -struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = -{ - gld${EMULATION_NAME}_before_parse, - syslib_default, - hll_default, - after_parse_default, - gld${EMULATION_NAME}_after_open, - after_allocation_default, - set_output_arch_default, - ldemul_default_target, - gld${EMULATION_NAME}_before_allocation, - gld${EMULATION_NAME}_get_script, - "${EMULATION_NAME}", - "${OUTPUT_FORMAT}", - NULL, - NULL, - gld${EMULATION_NAME}_open_dynamic_archive, - gld${EMULATION_NAME}_place_orphan -}; -EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/generic.em b/gnu/usr.bin/binutils/ld/emultempl/generic.em index cb5c30c064f..3a7d6115315 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/generic.em +++ b/gnu/usr.bin/binutils/ld/emultempl/generic.em @@ -4,7 +4,7 @@ cat >e${EMULATION_NAME}.c <<EOF /* This file is is generated by a shell script. DO NOT EDIT! */ /* emulate the original gld for the given ${EMULATION_NAME} - Copyright 1991, 1992, 1994, 1996, 2000 + Copyright 1991, 1992, 1994, 1996, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Steve Chamberlain steve@cygnus.com @@ -42,6 +42,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); +EOF + +# Import any needed special functions and/or overrides. +# +if test -n "$EXTRA_EM_FILE" ; then +. ${srcdir}/emultempl/${EXTRA_EM_FILE}.em +fi + +if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then +cat >>e${EMULATION_NAME}.c <<EOF + static void gld${EMULATION_NAME}_before_parse() { @@ -50,6 +61,12 @@ gld${EMULATION_NAME}_before_parse() #endif /* not TARGET_ */ } +EOF +fi + +if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then +cat >>e${EMULATION_NAME}.c <<EOF + static char * gld${EMULATION_NAME}_get_script(isfile) int *isfile; @@ -66,19 +83,19 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. @@ -87,9 +104,9 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; @@ -99,34 +116,37 @@ cat >>e${EMULATION_NAME}.c <<EOF return "ldscripts/${EMULATION_NAME}.x"; } EOF - +fi fi cat >>e${EMULATION_NAME}.c <<EOF struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { - gld${EMULATION_NAME}_before_parse, - syslib_default, - hll_default, - after_parse_default, - after_open_default, - after_allocation_default, - set_output_arch_default, - ldemul_default_target, - before_allocation_default, - gld${EMULATION_NAME}_get_script, + ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse}, + ${LDEMUL_SYSLIB-syslib_default}, + ${LDEMUL_HLL-hll_default}, + ${LDEMUL_AFTER_PARSE-after_parse_default}, + ${LDEMUL_AFTER_OPEN-after_open_default}, + ${LDEMUL_AFTER_ALLOCATION-after_allocation_default}, + ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default}, + ${LDEMUL_CHOOSE_TARGET-ldemul_default_target}, + ${LDEMUL_BEFORE_ALLOCATION-before_allocation_default}, + ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", - NULL, /* finish */ - NULL, /* create output section statements */ - NULL, /* open dynamic archive */ - NULL, /* place orphan */ - NULL, /* set symbols */ - NULL, /* parse args */ - NULL, /* unrecognized file */ - NULL, /* list options */ - NULL, /* recognized file */ - NULL /* find_potential_libraries */ + ${LDEMUL_FINISH-NULL}, + ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, + ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-NULL}, + ${LDEMUL_PLACE_ORPHAN-NULL}, + ${LDEMUL_SET_SYMBOLS-NULL}, + ${LDEMUL_PARSE_ARGS-NULL}, + NULL, /* add_options */ + NULL, /* handle_option */ + ${LDEMUL_UNRECOGNIZED_FILE-NULL}, + ${LDEMUL_LIST_OPTIONS-NULL}, + ${LDEMUL_RECOGNIZED_FILE-NULL}, + ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL}, + ${LDEMUL_NEW_VERS_PATTERN-NULL} }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/gld960.em b/gnu/usr.bin/binutils/ld/emultempl/gld960.em index 8d98355cb13..dd73e6b061e 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/gld960.em +++ b/gnu/usr.bin/binutils/ld/emultempl/gld960.em @@ -1,7 +1,8 @@ # This shell script emits a C file. -*- C -*- # It does some substitutions. cat >e${EMULATION_NAME}.c <<EOF -/* Copyright 1991, 1992, 1994, 1999, 2000 Free Software Foundation, Inc. +/* Copyright 1991, 1992, 1994, 1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -38,6 +39,11 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307 #include "ldfile.h" #include "ldemul.h" +static void gld960_before_parse PARAMS ((void)); +static char *gld960_choose_target PARAMS ((int, char **)); +static void gld960_set_output_arch PARAMS ((void)); +static char *gld960_get_script PARAMS ((int *)); + #ifdef GNU960 static void @@ -53,7 +59,7 @@ gld960_before_parse() ldfile_add_library_path (concat (env, "/lib/libbout", (const char *) NULL), - false); + FALSE); } } ldfile_output_architecture = bfd_arch_i960; @@ -66,11 +72,11 @@ static void gld960_before_parse() char *env ; env = getenv("G960LIB"); if (env) { - ldfile_add_library_path(env, false); + ldfile_add_library_path(env, FALSE); } env = getenv("G960BASE"); if (env) - ldfile_add_library_path (concat (env, "/lib", (const char *) NULL), false); + ldfile_add_library_path (concat (env, "/lib", (const char *) NULL), FALSE); ldfile_output_architecture = bfd_arch_i960; } @@ -84,7 +90,9 @@ gld960_set_output_arch() } static char * -gld960_choose_target() +gld960_choose_target (argc, argv) + int argc ATTRIBUTE_UNUSED; + char **argv ATTRIBUTE_UNUSED; { #ifdef GNU960 @@ -120,19 +128,19 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. @@ -141,9 +149,9 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; @@ -178,9 +186,12 @@ struct ld_emulation_xfer_struct ld_gld960_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ - NULL /* find_potential_libraries */ + NULL, /* find_potential_libraries */ + NULL /* new_vers_pattern */ }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/gld960c.em b/gnu/usr.bin/binutils/ld/emultempl/gld960c.em index 48fd95dafb1..132afcb5c5e 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/gld960c.em +++ b/gnu/usr.bin/binutils/ld/emultempl/gld960c.em @@ -1,7 +1,7 @@ # This shell script emits a C file. -*- C -*- # It does some substitutions. cat >e${EMULATION_NAME}.c <<EOF -/* Copyright 1991, 1993, 1994, 1996, 1999, 2000 +/* Copyright 1991, 1993, 1994, 1996, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -26,10 +26,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA */ -#include <ctype.h> #include "bfd.h" #include "sysdep.h" #include "libiberty.h" +#include "safe-ctype.h" #include "bfdlink.h" #include "ld.h" @@ -41,6 +41,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ldfile.h" #include "ldemul.h" +static void gld960_before_parse PARAMS ((void)); +static void gld960_set_output_arch PARAMS ((void)); +static char *gld960_choose_target PARAMS ((int, char **)); +static char *gld960_get_script PARAMS ((int *)); + #ifdef GNU960 static void @@ -56,7 +61,7 @@ gld960_before_parse() ldfile_add_library_path (concat (env, "/lib/libcoff", (const char *) NULL), - false); + FALSE); } } ldfile_output_architecture = bfd_arch_i960; @@ -69,12 +74,12 @@ static void gld960_before_parse() char *env ; env = getenv("G960LIB"); if (env) { - ldfile_add_library_path(env, false); + ldfile_add_library_path(env, FALSE); } env = getenv("G960BASE"); if (env) ldfile_add_library_path (concat (env, "/lib", (const char *) NULL), - false); + FALSE); ldfile_output_architecture = bfd_arch_i960; } @@ -91,8 +96,7 @@ gld960_set_output_arch() s = concat ("i960:", ldfile_output_machine_name, (char *) NULL); for (s1 = s; *s1 != '\0'; s1++) - if (isupper ((unsigned char) *s1)) - *s1 = tolower ((unsigned char) *s1); + *s1 = TOLOWER (*s1); ldfile_set_output_arch (s); free (s); } @@ -101,7 +105,9 @@ gld960_set_output_arch() } static char * -gld960_choose_target() +gld960_choose_target (argc, argv) + int argc ATTRIBUTE_UNUSED; + char **argv ATTRIBUTE_UNUSED; { #ifdef GNU960 @@ -137,19 +143,19 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. @@ -158,9 +164,9 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; @@ -195,9 +201,12 @@ struct ld_emulation_xfer_struct ld_gld960coff_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ - NULL /* find_potential_libraries */ + NULL, /* find_potential_libraries */ + NULL /* new_vers_pattern */ }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/hppaelf.em b/gnu/usr.bin/binutils/ld/emultempl/hppaelf.em index 050020028dc..4e3b6b957f9 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/hppaelf.em +++ b/gnu/usr.bin/binutils/ld/emultempl/hppaelf.em @@ -1,5 +1,5 @@ # This shell script emits a C file. -*- C -*- -# Copyright 1991, 1993, 1994, 1997, 1999, 2000, 2001 +# Copyright 1991, 1993, 1994, 1997, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # # This file is part of GLD, the Gnu Linker. @@ -27,14 +27,13 @@ cat >>e${EMULATION_NAME}.c <<EOF #include "ldctor.h" #include "elf32-hppa.h" -static void hppaelf_after_parse PARAMS((void)); +static void hppaelf_after_parse PARAMS ((void)); static void hppaelf_create_output_section_statements PARAMS ((void)); -static void hppaelf_delete_padding_statements - PARAMS ((lang_statement_list_type *)); static asection *hppaelf_add_stub_section PARAMS ((const char *, asection *)); -static void hppaelf_layaout_sections_again PARAMS ((void)); -static void hppaelf_finish PARAMS ((void)); +static void hppaelf_layout_sections_again PARAMS ((void)); +static void gld${EMULATION_NAME}_finish PARAMS ((void)); +static void build_section_lists PARAMS ((lang_statement_union_type *)); /* Fake input file for stubs. */ @@ -45,6 +44,9 @@ static lang_input_statement_type *stub_file; stubs. */ static int multi_subspace = 0; +/* Whether we need to call hppa_layout_sections_again. */ +static int need_laying_out = 0; + /* Maximum size of a group of input sections that can be handled by one stub section. A value of +/-1 indicates the bfd back-end should use a suitable default size. */ @@ -58,7 +60,7 @@ hppaelf_after_parse () { if (link_info.relocateable) lang_add_unique (".text"); -#if 0 /* enable this once we split millicode stuff from libgcc */ +#if 0 /* Enable this once we split millicode stuff from libgcc. */ else lang_add_input_file ("milli", lang_input_file_is_l_enum, @@ -88,63 +90,6 @@ hppaelf_create_output_section_statements () ldlang_add_file (stub_file); } -/* Walk all the lang statements splicing out any padding statements from - the list. */ - -static void -hppaelf_delete_padding_statements (list) - lang_statement_list_type *list; -{ - lang_statement_union_type *s; - lang_statement_union_type **ps; - for (ps = &list->head; (s = *ps) != NULL; ps = &s->next) - { - switch (s->header.type) - { - - /* We want to recursively walk these sections. */ - case lang_constructors_statement_enum: - hppaelf_delete_padding_statements (&constructor_list); - break; - - case lang_output_section_statement_enum: - hppaelf_delete_padding_statements (&s->output_section_statement.children); - break; - - case lang_group_statement_enum: - hppaelf_delete_padding_statements (&s->group_statement.children); - break; - - case lang_wild_statement_enum: - hppaelf_delete_padding_statements (&s->wild_statement.children); - break; - - /* Here's what we are really looking for. Splice these out of - the list. */ - case lang_padding_statement_enum: - *ps = s->next; - if (*ps == NULL) - list->tail = ps; - break; - - /* We don't care about these cases. */ - case lang_data_statement_enum: - case lang_object_symbols_statement_enum: - case lang_output_statement_enum: - case lang_target_statement_enum: - case lang_input_section_enum: - case lang_input_statement_enum: - case lang_assignment_statement_enum: - case lang_address_statement_enum: - break; - - default: - abort (); - break; - } - } -} - struct hook_stub_info { @@ -154,18 +99,18 @@ struct hook_stub_info /* Traverse the linker tree to find the spot where the stub goes. */ -static boolean hook_in_stub +static bfd_boolean hook_in_stub PARAMS ((struct hook_stub_info *, lang_statement_union_type **)); -static boolean +static bfd_boolean hook_in_stub (info, lp) struct hook_stub_info *info; lang_statement_union_type **lp; { lang_statement_union_type *l; - boolean ret; + bfd_boolean ret; - for (; (l = *lp) != NULL; lp = &l->next) + for (; (l = *lp) != NULL; lp = &l->header.next) { switch (l->header.type) { @@ -201,7 +146,7 @@ hook_in_stub (info, lp) before its associated input section. */ *lp = info->add.head; *(info->add.tail) = l; - return true; + return TRUE; } break; @@ -222,7 +167,7 @@ hook_in_stub (info, lp) break; } } - return false; + return FALSE; } @@ -258,7 +203,7 @@ hppaelf_add_stub_section (stub_sec_name, input_section) info.input_section = input_section; lang_list_init (&info.add); - wild_doit (&info.add, stub_sec, os, stub_file); + lang_add_section (&info.add, stub_sec, os, stub_file); if (info.add.head == NULL) goto err_ret; @@ -275,25 +220,40 @@ hppaelf_add_stub_section (stub_sec_name, input_section) /* Another call-back for elf32_hppa_size_stubs. */ static void -hppaelf_layaout_sections_again () +hppaelf_layout_sections_again () { /* If we have changed sizes of the stub sections, then we need to recalculate all the section offsets. This may mean we need to add even more stubs. */ + need_laying_out = 0; - /* Delete all the padding statements, they're no longer valid. */ - hppaelf_delete_padding_statements (stat_ptr); + lang_reset_memory_regions (); /* Resize the sections. */ lang_size_sections (stat_ptr->head, abs_output_section, - &stat_ptr->head, 0, (bfd_vma) 0, false); + &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); /* Redo special stuff. */ ldemul_after_allocation (); /* Do the assignments again. */ lang_do_assignments (stat_ptr->head, abs_output_section, - (fill_type) 0, (bfd_vma) 0); + (fill_type *) 0, (bfd_vma) 0); +} + + +static void +build_section_lists (statement) + lang_statement_union_type *statement; +{ + if (statement->header.type == lang_input_section_enum + && !statement->input_section.ifile->just_syms_flag + && statement->input_section.section->output_section != NULL + && statement->input_section.section->output_section->owner == output_bfd) + { + elf32_hppa_next_input_section (&link_info, + statement->input_section.section); + } } @@ -301,38 +261,64 @@ hppaelf_layaout_sections_again () to build linker stubs. */ static void -hppaelf_finish () +gld${EMULATION_NAME}_finish () { + /* bfd_elf32_discard_info just plays with debugging sections, + ie. doesn't affect any code, so we can delay resizing the + sections. It's likely we'll resize everything in the process of + adding stubs. */ + if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info)) + need_laying_out = 1; + /* If generating a relocatable output file, then we don't have to examine the relocs. */ - if (link_info.relocateable) - return; - - /* Call into the BFD backend to do the real work. */ - if (! elf32_hppa_size_stubs (output_bfd, - stub_file->the_bfd, - &link_info, - multi_subspace, - group_size, - &hppaelf_add_stub_section, - &hppaelf_layaout_sections_again)) + if (! link_info.relocateable) { - einfo ("%X%P: can not size stub section: %E\n"); - return; - } + int ret = elf32_hppa_setup_section_lists (output_bfd, &link_info); - /* Set the global data pointer. */ - if (! elf32_hppa_set_gp (output_bfd, &link_info)) - { - einfo ("%X%P: can not set gp\n"); - return; + if (ret != 0) + { + if (ret < 0) + { + einfo ("%X%P: can not size stub section: %E\n"); + return; + } + + lang_for_each_statement (build_section_lists); + + /* Call into the BFD backend to do the real work. */ + if (! elf32_hppa_size_stubs (output_bfd, + stub_file->the_bfd, + &link_info, + multi_subspace, + group_size, + &hppaelf_add_stub_section, + &hppaelf_layout_sections_again)) + { + einfo ("%X%P: can not size stub section: %E\n"); + return; + } + } } - /* Now build the linker stubs. */ - if (stub_file->the_bfd->sections != NULL) + if (need_laying_out) + hppaelf_layout_sections_again (); + + if (! link_info.relocateable) { - if (! elf32_hppa_build_stubs (&link_info)) - einfo ("%X%P: can not build stubs: %E\n"); + /* Set the global data pointer. */ + if (! elf32_hppa_set_gp (output_bfd, &link_info)) + { + einfo ("%X%P: can not set gp\n"); + return; + } + + /* Now build the linker stubs. */ + if (stub_file->the_bfd->sections != NULL) + { + if (! elf32_hppa_build_stubs (&link_info)) + einfo ("%X%P: can not build stubs: %E\n"); + } } } @@ -374,28 +360,24 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_STUBGROUP_SIZE (OPTION_MULTI_SUBSPACE + 1) ' -# The options are repeated below so that no abbreviations are allowed. -# Otherwise -s matches stub-group-size PARSE_AND_LIST_LONGOPTS=' { "multi-subspace", no_argument, NULL, OPTION_MULTI_SUBSPACE }, - { "multi-subspace", no_argument, NULL, OPTION_MULTI_SUBSPACE }, - { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE }, { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE }, ' PARSE_AND_LIST_OPTIONS=' fprintf (file, _("\ - --multi-subspace Generate import and export stubs to support\n\ - multiple sub-space shared libraries\n" + --multi-subspace Generate import and export stubs to support\n\ + multiple sub-space shared libraries\n" )); fprintf (file, _("\ - --stub-group-size=N Maximum size of a group of input sections that can be\n\ - handled by one stub section. A negative value\n\ - locates all stubs before their branches (with a\n\ - group size of -N), while a positive value allows\n\ - two groups of input sections, one before, and one\n\ - after each stub section. Values of +/-1 indicate\n\ - the linker should choose suitable defaults." + --stub-group-size=N Maximum size of a group of input sections that can be\n\ + handled by one stub section. A negative value\n\ + locates all stubs before their branches (with a\n\ + group size of -N), while a positive value allows\n\ + two groups of input sections, one before, and one\n\ + after each stub section. Values of +/-1 indicate\n\ + the linker should choose suitable defaults.\n" )); ' @@ -417,5 +399,5 @@ PARSE_AND_LIST_ARGS_CASES=' # Put these extra hppaelf routines in ld_${EMULATION_NAME}_emulation # LDEMUL_AFTER_PARSE=hppaelf_after_parse -LDEMUL_FINISH=hppaelf_finish +LDEMUL_FINISH=gld${EMULATION_NAME}_finish LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=hppaelf_create_output_section_statements diff --git a/gnu/usr.bin/binutils/ld/emultempl/linux.em b/gnu/usr.bin/binutils/ld/emultempl/linux.em index 888a3ddc61c..fae1252ca60 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/linux.em +++ b/gnu/usr.bin/binutils/ld/emultempl/linux.em @@ -1,10 +1,15 @@ # This shell script emits a C file. -*- C -*- # It does some substitutions. +if [ -z "$MACHINE" ]; then + OUTPUT_ARCH=${ARCH} +else + OUTPUT_ARCH=${ARCH}:${MACHINE} +fi cat >e${EMULATION_NAME}.c <<EOF /* This file is is generated by a shell script. DO NOT EDIT! */ /* Linux a.out emulation code for ${EMULATION_NAME} - Copyright 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000 + Copyright 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. Written by Steve Chamberlain <sac@cygnus.com> Linux support by Eric Youngdale <ericy@cais.cais.com> @@ -40,7 +45,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ldemul.h" static void gld${EMULATION_NAME}_before_parse PARAMS ((void)); -static boolean gld${EMULATION_NAME}_open_dynamic_archive +static bfd_boolean gld${EMULATION_NAME}_open_dynamic_archive PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); static void gld${EMULATION_NAME}_find_address_statement PARAMS ((lang_statement_union_type *)); @@ -52,15 +57,23 @@ static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); static void gld${EMULATION_NAME}_before_parse() { - ldfile_output_architecture = bfd_arch_${ARCH}; - config.dynamic_link = true; - config.has_shared = true; + const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}"); + if (arch) + { + ldfile_output_architecture = arch->arch; + ldfile_output_machine = arch->mach; + ldfile_output_machine_name = arch->printable_name; + } + else + ldfile_output_architecture = bfd_arch_${ARCH}; + config.dynamic_link = TRUE; + config.has_shared = TRUE; } /* Try to open a dynamic archive. This is where we know that Linux dynamic libraries have an extension of .sa. */ -static boolean +static bfd_boolean gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) const char *arch; search_dirs_type *search; @@ -69,7 +82,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) char *string; if (! entry->is_archive) - return false; + return FALSE; string = (char *) xmalloc (strlen (search->name) + strlen (entry->filename) @@ -81,12 +94,12 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) if (! ldfile_try_open_bfd (string, entry)) { free (string); - return false; + return FALSE; } entry->filename = string; - return true; + return TRUE; } /* This is called by the create_output_section_statements routine via @@ -144,33 +157,33 @@ then sc="-f stringify.sed" cat >>e${EMULATION_NAME}.c <<EOF -{ +{ *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. cat >>e${EMULATION_NAME}.c <<EOF -{ +{ *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; @@ -185,7 +198,7 @@ fi cat >>e${EMULATION_NAME}.c <<EOF -struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { gld${EMULATION_NAME}_before_parse, syslib_default, @@ -205,9 +218,12 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ - NULL /* find_potential_libraries */ + NULL, /* find_potential_libraries */ + NULL /* new_vers_pattern */ }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/lnk960.em b/gnu/usr.bin/binutils/ld/emultempl/lnk960.em index ec69b45c740..ba0fe93b6f6 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/lnk960.em +++ b/gnu/usr.bin/binutils/ld/emultempl/lnk960.em @@ -2,7 +2,7 @@ # It does some substitutions. cat >e${EMULATION_NAME}.c <<EOF /* intel coff loader emulation specific stuff - Copyright 1991, 1992, 1994, 1995, 1996, 1999, 2000 + Copyright 1991, 1992, 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Written by Steve Chamberlain steve@cygnus.com @@ -47,64 +47,75 @@ static lib_list_type **hll_list_tail = &hll_list; static lib_list_type *syslib_list; static lib_list_type **syslib_list_tail = &syslib_list; +static void append PARAMS ((lib_list_type ***, char *)); +static void lnk960_hll PARAMS ((char *)); +static void lnk960_syslib PARAMS ((char *)); +static void lnk960_before_parse PARAMS ((void)); +static void add_on PARAMS ((lib_list_type *, lang_input_file_enum_type)); +static void lnk960_after_parse PARAMS ((void)); +static void lnk960_before_allocation PARAMS ((void)); +static void lnk960_after_allocation PARAMS ((void)); +static void lnk960_set_output_arch PARAMS ((void)); +static char *lnk960_choose_target PARAMS ((int, char **)); +static char *lnk960_get_script PARAMS ((int *)); + static void -append(list, name) +append (list, name) lib_list_type ***list; char *name; { - lib_list_type *element = - (lib_list_type *)(xmalloc(sizeof(lib_list_type))); + lib_list_type *element = (lib_list_type *) xmalloc (sizeof (lib_list_type)); element->name = name; - element->next = (lib_list_type *)NULL; + element->next = (lib_list_type *) NULL; **list = element; *list = &element->next; } -static boolean had_hll = false; -static boolean had_hll_name = false; +static bfd_boolean had_hll = FALSE; +static bfd_boolean had_hll_name = FALSE; static void -lnk960_hll(name) +lnk960_hll (name) char *name; { - had_hll = true; - if (name != (char *)NULL) { - had_hll_name = true; - append(&hll_list_tail, name); - } + had_hll = TRUE; + if (name != (char *) NULL) + { + had_hll_name = TRUE; + append (&hll_list_tail, name); + } } static void -lnk960_syslib(name) +lnk960_syslib (name) char *name; { - append(&syslib_list_tail,name); + append (&syslib_list_tail, name); } #ifdef GNU960 static void -lnk960_before_parse() +lnk960_before_parse () { static char *env_variables[] = { "G960LIB", "G960BASE", 0 }; char **p; char *env ; - for ( p = env_variables; *p; p++ ){ - env = (char *) getenv(*p); - if (env) { - ldfile_add_library_path(concat(env,"/lib/libcoff",""), false); + for (p = env_variables; *p; p++) + { + env = (char *) getenv (*p); + if (env) + ldfile_add_library_path (concat (env, "/lib/libcoff", ""), FALSE); } - } - env= (char *) getenv("I960BASE"); - if ( env ) { - ldfile_add_library_path(concat(env,"/lib",""), false); - } + env = (char *) getenv ("I960BASE"); + if (env) + ldfile_add_library_path(concat (env, "/lib", ""), FALSE); ldfile_output_architecture = bfd_arch_i960; ldfile_output_machine = bfd_mach_i960_core; @@ -113,19 +124,19 @@ lnk960_before_parse() #else /* not GNU960 */ static void -lnk960_before_parse() +lnk960_before_parse () { - char *name = getenv("I960BASE"); + char *name = getenv ("I960BASE"); - if (name == (char *)NULL) { - name = getenv("G960BASE"); - if (name == (char *)NULL) { - einfo("%P%F I960BASE and G960BASE not set\n"); + if (name == (char *) NULL) + { + name = getenv("G960BASE"); + if (name == (char *) NULL) + einfo ("%P%F I960BASE and G960BASE not set\n"); } - } - ldfile_add_library_path(concat(name,"/lib",""), false); + ldfile_add_library_path (concat (name, "/lib", ""), FALSE); ldfile_output_architecture = bfd_arch_i960; ldfile_output_machine = bfd_mach_i960_core; } @@ -134,55 +145,52 @@ lnk960_before_parse() static void -add_on(list, search) +add_on (list, search) lib_list_type *list; lang_input_file_enum_type search; { - while (list) { - lang_add_input_file(list->name, - search, - (char *)NULL); - list = list->next; - } + while (list) + { + lang_add_input_file (list->name, search, (char *) NULL); + list = list->next; + } } static void -lnk960_after_parse() +lnk960_after_parse () { /* If there has been no arch, default to -KB */ - if (ldfile_output_machine_name[0] ==0) { - ldfile_add_arch("KB"); - } + if (ldfile_output_machine_name[0] == 0) + ldfile_add_arch ("KB"); /* if there has been no hll list then add our own */ - if(had_hll && !had_hll_name) { - append(&hll_list_tail,"cg"); - if (ldfile_output_machine == bfd_mach_i960_ka_sa || - ldfile_output_machine == bfd_mach_i960_ca) { - { - append(&hll_list_tail,"fpg"); - } + if (had_hll && !had_hll_name) + { + append (&hll_list_tail, "cg"); + if (ldfile_output_machine == bfd_mach_i960_ka_sa + || ldfile_output_machine == bfd_mach_i960_ca) + append (&hll_list_tail, "fpg"); } - } - add_on(hll_list, lang_input_file_is_l_enum); - add_on(syslib_list, lang_input_file_is_search_file_enum); + add_on (hll_list, lang_input_file_is_l_enum); + add_on (syslib_list, lang_input_file_is_search_file_enum); } static void -lnk960_before_allocation() +lnk960_before_allocation () { } static void -lnk960_after_allocation() +lnk960_after_allocation () { - if (link_info.relocateable == false) { - lang_abs_symbol_at_end_of(".text","_etext"); - lang_abs_symbol_at_end_of(".data","_edata"); - lang_abs_symbol_at_beginning_of(".bss","_bss_start"); - lang_abs_symbol_at_end_of(".bss","_end"); - } + if (!link_info.relocateable) + { + lang_abs_symbol_at_end_of (".text", "_etext"); + lang_abs_symbol_at_end_of (".data", "_edata"); + lang_abs_symbol_at_beginning_of (".bss", "_bss_start"); + lang_abs_symbol_at_end_of (".bss", "_end"); + } } @@ -219,31 +227,36 @@ machine_table[] = }; static void -lnk960_set_output_arch() +lnk960_set_output_arch () { /* Set the output architecture and machine if possible */ unsigned int i; ldfile_output_machine = bfd_mach_i960_core; - for (i= 0; machine_table[i].name != (char*)NULL; i++) { - if (strcmp(ldfile_output_machine_name,machine_table[i].name)==0) { - ldfile_output_machine = machine_table[i].number; - break; + for (i= 0; machine_table[i].name != (char*) NULL; i++) + { + if (strcmp (ldfile_output_machine_name, machine_table[i].name) == 0) + { + ldfile_output_machine = machine_table[i].number; + break; + } } - } - bfd_set_arch_mach(output_bfd, ldfile_output_architecture, ldfile_output_machine); + bfd_set_arch_mach (output_bfd, ldfile_output_architecture, + ldfile_output_machine); } static char * -lnk960_choose_target() +lnk960_choose_target (argc, argv) + int argc ATTRIBUTE_UNUSED; + char **argv ATTRIBUTE_UNUSED; { #ifdef GNU960 - return bfd_make_targ_name(BFD_COFF_FORMAT, 0); + return bfd_make_targ_name (BFD_COFF_FORMAT, 0); #else - char *from_outside = getenv(TARGET_ENVIRON); - if (from_outside != (char *)NULL) + char *from_outside = getenv (TARGET_ENVIRON); + if (from_outside != (char *) NULL) return from_outside; #ifdef LNK960_LITTLE return "coff-Intel-little"; @@ -255,7 +268,7 @@ lnk960_choose_target() } static char * -lnk960_get_script(isfile) +lnk960_get_script (isfile) int *isfile; EOF @@ -270,19 +283,19 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. @@ -291,9 +304,9 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; @@ -328,9 +341,12 @@ struct ld_emulation_xfer_struct ld_lnk960_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ - NULL /* find_potential_libraries */ + NULL, /* find_potential_libraries */ + NULL /* new_vers_pattern */ }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em b/gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em index 205943b69f7..6e417ed52c6 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em +++ b/gnu/usr.bin/binutils/ld/emultempl/mipsecoff.em @@ -1,10 +1,16 @@ # This shell script emits a C file. -*- C -*- # It does some substitutions. +if [ -z "$MACHINE" ]; then + OUTPUT_ARCH=${ARCH} +else + OUTPUT_ARCH=${ARCH}:${MACHINE} +fi cat >e${EMULATION_NAME}.c <<EOF /* This file is is generated by a shell script. DO NOT EDIT! */ /* Handle embedded relocs for MIPS. - Copyright 1994, 1995, 1997, 2000 Free Software Foundation, Inc. + Copyright 1994, 1995, 1997, 2000, 2002, 2003 + Free Software Foundation, Inc. Written by Ian Lance Taylor <ian@cygnus.com> based on generic.em. This file is part of GLD, the Gnu Linker. @@ -48,7 +54,15 @@ static void gld${EMULATION_NAME}_before_parse() { #ifndef TARGET_ /* I.e., if not generic. */ - ldfile_output_architecture = bfd_arch_${ARCH}; + const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}"); + if (arch) + { + ldfile_output_architecture = arch->arch; + ldfile_output_machine = arch->mach; + ldfile_output_machine_name = arch->printable_name; + } + else + ldfile_output_architecture = bfd_arch_${ARCH}; #endif /* not TARGET_ */ } @@ -181,19 +195,19 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. @@ -202,9 +216,9 @@ cat >>e${EMULATION_NAME}.c <<EOF { *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; @@ -239,9 +253,12 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ - NULL /* find_potential_libraries */ + NULL, /* find_potential_libraries */ + NULL /* new_vers_pattern */ }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/pe.em b/gnu/usr.bin/binutils/ld/emultempl/pe.em index feab3387014..10522d75759 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/pe.em +++ b/gnu/usr.bin/binutils/ld/emultempl/pe.em @@ -1,33 +1,50 @@ # This shell script emits a C file. -*- C -*- # It does some substitutions. +if [ -z "$MACHINE" ]; then + OUTPUT_ARCH=${ARCH} +else + OUTPUT_ARCH=${ARCH}:${MACHINE} +fi rm -f e${EMULATION_NAME}.c (echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-) cat >>e${EMULATION_NAME}.c <<EOF /* This file is part of GLD, the Gnu Linker. - Copyright 1995, 1996, 1997, 1998, 1999, 2000 + Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* For WINDOWS_NT */ /* The original file generated returned different default scripts depending on whether certain switches were set, but these switches pertain to the Linux system and that particular version of coff. In the NT case, we only determine if the subsystem is console or windows in order to select - the correct entry point by default. */ - + the correct entry point by default. */ + +#define TARGET_IS_${EMULATION_NAME} + +/* Do this before including bfd.h, so we prototype the right functions. */ +#ifdef TARGET_IS_arm_epoc_pe +#define bfd_arm_pe_allocate_interworking_sections \ + bfd_arm_epoc_pe_allocate_interworking_sections +#define bfd_arm_pe_get_bfd_for_interworking \ + bfd_arm_epoc_pe_get_bfd_for_interworking +#define bfd_arm_pe_process_before_allocation \ + bfd_arm_epoc_pe_process_before_allocation +#endif + #include "bfd.h" #include "sysdep.h" #include "bfdlink.h" @@ -35,11 +52,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "libiberty.h" #include "ld.h" #include "ldmain.h" -#include "ldgram.h" #include "ldexp.h" #include "ldlang.h" #include "ldfile.h" #include "ldemul.h" +#include <ldgram.h> #include "ldlex.h" #include "ldmisc.h" #include "ldctor.h" @@ -52,7 +69,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "deffile.h" #include "pe-dll.h" -#define TARGET_IS_${EMULATION_NAME} +#include <ctype.h> /* Permit the emulation parameters to override the default section alignment by setting OVERRIDE_SECTION_ALIGNMENT. FIXME: This makes @@ -87,27 +104,44 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define PE_DEF_FILE_ALIGNMENT 0x00000200 #endif -#ifdef TARGET_IS_arm_epoc_pe -#define bfd_arm_pe_allocate_interworking_sections \ - bfd_arm_epoc_pe_allocate_interworking_sections -#define bfd_arm_pe_get_bfd_for_interworking \ - bfd_arm_epoc_pe_get_bfd_for_interworking -#define bfd_arm_pe_process_before_allocation \ - bfd_arm_epoc_pe_process_before_allocation -#endif - static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void)); static void gld_${EMULATION_NAME}_after_open PARAMS ((void)); static void gld_${EMULATION_NAME}_before_parse PARAMS ((void)); static void gld_${EMULATION_NAME}_after_parse PARAMS ((void)); static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void)); -static boolean gld_${EMULATION_NAME}_place_orphan +static asection *output_prev_sec_find + PARAMS ((lang_output_section_statement_type *)); +static bfd_boolean gld_${EMULATION_NAME}_place_orphan PARAMS ((lang_input_statement_type *, asection *)); static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *)); -static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **)); static void gld_${EMULATION_NAME}_finish PARAMS ((void)); -static boolean gld_${EMULATION_NAME}_open_dynamic_archive +static bfd_boolean gld_${EMULATION_NAME}_open_dynamic_archive PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); +static void gld${EMULATION_NAME}_add_options + PARAMS ((int, char **, int, struct option **, int, struct option **)); +static bfd_boolean gld${EMULATION_NAME}_handle_option PARAMS ((int)); +static void gld_${EMULATION_NAME}_list_options PARAMS ((FILE *)); +static void set_pe_name PARAMS ((char *, long)); +static void set_pe_subsystem PARAMS ((void)); +static void set_pe_value PARAMS ((char *)); +static void set_pe_stack_heap PARAMS ((char *, char *)); + +#ifdef DLL_SUPPORT +static bfd_boolean pe_undef_cdecl_match + PARAMS ((struct bfd_link_hash_entry *, PTR)); +static void pe_fixup_stdcalls PARAMS ((void)); +static int make_import_fixup PARAMS ((arelent *, asection *)); +static void pe_find_data_imports PARAMS ((void)); +#endif + +static bfd_boolean pr_sym PARAMS ((struct bfd_hash_entry *, PTR)); +static bfd_boolean gld_${EMULATION_NAME}_unrecognized_file + PARAMS ((lang_input_statement_type *)); +static bfd_boolean gld_${EMULATION_NAME}_recognized_file + PARAMS ((lang_input_statement_type *)); +static int gld_${EMULATION_NAME}_find_potential_libraries + PARAMS ((char *, lang_input_statement_type *)); + static struct internal_extra_pe_aouthdr pe; static int dll; @@ -116,7 +150,7 @@ static char * thumb_entry_symbol = NULL; static lang_assignment_statement_type *image_base_statement = 0; #ifdef DLL_SUPPORT -static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable */ +static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable. */ static char *pe_out_def_filename = NULL; static char *pe_implib_filename = NULL; static int pe_enable_auto_image_base = 0; @@ -128,10 +162,21 @@ extern const char *output_filename; static void gld_${EMULATION_NAME}_before_parse() { + const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}"); + if (arch) + { + ldfile_output_architecture = arch->arch; + ldfile_output_machine = arch->mach; + ldfile_output_machine_name = arch->printable_name; + } + else + ldfile_output_architecture = bfd_arch_${ARCH}; output_filename = "${EXECUTABLE_NAME:-a.exe}"; - ldfile_output_architecture = bfd_arch_${ARCH}; #ifdef DLL_SUPPORT + config.dynamic_link = TRUE; config.has_shared = 1; + link_info.pei386_auto_import = -1; + link_info.pei386_runtime_pseudo_reloc = FALSE; #if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2) #if defined TARGET_IS_mipspe || defined TARGET_IS_armpe @@ -145,7 +190,7 @@ gld_${EMULATION_NAME}_before_parse() /* PE format extra command line options. */ -/* Used for setting flags in the PE header. */ +/* Used for setting flags in the PE header. */ #define OPTION_BASE_FILE (300 + 1) #define OPTION_DLL (OPTION_BASE_FILE + 1) #define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1) @@ -176,50 +221,80 @@ gld_${EMULATION_NAME}_before_parse() #define OPTION_DISABLE_AUTO_IMAGE_BASE (OPTION_ENABLE_AUTO_IMAGE_BASE + 1) #define OPTION_DLL_SEARCH_PREFIX (OPTION_DISABLE_AUTO_IMAGE_BASE + 1) #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_DLL_SEARCH_PREFIX + 1) +#define OPTION_DLL_ENABLE_AUTO_IMPORT (OPTION_NO_DEFAULT_EXCLUDES + 1) +#define OPTION_DLL_DISABLE_AUTO_IMPORT (OPTION_DLL_ENABLE_AUTO_IMPORT + 1) +#define OPTION_ENABLE_EXTRA_PE_DEBUG (OPTION_DLL_DISABLE_AUTO_IMPORT + 1) +#define OPTION_EXCLUDE_LIBS (OPTION_ENABLE_EXTRA_PE_DEBUG + 1) +#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC \ + (OPTION_EXCLUDE_LIBS + 1) +#define OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC \ + (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC + 1) -static struct option longopts[] = { - /* PE options */ - {"base-file", required_argument, NULL, OPTION_BASE_FILE}, - {"dll", no_argument, NULL, OPTION_DLL}, - {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT}, - {"heap", required_argument, NULL, OPTION_HEAP}, - {"image-base", required_argument, NULL, OPTION_IMAGE_BASE}, - {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION}, - {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION}, - {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION}, - {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION}, - {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION}, - {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION}, - {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT}, - {"stack", required_argument, NULL, OPTION_STACK}, - {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, - {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, - {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY}, +static void +gld${EMULATION_NAME}_add_options (ns, shortopts, nl, longopts, nrl, really_longopts) + int ns ATTRIBUTE_UNUSED; + char **shortopts ATTRIBUTE_UNUSED; + int nl; + struct option **longopts; + int nrl ATTRIBUTE_UNUSED; + struct option **really_longopts ATTRIBUTE_UNUSED; +{ + static const struct option xtra_long[] = { + /* PE options */ + {"base-file", required_argument, NULL, OPTION_BASE_FILE}, + {"dll", no_argument, NULL, OPTION_DLL}, + {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT}, + {"heap", required_argument, NULL, OPTION_HEAP}, + {"image-base", required_argument, NULL, OPTION_IMAGE_BASE}, + {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION}, + {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION}, + {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION}, + {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION}, + {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION}, + {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION}, + {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT}, + {"stack", required_argument, NULL, OPTION_STACK}, + {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, + {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, + {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY}, #ifdef DLL_SUPPORT - /* getopt allows abbreviations, so we do this to stop it from treating -o - as an abbreviation for this option */ - {"output-def", required_argument, NULL, OPTION_OUT_DEF}, - {"output-def", required_argument, NULL, OPTION_OUT_DEF}, - {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL}, - {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS}, - {"kill-at", no_argument, NULL, OPTION_KILL_ATS}, - {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES}, - {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP}, - {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP}, - {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME}, - {"warn-duplicate-exports", no_argument, NULL, OPTION_WARN_DUPLICATE_EXPORTS}, - {"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT}, - {"enable-auto-image-base", no_argument, NULL, OPTION_ENABLE_AUTO_IMAGE_BASE}, - {"disable-auto-image-base", no_argument, NULL, OPTION_DISABLE_AUTO_IMAGE_BASE}, - {"dll-search-prefix", required_argument, NULL, OPTION_DLL_SEARCH_PREFIX}, - {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES}, + /* getopt allows abbreviations, so we do this to stop it from treating -o + as an abbreviation for this option */ + {"output-def", required_argument, NULL, OPTION_OUT_DEF}, + {"output-def", required_argument, NULL, OPTION_OUT_DEF}, + {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL}, + {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS}, + {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS}, + {"kill-at", no_argument, NULL, OPTION_KILL_ATS}, + {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES}, + {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP}, + {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP}, + {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME}, + {"warn-duplicate-exports", no_argument, NULL, OPTION_WARN_DUPLICATE_EXPORTS}, + /* getopt() allows abbreviations, so we do this to stop it from + treating -c as an abbreviation for these --compat-implib. */ + {"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT}, + {"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT}, + {"enable-auto-image-base", no_argument, NULL, OPTION_ENABLE_AUTO_IMAGE_BASE}, + {"disable-auto-image-base", no_argument, NULL, OPTION_DISABLE_AUTO_IMAGE_BASE}, + {"dll-search-prefix", required_argument, NULL, OPTION_DLL_SEARCH_PREFIX}, + {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES}, + {"enable-auto-import", no_argument, NULL, OPTION_DLL_ENABLE_AUTO_IMPORT}, + {"disable-auto-import", no_argument, NULL, OPTION_DLL_DISABLE_AUTO_IMPORT}, + {"enable-extra-pe-debug", no_argument, NULL, OPTION_ENABLE_EXTRA_PE_DEBUG}, + {"enable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC}, + {"disable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC}, #endif - {NULL, no_argument, NULL, 0} -}; + {NULL, no_argument, NULL, 0} + }; + *longopts = (struct option *) + xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long)); + memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long)); +} /* PE/WIN32; added routines to get the subsystem type, heap and/or stack - parameters which may be input from the command line */ + parameters which may be input from the command line. */ typedef struct { @@ -260,6 +335,7 @@ static definfo init[] = { NULL, 0, 0, NULL, 0 } }; + static void gld_${EMULATION_NAME}_list_options (file) FILE * file; @@ -285,29 +361,42 @@ gld_${EMULATION_NAME}_list_options (file) fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n")); fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n")); fprintf (file, _(" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n")); + fprintf (file, _(" --exclude-libs lib,lib,... Exclude libraries from automatic export\n")); fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n")); fprintf (file, _(" --kill-at Remove @nn from exported symbols\n")); fprintf (file, _(" --out-implib <file> Generate import library\n")); fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n")); fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports.\n")); - fprintf (file, _(" --compat-implib Create backward compatible import libs;\n")); - fprintf (file, _(" create __imp_<SYMBOL> as well.\n")); - fprintf (file, _(" --enable-auto-image-base Automatically choose image base for DLLs\n")); - fprintf (file, _(" unless user specifies one\n")); + fprintf (file, _(" --compat-implib Create backward compatible import libs;\n\ + create __imp_<SYMBOL> as well.\n")); + fprintf (file, _(" --enable-auto-image-base Automatically choose image base for DLLs\n\ + unless user specifies one\n")); fprintf (file, _(" --disable-auto-image-base Do not auto-choose image base. (default)\n")); - fprintf (file, _(" --dll-search-prefix=<string> When linking dynamically to a dll witout an\n")); - fprintf (file, _(" importlib, use <string><basename>.dll \n")); - fprintf (file, _(" in preference to lib<basename>.dll \n")); + fprintf (file, _(" --dll-search-prefix=<string> When linking dynamically to a dll without\n\ + an importlib, use <string><basename>.dll\n\ + in preference to lib<basename>.dll \n")); + fprintf (file, _(" --enable-auto-import Do sophistcated linking of _sym to\n\ + __imp_sym for DATA references\n")); + fprintf (file, _(" --disable-auto-import Do not auto-import DATA items from DLLs\n")); + fprintf (file, _(" --enable-runtime-pseudo-reloc Work around auto-import limitations by\n\ + adding pseudo-relocations resolved at\n\ + runtime.\n")); + fprintf (file, _(" --disable-runtime-pseudo-reloc Do not add runtime pseudo-relocations for\n\ + auto-imported DATA.\n")); + fprintf (file, _(" --enable-extra-pe-debug Enable verbose debug output when building\n\ + or linking to DLLs (esp. auto-import)\n")); #endif } + static void set_pe_name (name, val) char *name; long val; { int i; - /* Find the name and set it. */ + + /* Find the name and set it. */ for (i = 0; init[i].ptr; i++) { if (strcmp (name, init[i].symbol) == 0) @@ -317,7 +406,7 @@ set_pe_name (name, val) return; } } - abort(); + abort (); } @@ -327,7 +416,7 @@ set_pe_subsystem () const char *sver; int len; int i; - static const struct + static const struct { const char *name; const int value; @@ -395,39 +484,39 @@ set_pe_subsystem () entry = alc_entry; } - lang_add_entry (entry, 1); + lang_add_entry (entry, 0); return; } } - + einfo (_("%P%F: invalid subsystem type %s\n"), optarg); } - static void set_pe_value (name) char *name; - + { char *end; - + set_pe_name (name, strtoul (optarg, &end, 0)); - + if (end == optarg) einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg); optarg = end; } + static void set_pe_stack_heap (resname, comname) char *resname; char *comname; { set_pe_value (resname); - + if (*optarg == ',') { optarg++; @@ -438,35 +527,14 @@ set_pe_stack_heap (resname, comname) } - -static int -gld_${EMULATION_NAME}_parse_args(argc, argv) - int argc; - char **argv; +static bfd_boolean +gld${EMULATION_NAME}_handle_option (optc) + int optc; { - int longind; - int optc; - int prevoptind = optind; - int prevopterr = opterr; - int wanterror; - static int lastoptind = -1; - - if (lastoptind != optind) - opterr = 0; - wanterror = opterr; - - lastoptind = optind; - - optc = getopt_long_only (argc, argv, "-", longopts, &longind); - opterr = prevopterr; - switch (optc) { default: - if (wanterror) - xexit (1); - optind = prevoptind; - return 0; + return FALSE; case OPTION_BASE_FILE: link_info.base_file = (PTR) fopen (optarg, FOPEN_WB); @@ -479,11 +547,11 @@ gld_${EMULATION_NAME}_parse_args(argc, argv) } break; - /* PE options */ - case OPTION_HEAP: + /* PE options. */ + case OPTION_HEAP: set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__"); break; - case OPTION_STACK: + case OPTION_STACK: set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__"); break; case OPTION_SUBSYSTEM: @@ -533,7 +601,10 @@ gld_${EMULATION_NAME}_parse_args(argc, argv) pe_dll_export_everything = 1; break; case OPTION_EXCLUDE_SYMBOLS: - pe_dll_add_excludes (optarg); + pe_dll_add_excludes (optarg, 0); + break; + case OPTION_EXCLUDE_LIBS: + pe_dll_add_excludes (optarg, 1); break; case OPTION_KILL_ATS: pe_dll_kill_ats = 1; @@ -563,19 +634,34 @@ gld_${EMULATION_NAME}_parse_args(argc, argv) pe_enable_auto_image_base = 0; break; case OPTION_DLL_SEARCH_PREFIX: - pe_dll_search_prefix = xstrdup( optarg ); + pe_dll_search_prefix = xstrdup (optarg); break; case OPTION_NO_DEFAULT_EXCLUDES: pe_dll_do_default_excludes = 0; break; + case OPTION_DLL_ENABLE_AUTO_IMPORT: + link_info.pei386_auto_import = 1; + break; + case OPTION_DLL_DISABLE_AUTO_IMPORT: + link_info.pei386_auto_import = 0; + break; + case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC: + link_info.pei386_runtime_pseudo_reloc = 1; + break; + case OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC: + link_info.pei386_runtime_pseudo_reloc = 0; + break; + case OPTION_ENABLE_EXTRA_PE_DEBUG: + pe_dll_extra_pe_debug = 1; + break; #endif } - return 1; + return TRUE; } #ifdef DLL_SUPPORT -static unsigned long +static unsigned long strhash (const char *str) { const unsigned char *s; @@ -598,7 +684,8 @@ strhash (const char *str) return hash; } -/* Use the output file to create a image base for relocatable DLLs. */ +/* Use the output file to create a image base for relocatable DLLs. */ + static unsigned long compute_dll_image_base (const char *ofile) { @@ -614,7 +701,7 @@ static void gld_${EMULATION_NAME}_set_symbols () { /* Run through and invent symbols for all the - names and insert the defaults. */ + names and insert the defaults. */ int j; lang_statement_list_type *save; @@ -637,7 +724,7 @@ gld_${EMULATION_NAME}_set_symbols () if (link_info.relocateable) return; - /* Glue the assignments into the abs section */ + /* Glue the assignments into the abs section. */ save = stat_ptr; stat_ptr = &(abs_output_section->children); @@ -646,23 +733,24 @@ gld_${EMULATION_NAME}_set_symbols () { long val = init[j].value; lang_assignment_statement_type *rv; - rv = lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val))); - if (init[j].size == sizeof(short)) - *(short *)init[j].ptr = val; - else if (init[j].size == sizeof(int)) - *(int *)init[j].ptr = val; - else if (init[j].size == sizeof(long)) - *(long *)init[j].ptr = val; + rv = lang_add_assignment (exp_assop ('=', init[j].symbol, + exp_intop (val))); + if (init[j].size == sizeof (short)) + *(short *) init[j].ptr = val; + else if (init[j].size == sizeof (int)) + *(int *) init[j].ptr = val; + else if (init[j].size == sizeof (long)) + *(long *) init[j].ptr = val; /* This might be a long long or other special type. */ - else if (init[j].size == sizeof(bfd_vma)) - *(bfd_vma *)init[j].ptr = val; - else abort(); + else if (init[j].size == sizeof (bfd_vma)) + *(bfd_vma *) init[j].ptr = val; + else abort (); if (j == IMAGEBASEOFF) image_base_statement = rv; } - /* Restore the pointer. */ + /* Restore the pointer. */ stat_ptr = save; - + if (pe.FileAlignment > pe.SectionAlignment) { @@ -689,27 +777,36 @@ gld_${EMULATION_NAME}_after_parse () opened, so registering the symbol as undefined will make a difference. */ - if (! link_info.relocateable && entry_symbol != NULL) - ldlang_add_undef (entry_symbol); + if (! link_info.relocateable && entry_symbol.name != NULL) + ldlang_add_undef (entry_symbol.name); } +/* pe-dll.c directly accesses pe_data_import_dll, + so it must be defined outside of #ifdef DLL_SUPPORT. + Note - this variable is deliberately not initialised. + This allows it to be treated as a common varaible, and only + exist in one incarnation in a multiple target enabled linker. */ +char * pe_data_import_dll; + #ifdef DLL_SUPPORT static struct bfd_link_hash_entry *pe_undef_found_sym; -static boolean +static bfd_boolean pe_undef_cdecl_match (h, string) struct bfd_link_hash_entry *h; PTR string; { - int sl = strlen (string); + int sl; + + sl = strlen (string); /* Silence compiler warning. */ if (h->type == bfd_link_hash_defined && strncmp (h->root.string, string, sl) == 0 && h->root.string[sl] == '@') - { - pe_undef_found_sym = h; - return false; - } - return true; + { + pe_undef_found_sym = h; + return FALSE; + } + return TRUE; } static void @@ -717,75 +814,198 @@ pe_fixup_stdcalls () { static int gave_warning_message = 0; struct bfd_link_hash_entry *undef, *sym; - char *at; + + if (pe_dll_extra_pe_debug) + printf ("%s\n", __FUNCTION__); + for (undef = link_info.hash->undefs; undef; undef=undef->next) if (undef->type == bfd_link_hash_undefined) - { - at = strchr (undef->root.string, '@'); - if (at) { - /* The symbol is a stdcall symbol, so let's look for a cdecl - symbol with the same name and resolve to that */ - char *cname = xstrdup (undef->root.string); - at = strchr (cname, '@'); - *at = 0; - sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1); - if (sym && sym->type == bfd_link_hash_defined) - { - undef->type = bfd_link_hash_defined; - undef->u.def.value = sym->u.def.value; - undef->u.def.section = sym->u.def.section; - if (pe_enable_stdcall_fixup == -1) - { - einfo (_("Warning: resolving %s by linking to %s\n"), - undef->root.string, cname); - if (! gave_warning_message) - { - gave_warning_message = 1; - einfo(_("Use --enable-stdcall-fixup to disable these warnings\n")); - einfo(_("Use --disable-stdcall-fixup to disable these fixups\n")); - } - } - } + char* at = strchr (undef->root.string, '@'); + int lead_at = (*undef->root.string == '@'); + /* For now, don't try to fixup fastcall symbols. */ + + if (at && !lead_at) + { + /* The symbol is a stdcall symbol, so let's look for a + cdecl symbol with the same name and resolve to that. */ + char *cname = xstrdup (undef->root.string /* + lead_at */); + at = strchr (cname, '@'); + *at = 0; + sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1); + + if (sym && sym->type == bfd_link_hash_defined) + { + undef->type = bfd_link_hash_defined; + undef->u.def.value = sym->u.def.value; + undef->u.def.section = sym->u.def.section; + + if (pe_enable_stdcall_fixup == -1) + { + einfo (_("Warning: resolving %s by linking to %s\n"), + undef->root.string, cname); + if (! gave_warning_message) + { + gave_warning_message = 1; + einfo (_("Use --enable-stdcall-fixup to disable these warnings\n")); + einfo (_("Use --disable-stdcall-fixup to disable these fixups\n")); + } + } + } + } + else + { + /* The symbol is a cdecl symbol, so we look for stdcall + symbols - which means scanning the whole symbol table. */ + pe_undef_found_sym = 0; + bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match, + (PTR) undef->root.string); + sym = pe_undef_found_sym; + if (sym) + { + undef->type = bfd_link_hash_defined; + undef->u.def.value = sym->u.def.value; + undef->u.def.section = sym->u.def.section; + + if (pe_enable_stdcall_fixup == -1) + { + einfo (_("Warning: resolving %s by linking to %s\n"), + undef->root.string, sym->root.string); + if (! gave_warning_message) + { + gave_warning_message = 1; + einfo (_("Use --enable-stdcall-fixup to disable these warnings\n")); + einfo (_("Use --disable-stdcall-fixup to disable these fixups\n")); + } + } + } + } } - else - { - /* The symbol is a cdecl symbol, so we look for stdcall - symbols - which means scanning the whole symbol table */ - pe_undef_found_sym = 0; - bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match, - (PTR) undef->root.string); - sym = pe_undef_found_sym; - if (sym) - { - undef->type = bfd_link_hash_defined; - undef->u.def.value = sym->u.def.value; - undef->u.def.section = sym->u.def.section; - if (pe_enable_stdcall_fixup == -1) - { - einfo (_("Warning: resolving %s by linking to %s\n"), - undef->root.string, sym->root.string); - if (! gave_warning_message) +} + +static int +make_import_fixup (rel, s) + arelent *rel; + asection *s; +{ + struct symbol_cache_entry *sym = *rel->sym_ptr_ptr; + int addend = 0; + + if (pe_dll_extra_pe_debug) + printf ("arelent: %s@%#lx: add=%li\n", sym->name, + (long) rel->address, (long) rel->addend); + + if (! bfd_get_section_contents (s->owner, s, &addend, rel->address, sizeof (addend))) + einfo (_("%C: Cannot get section contents - auto-import exception\n"), + s->owner, s, rel->address); + + pe_create_import_fixup (rel, s, addend); + + return 1; +} + +static void +pe_find_data_imports () +{ + struct bfd_link_hash_entry *undef, *sym; + + if (link_info.pei386_auto_import == 0) + return; + + for (undef = link_info.hash->undefs; undef; undef=undef->next) + { + if (undef->type == bfd_link_hash_undefined) + { + /* C++ symbols are *long*. */ + char buf[4096]; + + if (pe_dll_extra_pe_debug) + printf ("%s:%s\n", __FUNCTION__, undef->root.string); + + sprintf (buf, "__imp_%s", undef->root.string); + + sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1); + + if (sym && sym->type == bfd_link_hash_defined) + { + bfd *b = sym->u.def.section->owner; + asymbol **symbols; + int nsyms, symsize, i; + + if (link_info.pei386_auto_import == -1) + info_msg (_("Info: resolving %s by linking to %s (auto-import)\n"), + undef->root.string, buf); + + symsize = bfd_get_symtab_upper_bound (b); + symbols = (asymbol **) xmalloc (symsize); + nsyms = bfd_canonicalize_symtab (b, symbols); + + for (i = 0; i < nsyms; i++) { - gave_warning_message = 1; - einfo(_("Use --enable-stdcall-fixup to disable these warnings\n")); - einfo(_("Use --disable-stdcall-fixup to disable these fixups\n")); + if (memcmp (symbols[i]->name, "__head_", + sizeof ("__head_") - 1)) + continue; + + if (pe_dll_extra_pe_debug) + printf ("->%s\n", symbols[i]->name); + + pe_data_import_dll = (char*) (symbols[i]->name + + sizeof ("__head_") - 1); + break; } - } - } - } + + pe_walk_relocs_of_symbol (&link_info, undef->root.string, + make_import_fixup); + + /* Let's differentiate it somehow from defined. */ + undef->type = bfd_link_hash_defweak; + /* We replace original name with __imp_ prefixed, this + 1) may trash memory 2) leads to duplicate symbol generation. + Still, IMHO it's better than having name poluted. */ + undef->root.string = sym->root.string; + undef->u.def.value = sym->u.def.value; + undef->u.def.section = sym->u.def.section; + } + } } } #endif /* DLL_SUPPORT */ +static bfd_boolean +pr_sym (h, string) + struct bfd_hash_entry *h; + PTR string ATTRIBUTE_UNUSED; +{ + if (pe_dll_extra_pe_debug) + printf ("+%s\n",h->string); + + return TRUE; +} + + static void gld_${EMULATION_NAME}_after_open () { + if (pe_dll_extra_pe_debug) + { + bfd *a; + struct bfd_link_hash_entry *sym; + + printf ("%s()\n", __FUNCTION__); + + for (sym = link_info.hash->undefs; sym; sym=sym->next) + printf ("-%s\n", sym->root.string); + bfd_hash_traverse (&link_info.hash->table, pr_sym,NULL); + + for (a = link_info.input_bfds; a; a = a->link_next) + printf ("*%s\n",a->filename); + } + /* Pass the wacky PE command line options into the output bfd. FIXME: This should be done via a function, rather than by including an internal BFD header. */ - - if (!coff_data (output_bfd)->pe) + + if (coff_data (output_bfd) == NULL || coff_data (output_bfd)->pe == 0) einfo (_("%F%P: PE operations on non PE file.\n")); pe_data (output_bfd)->pe_opthdr = pe; @@ -795,8 +1015,15 @@ gld_${EMULATION_NAME}_after_open () if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */ pe_fixup_stdcalls (); - pe_process_import_defs(output_bfd, &link_info); + pe_process_import_defs (output_bfd, & link_info); + + pe_find_data_imports (); + +#if ! (defined (TARGET_IS_i386pe) || defined (TARGET_IS_armpe)) if (link_info.shared) +#else + if (!link_info.relocateable) +#endif pe_dll_build_sections (output_bfd, &link_info); #ifndef TARGET_IS_i386pe @@ -836,7 +1063,7 @@ gld_${EMULATION_NAME}_after_open () head/tail objects, causing an improper import table. We detect those cases and rename the "other" import libraries to match the one the head/tail come from, so that the linker will sort - things nicely and produce a valid import table. */ + things nicely and produce a valid import table. */ LANG_FOR_EACH_INPUT_STATEMENT (is) { @@ -844,7 +1071,7 @@ gld_${EMULATION_NAME}_after_open () { int idata2 = 0, reloc_count=0, is_imp = 0; asection *sec; - + /* See if this is an import library thunk. */ for (sec = is->the_bfd->sections; sec; sec = sec->next) { @@ -854,7 +1081,7 @@ gld_${EMULATION_NAME}_after_open () is_imp = 1; reloc_count += sec->reloc_count; } - + if (is_imp && !idata2 && reloc_count) { /* It is, look for the reference to head and see if it's @@ -867,22 +1094,22 @@ gld_${EMULATION_NAME}_after_open () asymbol **symbols; arelent **relocs; int nrelocs; - + symsize = bfd_get_symtab_upper_bound (is->the_bfd); if (symsize < 1) break; relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec); if (relsize < 1) break; - + symbols = (asymbol **) xmalloc (symsize); - symsize = bfd_canonicalize_symtab (is->the_bfd, symbols); + symsize = bfd_canonicalize_symtab (is->the_bfd, symbols); if (symsize < 0) { einfo ("%X%P: unable to process symbols: %E"); return; } - + relocs = (arelent **) xmalloc ((size_t) relsize); nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec, relocs, symbols); @@ -892,39 +1119,39 @@ gld_${EMULATION_NAME}_after_open () einfo ("%X%P: unable to process relocs: %E"); return; } - + for (i = 0; i < nrelocs; i++) { struct symbol_cache_entry *s; struct bfd_link_hash_entry * blhe; bfd *other_bfd; char *n; - + s = (relocs[i]->sym_ptr_ptr)[0]; - + if (s->flags & BSF_LOCAL) continue; - + /* Thunk section with reloc to another bfd. */ blhe = bfd_link_hash_lookup (link_info.hash, s->name, - false, false, true); - + FALSE, FALSE, TRUE); + if (blhe == NULL || blhe->type != bfd_link_hash_defined) continue; - + other_bfd = blhe->u.def.section->owner; - + if (strcmp (is->the_bfd->my_archive->filename, other_bfd->my_archive->filename) == 0) continue; - + /* Rename this implib to match the other. */ n = (char *) xmalloc (strlen (other_bfd->my_archive->filename) + 1); - + strcpy (n, other_bfd->my_archive->filename); - + is->the_bfd->my_archive->filename = n; } @@ -1002,11 +1229,11 @@ gld_${EMULATION_NAME}_after_open () } } -static void -gld_${EMULATION_NAME}_before_allocation() +static void +gld_${EMULATION_NAME}_before_allocation () { #ifdef TARGET_IS_ppcpe - /* Here we rummage through the found bfds to collect toc information */ + /* Here we rummage through the found bfds to collect toc information. */ { LANG_FOR_EACH_INPUT_STATEMENT (is) { @@ -1018,7 +1245,7 @@ gld_${EMULATION_NAME}_before_allocation() } } - /* We have seen it all. Allocate it, and carry on */ + /* We have seen it all. Allocate it, and carry on. */ ppc_allocate_toc_section (&link_info); #endif /* TARGET_IS_ppcpe */ @@ -1028,7 +1255,7 @@ gld_${EMULATION_NAME}_before_allocation() Here we rummage through the found bfds to collect glue information. FIXME: should this be based on a command line - option? krk@cygnus.com */ + option? krk@cygnus.com. */ { LANG_FOR_EACH_INPUT_STATEMENT (is) { @@ -1042,113 +1269,119 @@ gld_${EMULATION_NAME}_before_allocation() } } - /* We have seen it all. Allocate it, and carry on */ + /* We have seen it all. Allocate it, and carry on. */ bfd_arm_pe_allocate_interworking_sections (& link_info); #endif /* TARGET_IS_armpe */ } #ifdef DLL_SUPPORT /* This is called when an input file isn't recognized as a BFD. We - check here for .DEF files and pull them in automatically. */ + check here for .DEF files and pull them in automatically. */ static int -saw_option(char *option) +saw_option (char * option) { int i; - for (i=0; init[i].ptr; i++) + + for (i = 0; init[i].ptr; i++) if (strcmp (init[i].symbol, option) == 0) return init[i].inited; return 0; } #endif /* DLL_SUPPORT */ -static boolean -gld_${EMULATION_NAME}_unrecognized_file(entry) +static bfd_boolean +gld_${EMULATION_NAME}_unrecognized_file (entry) lang_input_statement_type *entry ATTRIBUTE_UNUSED; { #ifdef DLL_SUPPORT const char *ext = entry->filename + strlen (entry->filename) - 4; if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0) - { - if (pe_def_file == 0) - pe_def_file = def_file_empty (); - def_file_parse (entry->filename, pe_def_file); - if (pe_def_file) { - int i, buflen=0, len; - char *buf; - for (i=0; i<pe_def_file->num_exports; i++) - { - len = strlen(pe_def_file->exports[i].internal_name); - if (buflen < len+2) - buflen = len+2; - } - buf = (char *) xmalloc (buflen); - for (i=0; i<pe_def_file->num_exports; i++) + if (pe_def_file == 0) + pe_def_file = def_file_empty (); + + def_file_parse (entry->filename, pe_def_file); + + if (pe_def_file) { - struct bfd_link_hash_entry *h; - sprintf(buf, "_%s", pe_def_file->exports[i].internal_name); + int i, buflen=0, len; + char *buf; - h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true); - if (h == (struct bfd_link_hash_entry *) NULL) - einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); - if (h->type == bfd_link_hash_new) + for (i = 0; i < pe_def_file->num_exports; i++) { - h->type = bfd_link_hash_undefined; - h->u.undef.abfd = NULL; - bfd_link_add_undef (link_info.hash, h); + len = strlen (pe_def_file->exports[i].internal_name); + if (buflen < len + 2) + buflen = len + 2; } - } - free (buf); - /* def_file_print (stdout, pe_def_file); */ - if (pe_def_file->is_dll == 1) - link_info.shared = 1; + buf = (char *) xmalloc (buflen); - if (pe_def_file->base_address != (bfd_vma)(-1)) - { - pe.ImageBase = - pe_data (output_bfd)->pe_opthdr.ImageBase = - init[IMAGEBASEOFF].value = pe_def_file->base_address; - init[IMAGEBASEOFF].inited = 1; - if (image_base_statement) - image_base_statement->exp = - exp_assop ('=', "__image_base__", exp_intop (pe.ImageBase)); - } + for (i = 0; i < pe_def_file->num_exports; i++) + { + struct bfd_link_hash_entry *h; + + sprintf (buf, "_%s", pe_def_file->exports[i].internal_name); + + h = bfd_link_hash_lookup (link_info.hash, buf, TRUE, TRUE, TRUE); + if (h == (struct bfd_link_hash_entry *) NULL) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + if (h->type == bfd_link_hash_new) + { + h->type = bfd_link_hash_undefined; + h->u.undef.abfd = NULL; + bfd_link_add_undef (link_info.hash, h); + } + } + free (buf); + + /* def_file_print (stdout, pe_def_file); */ + if (pe_def_file->is_dll == 1) + link_info.shared = 1; + + if (pe_def_file->base_address != (bfd_vma)(-1)) + { + pe.ImageBase = + pe_data (output_bfd)->pe_opthdr.ImageBase = + init[IMAGEBASEOFF].value = pe_def_file->base_address; + init[IMAGEBASEOFF].inited = 1; + if (image_base_statement) + image_base_statement->exp = + exp_assop ('=', "__image_base__", exp_intop (pe.ImageBase)); + } #if 0 - /* Not sure if these *should* be set */ - if (pe_def_file->version_major != -1) - { - pe.MajorImageVersion = pe_def_file->version_major; - pe.MinorImageVersion = pe_def_file->version_minor; - } + /* Not sure if these *should* be set. */ + if (pe_def_file->version_major != -1) + { + pe.MajorImageVersion = pe_def_file->version_major; + pe.MinorImageVersion = pe_def_file->version_minor; + } #endif - if (pe_def_file->stack_reserve != -1 - && ! saw_option ("__size_of_stack_reserve__")) - { - pe.SizeOfStackReserve = pe_def_file->stack_reserve; - if (pe_def_file->stack_commit != -1) - pe.SizeOfStackCommit = pe_def_file->stack_commit; - } - if (pe_def_file->heap_reserve != -1 - && ! saw_option ("__size_of_heap_reserve__")) - { - pe.SizeOfHeapReserve = pe_def_file->heap_reserve; - if (pe_def_file->heap_commit != -1) - pe.SizeOfHeapCommit = pe_def_file->heap_commit; - } - return true; + if (pe_def_file->stack_reserve != -1 + && ! saw_option ("__size_of_stack_reserve__")) + { + pe.SizeOfStackReserve = pe_def_file->stack_reserve; + if (pe_def_file->stack_commit != -1) + pe.SizeOfStackCommit = pe_def_file->stack_commit; + } + if (pe_def_file->heap_reserve != -1 + && ! saw_option ("__size_of_heap_reserve__")) + { + pe.SizeOfHeapReserve = pe_def_file->heap_reserve; + if (pe_def_file->heap_commit != -1) + pe.SizeOfHeapCommit = pe_def_file->heap_commit; + } + return TRUE; + } } - } #endif - return false; - + return FALSE; } -static boolean -gld_${EMULATION_NAME}_recognized_file(entry) +static bfd_boolean +gld_${EMULATION_NAME}_recognized_file (entry) lang_input_statement_type *entry ATTRIBUTE_UNUSED; { #ifdef DLL_SUPPORT @@ -1166,12 +1399,19 @@ gld_${EMULATION_NAME}_recognized_file(entry) #endif if (bfd_get_format (entry->the_bfd) == bfd_object) { - const char *ext = entry->filename + strlen (entry->filename) - 4; + char fbuf[LD_PATHMAX + 1]; + const char *ext; + + if (REALPATH (entry->filename, fbuf) == NULL) + strncpy (fbuf, entry->filename, sizeof (fbuf)); + + ext = fbuf + strlen (fbuf) - 4; + if (strcmp (ext, ".dll") == 0 || strcmp (ext, ".DLL") == 0) - return pe_implied_import_dll (entry->filename); + return pe_implied_import_dll (fbuf); } #endif - return false; + return FALSE; } static void @@ -1182,8 +1422,9 @@ gld_${EMULATION_NAME}_finish () if (thumb_entry_symbol != NULL) { - h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, false, false, true); - + h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, + FALSE, FALSE, TRUE); + if (h != (struct bfd_link_hash_entry *) NULL && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak) @@ -1191,27 +1432,27 @@ gld_${EMULATION_NAME}_finish () { static char buffer[32]; bfd_vma val; - + /* Special procesing is required for a Thumb entry symbol. The bottom bit of its address must be set. */ val = (h->u.def.value + bfd_get_section_vma (output_bfd, h->u.def.section->output_section) + h->u.def.section->output_offset); - + val |= 1; - + /* Now convert this value into a string and store it in entry_symbol where the lang_finish() function will pick it up. */ buffer[0] = '0'; buffer[1] = 'x'; - + sprintf_vma (buffer + 2, val); - - if (entry_symbol != NULL && entry_from_cmdline) + + if (entry_symbol.name != NULL && entry_from_cmdline) einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"), - thumb_entry_symbol, entry_symbol); - entry_symbol = buffer; + thumb_entry_symbol, entry_symbol.name); + entry_symbol.name = buffer; } else einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol); @@ -1219,7 +1460,11 @@ gld_${EMULATION_NAME}_finish () #endif /* defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe) */ #ifdef DLL_SUPPORT - if (link_info.shared) + if (link_info.shared +#if !defined(TARGET_IS_shpe) && !defined(TARGET_IS_mipspe) + || (!link_info.relocateable && pe_def_file->num_exports != 0) +#endif + ) { pe_dll_fill_sections (output_bfd, &link_info); if (pe_implib_filename) @@ -1232,13 +1477,50 @@ gld_${EMULATION_NAME}_finish () pe_exe_fill_sections (output_bfd, &link_info); } #endif - + if (pe_out_def_filename) pe_dll_generate_def_file (pe_out_def_filename); #endif /* DLL_SUPPORT */ + + /* I don't know where .idata gets set as code, but it shouldn't be. */ + { + asection *asec = bfd_get_section_by_name (output_bfd, ".idata"); + + if (asec) + { + asec->flags &= ~SEC_CODE; + asec->flags |= SEC_DATA; + } + } } +/* Find the last output section before given output statement. + Used by place_orphan. */ + +static asection * +output_prev_sec_find (os) + lang_output_section_statement_type *os; +{ + asection *s = (asection *) NULL; + lang_statement_union_type *u; + lang_output_section_statement_type *lookup; + + for (u = lang_output_section_statement.head; + u != (lang_statement_union_type *) NULL; + u = lookup->next) + { + lookup = &u->output_section_statement; + if (lookup == os) + return s; + + if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL) + s = lookup->bfd_section; + } + + return NULL; +} + /* Place an orphan section. We use this to put sections in a reasonable place in the file, and @@ -1259,8 +1541,7 @@ struct orphan_save lang_statement_union_type **stmt; }; -/*ARGSUSED*/ -static boolean +static bfd_boolean gld_${EMULATION_NAME}_place_orphan (file, s) lang_input_statement_type *file; asection *s; @@ -1275,7 +1556,6 @@ gld_${EMULATION_NAME}_place_orphan (file, s) secname = bfd_get_section_name (s->owner, s); /* Look through the script to see where to place this section. */ - hold_section_name = xstrdup (secname); if (!link_info.relocateable) { @@ -1289,10 +1569,13 @@ gld_${EMULATION_NAME}_place_orphan (file, s) lang_list_init (&add_child); if (os != NULL - && os->bfd_section != NULL - && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0) + && (os->bfd_section == NULL + || ((s->flags ^ os->bfd_section->flags) + & (SEC_LOAD | SEC_ALLOC)) == 0)) { - wild_doit (&add_child, s, os, file); + /* We already have an output section statement with this + name, and its bfd section, if any, has compatible flags. */ + lang_add_section (&add_child, s, os, file); } else { @@ -1332,7 +1615,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s) /* Choose a unique name for the section. This will be needed if the same section name appears in the input file with - different loadable or allocateable characteristics. */ + different loadable or allocatable characteristics. */ outsecname = xstrdup (hold_section_name); if (bfd_get_section_by_name (output_bfd, outsecname) != NULL) { @@ -1371,7 +1654,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s) { char *symname; etree_type *e_align; - + symname = (char *) xmalloc (ps - outsecname + sizeof "___start_"); sprintf (symname, "___start_%s", outsecname); e_align = exp_unop (ALIGN_K, @@ -1379,7 +1662,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s) lang_add_assignment (exp_assop ('=', symname, e_align)); } } - + if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) address = exp_intop ((bfd_vma) 0); else @@ -1396,21 +1679,21 @@ gld_${EMULATION_NAME}_place_orphan (file, s) (etree_type *) NULL, (etree_type *) NULL); - wild_doit (&add_child, s, os, file); + lang_add_section (&add_child, s, os, file); lang_leave_output_section_statement ((bfd_vma) 0, "*default*", - (struct lang_output_section_phdr_list *) NULL, "*default*"); + (struct lang_output_section_phdr_list *) NULL, NULL); if (config.build_constructors && *ps == '\0') { char *symname; - /* lang_leave_ouput_section_statement resets stat_ptr. Put - stat_ptr back where we want it. */ + /* lang_leave_ouput_section_statement resets stat_ptr. + Put stat_ptr back where we want it. */ if (place != NULL) stat_ptr = &add; - + symname = (char *) xmalloc (ps - outsecname + sizeof "___stop_"); sprintf (symname, "___stop_%s", outsecname); lang_add_assignment (exp_assop ('=', symname, @@ -1419,55 +1702,78 @@ gld_${EMULATION_NAME}_place_orphan (file, s) stat_ptr = old; - if (place != NULL) + if (place != NULL && os->bfd_section != NULL) { asection *snew, **pps; snew = os->bfd_section; - if (place->os->bfd_section != NULL || place->section != NULL) + + /* Shuffle the bfd section list to make the output file look + neater. This is really only cosmetic. */ + if (place->section == NULL) { - /* Shuffle the section to make the output file look neater. */ - if (place->section == NULL) - { -#if 0 - /* Finding the end of the list is a little tricky. We - make a wild stab at it by comparing section flags. */ - flagword first_flags = place->os->bfd_section->flags; - for (pps = &place->os->bfd_section->next; - *pps != NULL && (*pps)->flags == first_flags; - pps = &(*pps)->next) - ; - place->section = pps; -#else - /* Put orphans after the first section on the list. */ - place->section = &place->os->bfd_section->next; -#endif - } + asection *bfd_section = place->os->bfd_section; - /* Unlink the section. */ - for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next) - ; - *pps = snew->next; + /* If the output statement hasn't been used to place + any input sections (and thus doesn't have an output + bfd_section), look for the closest prior output statement + having an output section. */ + if (bfd_section == NULL) + bfd_section = output_prev_sec_find (place->os); - /* Now tack it on to the "place->os" section list. */ - snew->next = *place->section; - *place->section = snew; + if (bfd_section != NULL && bfd_section != snew) + place->section = &bfd_section->next; } - place->section = &snew->next; /* Save the end of this list. */ - if (place->stmt == NULL) + if (place->section != NULL) { - /* Put the new statement list right at the head. */ - *add.tail = place->os->header.next; - place->os->header.next = add.head; + /* Unlink the section. */ + for (pps = &output_bfd->sections; + *pps != snew; + pps = &(*pps)->next) + ; + bfd_section_list_remove (output_bfd, pps); + + /* Now tack it on to the "place->os" section list. */ + bfd_section_list_insert (output_bfd, place->section, snew); } - else + + /* Save the end of this list. Further ophans of this type will + follow the one we've just added. */ + place->section = &snew->next; + + /* The following is non-cosmetic. We try to put the output + statements in some sort of reasonable order here, because + they determine the final load addresses of the orphan + sections. In addition, placing output statements in the + wrong order may require extra segments. For instance, + given a typical situation of all read-only sections placed + in one segment and following that a segment containing all + the read-write sections, we wouldn't want to place an orphan + read/write section before or amongst the read-only ones. */ + if (add.head != NULL) { - /* Put it after the last orphan statement we added. */ - *add.tail = *place->stmt; - *place->stmt = add.head; + if (place->stmt == NULL) + { + /* Put the new statement list right at the head. */ + *add.tail = place->os->header.next; + place->os->header.next = add.head; + } + else + { + /* Put it after the last orphan statement we added. */ + *add.tail = *place->stmt; + *place->stmt = add.head; + } + + /* Fix the global list pointer if we happened to tack our + new list at the tail. */ + if (*old->tail == add.head) + old->tail = add.tail; + + /* Save the end of this list. */ + place->stmt = add.tail; } - place->stmt = add.tail; /* Save the end of this list. */ } } @@ -1476,13 +1782,12 @@ gld_${EMULATION_NAME}_place_orphan (file, s) if (dollar != NULL) { - boolean found_dollar; + bfd_boolean found_dollar; /* The section name has a '$'. Sort it with the other '$' sections. */ - - found_dollar = false; - for ( ; *pl != NULL; pl = &(*pl)->next) + found_dollar = FALSE; + for ( ; *pl != NULL; pl = &(*pl)->header.next) { lang_input_section_type *ls; const char *lname; @@ -1500,7 +1805,7 @@ gld_${EMULATION_NAME}_place_orphan (file, s) } else { - found_dollar = true; + found_dollar = TRUE; if (strcmp (secname, lname) < 0) break; } @@ -1509,17 +1814,17 @@ gld_${EMULATION_NAME}_place_orphan (file, s) if (add_child.head != NULL) { - add_child.head->next = *pl; + add_child.head->header.next = *pl; *pl = add_child.head; } } free (hold_section_name); - return true; + return TRUE; } -static boolean +static bfd_boolean gld_${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) const char * arch ATTRIBUTE_UNUSED; search_dirs_type * search; @@ -1529,77 +1834,75 @@ gld_${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) char * string; if (! entry->is_archive) - return false; + return FALSE; filename = entry->filename; string = (char *) xmalloc (strlen (search->name) - + strlen (filename) + + strlen (filename) + sizeof "/lib.a.dll" #ifdef DLL_SUPPORT + (pe_dll_search_prefix ? strlen (pe_dll_search_prefix) : 0) #endif + 1); - /* Try "libfoo.dll.a" first (preferred explicit import library for dll's */ + /* Try "libfoo.dll.a" first (preferred explicit import library for dll's. */ sprintf (string, "%s/lib%s.dll.a", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { - /* Try "foo.dll.a" next (alternate explicit import library for dll's */ + /* Try "foo.dll.a" next (alternate explicit import library for dll's. */ sprintf (string, "%s/%s.dll.a", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { -/* - Try libfoo.a next. Normally, this would be interpreted as a static - library, but it *could* be an import library. For backwards compatibility, - libfoo.a needs to ==precede== libfoo.dll and foo.dll in the search, - or sometimes errors occur when building legacy packages. - - Putting libfoo.a here means that in a failure case (i.e. the library - -lfoo is not found) we will search for libfoo.a twice before - giving up -- once here, and once when searching for a "static" lib. - for a "static" lib. -*/ + /* Try libfoo.a next. Normally, this would be interpreted as a static + library, but it *could* be an import library. For backwards compatibility, + libfoo.a needs to ==precede== libfoo.dll and foo.dll in the search, + or sometimes errors occur when building legacy packages. + + Putting libfoo.a here means that in a failure case (i.e. the library + -lfoo is not found) we will search for libfoo.a twice before + giving up -- once here, and once when searching for a "static" lib. + for a "static" lib. */ /* Try "libfoo.a" (import lib, or static lib, but must - take precedence over dll's) */ + take precedence over dll's). */ sprintf (string, "%s/lib%s.a", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { #ifdef DLL_SUPPORT if (pe_dll_search_prefix) - { - /* Try "<prefix>foo.dll" (preferred dll name, if specified) */ + { + /* Try "<prefix>foo.dll" (preferred dll name, if specified). */ sprintf (string, "%s/%s%s.dll", search->name, pe_dll_search_prefix, filename); if (! ldfile_try_open_bfd (string, entry)) { - /* Try "libfoo.dll" (default preferred dll name) */ + /* Try "libfoo.dll" (default preferred dll name). */ sprintf (string, "%s/lib%s.dll", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { - /* Finally, try "foo.dll" (alternate dll name) */ + /* Finally, try "foo.dll" (alternate dll name). */ sprintf (string, "%s/%s.dll", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { free (string); - return false; + return FALSE; } } } } - else /* pe_dll_search_prefix not specified */ -#endif + else /* pe_dll_search_prefix not specified. */ +#endif { - /* Try "libfoo.dll" (preferred dll name) */ + /* Try "libfoo.dll" (preferred dll name). */ sprintf (string, "%s/lib%s.dll", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { - /* Finally, try "foo.dll" (alternate dll name) */ + /* Finally, try "foo.dll" (alternate dll name). */ sprintf (string, "%s/%s.dll", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { free (string); - return false; + return FALSE; } } } @@ -1609,7 +1912,7 @@ gld_${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) entry->filename = string; - return true; + return TRUE; } static int @@ -1621,7 +1924,7 @@ gld_${EMULATION_NAME}_find_potential_libraries (name, entry) } static char * -gld_${EMULATION_NAME}_get_script(isfile) +gld_${EMULATION_NAME}_get_script (isfile) int *isfile; EOF # Scripts compiled in. @@ -1629,27 +1932,27 @@ EOF sc="-f stringify.sed" cat >>e${EMULATION_NAME}.c <<EOF -{ +{ *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF -sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c -echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c +echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c cat >>e${EMULATION_NAME}.c <<EOF -struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { gld_${EMULATION_NAME}_before_parse, syslib_default, @@ -1663,15 +1966,18 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", - gld_${EMULATION_NAME}_finish, /* finish */ - NULL, /* create output section statements */ + gld_${EMULATION_NAME}_finish, + NULL, /* Create output section statements. */ gld_${EMULATION_NAME}_open_dynamic_archive, gld_${EMULATION_NAME}_place_orphan, gld_${EMULATION_NAME}_set_symbols, - gld_${EMULATION_NAME}_parse_args, + NULL, /* parse_args */ + gld${EMULATION_NAME}_add_options, + gld${EMULATION_NAME}_handle_option, gld_${EMULATION_NAME}_unrecognized_file, gld_${EMULATION_NAME}_list_options, gld_${EMULATION_NAME}_recognized_file, - gld_${EMULATION_NAME}_find_potential_libraries + gld_${EMULATION_NAME}_find_potential_libraries, + NULL /* new_vers_pattern. */ }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/sunos.em b/gnu/usr.bin/binutils/ld/emultempl/sunos.em index c98d87e1f76..8cabe3a0a2a 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/sunos.em +++ b/gnu/usr.bin/binutils/ld/emultempl/sunos.em @@ -1,10 +1,15 @@ # This shell script emits a C file. -*- C -*- # It does some substitutions. +if [ -z "$MACHINE" ]; then + OUTPUT_ARCH=${ARCH} +else + OUTPUT_ARCH=${ARCH}:${MACHINE} +fi cat >e${EMULATION_NAME}.c <<EOF /* This file is is generated by a shell script. DO NOT EDIT! */ /* SunOS emulation code for ${EMULATION_NAME} - Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. Written by Steve Chamberlain <sac@cygnus.com> SunOS shared library support by Ian Lance Taylor <ian@cygnus.com> @@ -27,12 +32,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define TARGET_IS_${EMULATION_NAME} -#include <ctype.h> - #include "bfd.h" #include "sysdep.h" #include "bfdlink.h" #include "libiberty.h" +#include "safe-ctype.h" #include "ld.h" #include "ldmain.h" @@ -64,13 +68,13 @@ static void gld${EMULATION_NAME}_create_output_section_statements static void gld${EMULATION_NAME}_find_so PARAMS ((lang_input_statement_type *)); static char *gld${EMULATION_NAME}_search_dir - PARAMS ((const char *, const char *, boolean *)); + PARAMS ((const char *, const char *, bfd_boolean *)); static void gld${EMULATION_NAME}_after_open PARAMS ((void)); static void gld${EMULATION_NAME}_check_needed PARAMS ((lang_input_statement_type *)); -static boolean gld${EMULATION_NAME}_search_needed +static bfd_boolean gld${EMULATION_NAME}_search_needed PARAMS ((const char *, const char *)); -static boolean gld${EMULATION_NAME}_try_needed +static bfd_boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, const char *)); static void gld${EMULATION_NAME}_before_allocation PARAMS ((void)); static void gld${EMULATION_NAME}_find_assignment @@ -85,9 +89,17 @@ static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); static void gld${EMULATION_NAME}_before_parse() { - ldfile_output_architecture = bfd_arch_${ARCH}; - config.dynamic_link = true; - config.has_shared = true; + const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}"); + if (arch) + { + ldfile_output_architecture = arch->arch; + ldfile_output_machine = arch->mach; + ldfile_output_machine_name = arch->printable_name; + } + else + ldfile_output_architecture = bfd_arch_${ARCH}; + config.dynamic_link = TRUE; + config.has_shared = TRUE; } /* This is called after the command line arguments have been parsed, @@ -119,7 +131,7 @@ cat >>e${EMULATION_NAME}.c <<EOF if (c != NULL) *c++ = '\0'; if (*l != '\0') - ldfile_add_library_path (l, false); + ldfile_add_library_path (l, FALSE); if (c == NULL) break; l = c; @@ -167,7 +179,7 @@ gld${EMULATION_NAME}_find_so (inp) for (search = search_head; search != NULL; search = search->next) { - boolean found_static; + bfd_boolean found_static; found = gld${EMULATION_NAME}_search_dir (search->name, inp->filename, &found_static); @@ -190,7 +202,7 @@ gld${EMULATION_NAME}_find_so (inp) /* Turn off the search_dirs_flag to prevent ldfile_open_file from searching for this file again. */ - inp->search_dirs_flag = false; + inp->search_dirs_flag = FALSE; free (found); @@ -225,7 +237,7 @@ static char * gld${EMULATION_NAME}_search_dir (dirname, filename, found_static) const char *dirname; const char *filename; - boolean *found_static; + bfd_boolean *found_static; { int force_maj, force_min; const char *dot; @@ -240,7 +252,7 @@ gld${EMULATION_NAME}_search_dir (dirname, filename, found_static) int statval; struct stat st; - *found_static = false; + *found_static = FALSE; force_maj = -1; force_min = -1; @@ -272,7 +284,7 @@ gld${EMULATION_NAME}_search_dir (dirname, filename, found_static) if (dir == NULL) return NULL; dirnamelen = strlen (dirname); - + while ((entry = readdir (dir)) != NULL) { const char *s; @@ -285,7 +297,7 @@ gld${EMULATION_NAME}_search_dir (dirname, filename, found_static) if (dot == NULL && strcmp (entry->d_name + 3 + len, ".a") == 0) { - *found_static = true; + *found_static = TRUE; continue; } @@ -298,13 +310,13 @@ gld${EMULATION_NAME}_search_dir (dirname, filename, found_static) if (entry->d_name[6 + len] == '\0') ; else if (entry->d_name[6 + len] == '.' - && isdigit ((unsigned char) entry->d_name[7 + len])) + && ISDIGIT (entry->d_name[7 + len])) ; else continue; for (s = entry->d_name + 6 + len; *s != '\0'; s++) - if (*s != '.' && ! isdigit ((unsigned char) *s)) + if (*s != '.' && ! ISDIGIT (*s)) break; if (*s != '\0') continue; @@ -361,7 +373,7 @@ gld${EMULATION_NAME}_search_dir (dirname, filename, found_static) between after_open and check_needed. */ static struct bfd_link_needed_list *global_needed; -static boolean global_found; +static bfd_boolean global_found; /* This is called after all the input files have been opened. */ @@ -400,7 +412,7 @@ gld${EMULATION_NAME}_after_open () /* See if this file was included in the link explicitly. */ global_needed = l; - global_found = false; + global_found = FALSE; lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); if (global_found) continue; @@ -501,7 +513,7 @@ cat >>e${EMULATION_NAME}.c <<EOF /* Search for a needed file in a path. */ -static boolean +static bfd_boolean gld${EMULATION_NAME}_search_needed (path, name) const char *path; const char *name; @@ -509,7 +521,7 @@ gld${EMULATION_NAME}_search_needed (path, name) const char *s; if (path == NULL || *path == '\0') - return false; + return FALSE; while (1) { const char *dir; @@ -530,7 +542,7 @@ gld${EMULATION_NAME}_search_needed (path, name) } if (gld${EMULATION_NAME}_try_needed (dir, name)) - return true; + return TRUE; if (dircopy != NULL) free (dircopy); @@ -540,41 +552,41 @@ gld${EMULATION_NAME}_search_needed (path, name) path = s + 1; } - return false; + return FALSE; } /* This function is called for each possible directory for a needed dynamic object. */ -static boolean +static bfd_boolean gld${EMULATION_NAME}_try_needed (dir, name) const char *dir; const char *name; { char *file; char *alc; - boolean ignore; + bfd_boolean ignore; bfd *abfd; file = gld${EMULATION_NAME}_search_dir (dir, name, &ignore); if (file == NULL) - return false; + return FALSE; alc = (char *) xmalloc (strlen (dir) + strlen (file) + 2); sprintf (alc, "%s/%s", dir, file); free (file); abfd = bfd_openr (alc, bfd_get_target (output_bfd)); if (abfd == NULL) - return false; + return FALSE; if (! bfd_check_format (abfd, bfd_object)) { (void) bfd_close (abfd); - return false; + return FALSE; } if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) { (void) bfd_close (abfd); - return false; + return FALSE; } /* We've found the needed dynamic object. */ @@ -583,7 +595,7 @@ gld${EMULATION_NAME}_try_needed (dir, name) if (! bfd_link_add_symbols (abfd, &link_info)) einfo ("%F%B: could not read symbols: %E\n", abfd); - return true; + return TRUE; } /* See if we have already included a needed object in the link. This @@ -599,7 +611,7 @@ gld${EMULATION_NAME}_check_needed (s) if (strncmp (global_needed->name, "-l", 2) != 0) { if (strcmp (s->filename, global_needed->name) == 0) - global_found = true; + global_found = TRUE; } else { @@ -639,7 +651,7 @@ gld${EMULATION_NAME}_check_needed (s) || (smin != lmin && smin != -1 && lmin != -1)) return; - global_found = true; + global_found = TRUE; } } @@ -647,7 +659,7 @@ gld${EMULATION_NAME}_check_needed (s) to lang_for_each_statement. Ick. */ static const char *find_assign; -static boolean found_assign; +static bfd_boolean found_assign; /* We need to use static variables to pass information around the call to lang_for_each_input_file. Ick. */ @@ -680,7 +692,7 @@ gld${EMULATION_NAME}_before_allocation () if (! link_info.shared && ! link_info.relocateable && ! entry_from_cmdline) { struct bfd_link_hash_entry *h; - + for (h = link_info.hash->undefs; h != NULL; h = h->next) { if (h->type == bfd_link_hash_undefined @@ -690,11 +702,11 @@ gld${EMULATION_NAME}_before_allocation () && strcmp (h->root.string, "__GLOBAL_OFFSET_TABLE_") != 0) { find_assign = h->root.string; - found_assign = false; + found_assign = FALSE; lang_for_each_statement (gld${EMULATION_NAME}_find_assignment); if (! found_assign) { - link_info.shared = true; + link_info.shared = TRUE; break; } } @@ -720,8 +732,8 @@ gld${EMULATION_NAME}_before_allocation () afterward. */ if (! link_info.relocateable) { - hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", true, false, - false); + hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", TRUE, FALSE, + FALSE); if (hdyn == NULL) einfo ("%P%F: bfd_link_hash_lookup: %E\n"); if (! bfd_sunos_record_link_assignment (output_bfd, &link_info, @@ -850,7 +862,7 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) if (find_assign != NULL) { if (strcmp (find_assign, exp->assign.dst) == 0) - found_assign = true; + found_assign = TRUE; return; } @@ -974,14 +986,14 @@ then sc="-f stringify.sed" cat >>e${EMULATION_NAME}.c <<EOF -{ +{ *isfile = 0; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return EOF sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c @@ -995,12 +1007,12 @@ else # Scripts read from the filesystem. cat >>e${EMULATION_NAME}.c <<EOF -{ +{ *isfile = 1; - if (link_info.relocateable == true && config.build_constructors == true) + if (link_info.relocateable && config.build_constructors) return "ldscripts/${EMULATION_NAME}.xu"; - else if (link_info.relocateable == true) + else if (link_info.relocateable) return "ldscripts/${EMULATION_NAME}.xr"; else if (!config.text_read_only) return "ldscripts/${EMULATION_NAME}.xbn"; @@ -1015,7 +1027,7 @@ fi cat >>e${EMULATION_NAME}.c <<EOF -struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = +struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { gld${EMULATION_NAME}_before_parse, syslib_default, @@ -1035,9 +1047,12 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = NULL, /* place orphan */ gld${EMULATION_NAME}_set_symbols, NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ - NULL /* find_potential_libraries */ + NULL, /* find_potential_libraries */ + NULL /* new_vers_pattern */ }; EOF diff --git a/gnu/usr.bin/binutils/ld/emultempl/vanilla.em b/gnu/usr.bin/binutils/ld/emultempl/vanilla.em index 3e6aed92e39..8d4f6d4d32d 100644 --- a/gnu/usr.bin/binutils/ld/emultempl/vanilla.em +++ b/gnu/usr.bin/binutils/ld/emultempl/vanilla.em @@ -2,7 +2,8 @@ # It does some substitutions. cat >e${EMULATION_NAME}.c <<EOF /* A vanilla emulation with no defaults - Copyright 1991, 1992, 1994, 2000 Free Software Foundation, Inc. + Copyright 1991, 1992, 1994, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. Written by Steve Chamberlain steve@cygnus.com This file is part of GLD, the Gnu Linker. @@ -34,6 +35,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ldfile.h" #include "ldemul.h" +static void vanilla_before_parse PARAMS ((void)); +static void vanilla_set_output_arch PARAMS ((void)); +static char *vanilla_get_script PARAMS ((int *)); + + static void vanilla_before_parse() { } @@ -74,9 +80,12 @@ struct ld_emulation_xfer_struct ld_vanilla_emulation = NULL, /* place orphan */ NULL, /* set symbols */ NULL, /* parse args */ + NULL, /* add_options */ + NULL, /* handle_option */ NULL, /* unrecognized file */ NULL, /* list options */ NULL, /* recognized file */ - NULL /* find_potential_libraries */ + NULL, /* find_potential_libraries */ + NULL /* new_vers_pattern */ }; EOF |