X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Femultempl%2Faix.em;h=463cf17955b93e17627630a841a781960e249bb6;hb=837a17b36c9e297f4bf33727e25dfa9f38360c17;hp=ad4c6dc963ce6f53878a3c294cab6aec4cb73d86;hpb=1049f94e8e1a9eae86a694d2dca94a6194f763b1;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index ad4c6dc963..463cf17955 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -5,36 +5,36 @@ if [ -z "$MACHINE" ]; then else OUTPUT_ARCH=${ARCH}:${MACHINE} fi -cat >e${EMULATION_NAME}.c < AIX support by Ian Lance Taylor AIX 64 bit support by Tom Rix -This file is part of GLD, the Gnu Linker. + This file is part of the GNU Binutils. -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 3 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., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #define TARGET_IS_${EMULATION_NAME} -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libiberty.h" #include "safe-ctype.h" #include "getopt.h" @@ -56,40 +56,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #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 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 *)); +static void gld${EMULATION_NAME}_read_file (const char *, bfd_boolean); +static void gld${EMULATION_NAME}_free (void *); +static void gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *); +static void gld${EMULATION_NAME}_find_exp_assignment (etree_type *); + /* The file alignment required for each section. */ static unsigned long file_align; @@ -111,6 +82,14 @@ static unsigned short modtype = ('1' << 8) | 'L'; permitted). */ static int textro; +/* A mask of XCOFF_EXPALL and XCOFF_EXPFULL flags, as set by their + associated -b and -bno options. */ +static unsigned int auto_export_flags; + +/* A mask of auto_export_flags bits that were explicitly set on the + command line. */ +static unsigned int explicit_auto_export_flags; + /* Whether to implement Unix like linker semantics. */ static int unix_ld; @@ -160,18 +139,11 @@ 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 (void) { - 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/:.*//'`; + ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`); + input_flags.dynamic = TRUE; config.has_shared = TRUE; /* The link_info.[init|fini]_functions are initialized in ld/lexsup.c. @@ -190,6 +162,8 @@ enum OPTION_AUTOIMP, OPTION_ERNOTOK, OPTION_EROK, + OPTION_EXPALL, + OPTION_EXPFULL, OPTION_EXPORT, OPTION_IMPORT, OPTION_INITFINI, @@ -198,6 +172,8 @@ enum OPTION_MAXSTACK, OPTION_MODTYPE, OPTION_NOAUTOIMP, + OPTION_NOEXPALL, + OPTION_NOEXPFULL, OPTION_NOSTRCMPCT, OPTION_PD, OPTION_PT, @@ -210,13 +186,9 @@ enum }; 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; +gld${EMULATION_NAME}_add_options + (int ns, char **shortopts, int nl, struct option **longopts, + int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED) { static const char xtra_short[] = "D:H:KT:z"; static const struct option xtra_long[] = { @@ -239,7 +211,10 @@ gld${EMULATION_NAME}_add_options (ns, shortopts, nl, longopts, nrl, really_longo {"bernotok", no_argument, NULL, OPTION_ERNOTOK}, {"berok", no_argument, NULL, OPTION_EROK}, {"berrmsg", no_argument, NULL, OPTION_IGNORE}, + {"bexpall", no_argument, NULL, OPTION_EXPALL}, + {"bexpfull", no_argument, NULL, OPTION_EXPFULL}, {"bexport", required_argument, NULL, OPTION_EXPORT}, + {"bbigtoc", no_argument, NULL, OPTION_IGNORE}, {"bf", no_argument, NULL, OPTION_ERNOTOK}, {"bgc", no_argument, &gc, 1}, {"bh", required_argument, NULL, OPTION_IGNORE}, @@ -254,6 +229,8 @@ gld${EMULATION_NAME}_add_options (ns, shortopts, nl, longopts, nrl, really_longo {"bM", required_argument, NULL, OPTION_MODTYPE}, {"bmodtype", required_argument, NULL, OPTION_MODTYPE}, {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP}, + {"bnoexpall", no_argument, NULL, OPTION_NOEXPALL}, + {"bnoexpfull", no_argument, NULL, OPTION_NOEXPFULL}, {"bnodelcsect", no_argument, NULL, OPTION_IGNORE}, {"bnoentry", no_argument, NULL, OPTION_IGNORE}, {"bnogc", no_argument, &gc, 0}, @@ -280,7 +257,7 @@ gld${EMULATION_NAME}_add_options (ns, shortopts, nl, longopts, nrl, really_longo {NULL, no_argument, NULL, 0} }; - /* Options supported by the AIX linker which we do not support: -f, + /* Options supported by the AIX linker which we do not support: -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps, -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl, -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl, @@ -291,15 +268,13 @@ gld${EMULATION_NAME}_add_options (ns, shortopts, nl, longopts, nrl, really_longo *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)); + *longopts = 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; +gld${EMULATION_NAME}_parse_args (int argc, char **argv) { int indx; @@ -310,7 +285,7 @@ gld${EMULATION_NAME}_parse_args (argc, argv) if (indx == 0) indx = 1; - if (indx < argc && strncmp (argv[indx], "-b", 2) == 0) + if (indx < argc && CONST_STRNEQ (argv[indx], "-b")) { char *s; @@ -326,9 +301,78 @@ gld${EMULATION_NAME}_parse_args (argc, argv) return FALSE; } +/* Helper for option '-f', which specify a list of input files. + Contrary to the native linker, we don't support shell patterns + (simply because glob isn't always available). */ + +static void +read_file_list (const char *filename) +{ + FILE *f; + /* An upper bound on the number of characters in the file. */ + long pos; + /* File in memory. */ + char *buffer; + size_t len; + char *b; + char *e; + + f = fopen (filename, FOPEN_RT); + if (f == NULL) + { + einfo ("%F%P: cannot open %s\n", filename); + return; + } + if (fseek (f, 0L, SEEK_END) == -1) + goto error; + pos = ftell (f); + if (pos == -1) + goto error; + if (fseek (f, 0L, SEEK_SET) == -1) + goto error; + + buffer = (char *) xmalloc (pos + 1); + len = fread (buffer, sizeof (char), pos, f); + if (len != (size_t) pos && ferror (f)) + goto error; + /* Add a NUL terminator. */ + buffer[len] = '\0'; + fclose (f); + + /* Parse files. */ + b = buffer; + while (1) + { + /* Skip empty lines. */ + while (*b == '\n' || *b == '\r') + b++; + + /* Stop if end of buffer. */ + if (b == buffer + len) + break; + + /* Eat any byte until end of line. */ + for (e = b; *e != '\0'; e++) + if (*e == '\n' || *e == '\r') + break; + + /* Replace end of line by nul. */ + if (*e != '\0') + *e++ = '\0'; + + if (b != e) + lang_add_input_file (b, lang_input_file_is_search_file_enum, NULL); + b = e; + } + return; + + error: + einfo ("%F%P: cannot read %s\n", optarg); + fclose (f); +} + static bfd_boolean -gld${EMULATION_NAME}_handle_option (optc) - int optc; +gld${EMULATION_NAME}_handle_option (int optc) { bfd_signed_vma val; const char *end; @@ -342,12 +386,18 @@ gld${EMULATION_NAME}_handle_option (optc) /* Long option which just sets a flag. */ break; + case 'f': + /* This overrides --auxiliary. This option specifies a file containing + a list of input files. */ + read_file_list (optarg); + break; + case 'D': val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') einfo ("%P: warning: ignoring invalid -D number %s\n", optarg); else if (val != -1) - lang_section_start (".data", exp_intop (val)); + lang_section_start (".data", exp_intop (val), NULL); break; case 'H': @@ -372,7 +422,7 @@ gld${EMULATION_NAME}_handle_option (optc) val = bfd_scan_vma (optarg, &end, 0); if (*end != '\0') return FALSE; - lang_section_start (".text", exp_intop (val)); + lang_section_start (".text", exp_intop (val), NULL); break; case OPTION_IGNORE: @@ -420,11 +470,23 @@ gld${EMULATION_NAME}_handle_option (optc) break; case OPTION_ERNOTOK: - force_make_executable = FALSE; + link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR; + link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR; break; case OPTION_EROK: - force_make_executable = TRUE; + link_info.unresolved_syms_in_objects = RM_IGNORE; + link_info.unresolved_syms_in_shared_libs = RM_IGNORE; + break; + + case OPTION_EXPALL: + auto_export_flags |= XCOFF_EXPALL; + explicit_auto_export_flags |= XCOFF_EXPALL; + break; + + case OPTION_EXPFULL: + auto_export_flags |= XCOFF_EXPFULL; + explicit_auto_export_flags |= XCOFF_EXPFULL; break; case OPTION_EXPORT: @@ -483,6 +545,16 @@ gld${EMULATION_NAME}_handle_option (optc) link_info.static_link = TRUE; break; + case OPTION_NOEXPALL: + auto_export_flags &= ~XCOFF_EXPALL; + explicit_auto_export_flags |= XCOFF_EXPALL; + break; + + case OPTION_NOEXPFULL: + auto_export_flags &= ~XCOFF_EXPFULL; + explicit_auto_export_flags |= XCOFF_EXPFULL; + break; + case OPTION_NOSTRCMPCT: link_info.traditional_format = TRUE; break; @@ -507,7 +579,7 @@ gld${EMULATION_NAME}_handle_option (optc) t = exp_binop ('&', exp_binop ('+', t, exp_intop (31)), exp_intop (~(bfd_vma) 31)); - lang_section_start (".data", t); + lang_section_start (".data", t, NULL); } break; @@ -528,7 +600,7 @@ gld${EMULATION_NAME}_handle_option (optc) t = exp_binop ('&', exp_binop ('+', t, exp_intop (31)), exp_intop (~(bfd_vma) 31)); - lang_section_start (".text", t); + lang_section_start (".text", t, NULL); } break; @@ -570,8 +642,7 @@ gld${EMULATION_NAME}_handle_option (optc) as an import file. This is for AIX compatibility. */ static bfd_boolean -gld${EMULATION_NAME}_unrecognized_file (entry) - lang_input_statement_type *entry; +gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry) { FILE *e; bfd_boolean ret; @@ -596,7 +667,7 @@ gld${EMULATION_NAME}_unrecognized_file (entry) *flpp = n; ret = TRUE; - entry->loaded = TRUE; + entry->flags.loaded = TRUE; } fclose (e); @@ -607,18 +678,20 @@ gld${EMULATION_NAME}_unrecognized_file (entry) /* This is called after the input files have been opened. */ static void -gld${EMULATION_NAME}_after_open () +gld${EMULATION_NAME}_after_open (void) { bfd_boolean r; struct set_info *p; + after_open_default (); + /* Call ldctor_build_sets, after pretending that this is a relocatable link. We do this because AIX requires relocation entries for all references to symbols, even in a final executable. Of course, we only want to do this if we are producing an XCOFF output file. */ r = link_info.relocatable; - if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL) + if (strstr (bfd_get_target (link_info.output_bfd), "xcoff") != NULL) link_info.relocatable = TRUE; ldctor_build_sets (); link_info.relocatable = r; @@ -643,7 +716,8 @@ 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 (link_info.output_bfd, &link_info, + p->h, size)) einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n"); } } @@ -652,13 +726,18 @@ gld${EMULATION_NAME}_after_open () sections, but before any sizes or addresses have been set. */ static void -gld${EMULATION_NAME}_before_allocation () +gld${EMULATION_NAME}_before_allocation (void) { struct filelist *fl; struct export_symbol_list *el; char *libpath; asection *special_sections[XCOFF_NUMBER_OF_SPECIAL_SECTIONS]; - int i; + static const char *const must_keep_sections[] = { + ".text", + ".data", + ".bss" + }; + unsigned int i, flags; /* Handle the import and export files, if any. */ for (fl = import_files; fl != NULL; fl = fl->next) @@ -670,7 +749,7 @@ gld${EMULATION_NAME}_before_allocation () 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)) + if (!bfd_xcoff_export_symbol (link_info.output_bfd, &link_info, h)) einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n"); } @@ -695,26 +774,65 @@ gld${EMULATION_NAME}_before_allocation () size_t len; search_dirs_type *search; - len = strlen (search_head->name); - libpath = xmalloc (len + 1); - strcpy (libpath, search_head->name); - for (search = search_head->next; search != NULL; search = search->next) + /* PR ld/4023: Strip sysroot prefix from any paths + being inserted into the output binary's DT_RPATH. */ + if (ld_sysroot != NULL + && * ld_sysroot != 0) { - size_t nlen; + const char * name = search_head->name; + size_t ld_sysroot_len = strlen (ld_sysroot); + + if (strncmp (name, ld_sysroot, ld_sysroot_len) == 0) + name += ld_sysroot_len; + + len = strlen (name); + libpath = xmalloc (len + 1); + strcpy (libpath, name); + + for (search = search_head->next; search != NULL; search = search->next) + { + size_t nlen; - nlen = strlen (search->name); - libpath = xrealloc (libpath, len + nlen + 2); - libpath[len] = ':'; - strcpy (libpath + len + 1, search->name); - len += nlen + 1; + name = search->name; + if (strncmp (name, ld_sysroot, ld_sysroot_len) == 0) + name += ld_sysroot_len; + + nlen = strlen (name); + libpath = xrealloc (libpath, len + nlen + 2); + libpath[len] = ':'; + strcpy (libpath + len + 1, name); + len += nlen + 1; + } + } + else + { + len = strlen (search_head->name); + libpath = xmalloc (len + 1); + strcpy (libpath, search_head->name); + + for (search = search_head->next; search != NULL; search = search->next) + { + size_t nlen; + + nlen = strlen (search->name); + libpath = xrealloc (libpath, len + nlen + 2); + libpath[len] = ':'; + strcpy (libpath + len + 1, search->name); + len += nlen + 1; + } } } + /* Default to -bexpfull for SVR4-like semantics. */ + flags = (unix_ld ? XCOFF_EXPFULL : 0); + flags &= ~explicit_auto_export_flags; + flags |= auto_export_flags; + /* Let the XCOFF backend set up the .loader section. */ if (!bfd_xcoff_size_dynamic_sections - (output_bfd, &link_info, libpath, entry_symbol.name, file_align, + (link_info.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, + modtype, textro ? TRUE : FALSE, flags, special_sections, rtld ? TRUE : FALSE)) einfo ("%P%F: failed to set dynamic section sizes: %E\n"); @@ -736,7 +854,7 @@ gld${EMULATION_NAME}_before_allocation () /* Remove this section from the list of the output section. This assumes we know what the script looks like. */ is = NULL; - os = lang_output_section_find (sec->output_section->name); + os = lang_output_section_get (sec->output_section); if (os == NULL) einfo ("%P%F: can't find output section %s\n", sec->output_section->name); @@ -831,12 +949,28 @@ gld${EMULATION_NAME}_before_allocation () &is->header.next); } } + + /* Executables and shared objects must always have .text, .data + and .bss output sections, so that the header can refer to them. + The kernel refuses to load objects that have missing sections. */ + if (!link_info.relocatable) + for (i = 0; i < ARRAY_SIZE (must_keep_sections); i++) + { + asection *sec; + + sec = bfd_get_section_by_name (link_info.output_bfd, + must_keep_sections[i]); + if (sec == NULL) + einfo ("%P: can't find required output section %s\n", must_keep_sections[i]); + else + sec->flags |= SEC_KEEP; + } + + before_allocation_default (); } static char * -gld${EMULATION_NAME}_choose_target (argc, argv) - int argc; - char **argv; +gld${EMULATION_NAME}_choose_target (int argc, char **argv) { int i, j, jmax; static char *from_outside; @@ -871,8 +1005,7 @@ gld${EMULATION_NAME}_choose_target (argc, argv) 1 : state changed 0 : no change */ static int -change_symbol_mode (input) - char *input; +change_symbol_mode (char *input) { char *symbol_mode_string[] = { "# 32", /* 0x01 */ @@ -906,9 +1039,7 @@ change_symbol_mode (input) 0 : ignore -1 : error, try something else */ static int -is_syscall (input, flag) - char *input; - unsigned int *flag; +is_syscall (char *input, unsigned int *flag) { unsigned int bit; char *string; @@ -958,9 +1089,7 @@ is_syscall (input, flag) this is called by the handle_option emulation routine. */ static void -gld${EMULATION_NAME}_read_file (filename, import) - const char *filename; - bfd_boolean import; +gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import) { struct obstack *o; FILE *f; @@ -979,6 +1108,7 @@ gld${EMULATION_NAME}_read_file (filename, import) { bfd_set_error (bfd_error_system_call); einfo ("%F%s: %E\n", filename); + return; } keep = FALSE; @@ -1044,32 +1174,18 @@ gld${EMULATION_NAME}_read_file (filename, import) else { char cs; - char *file; + char *start; (void) obstack_finish (o); keep = TRUE; - imppath = s; - file = NULL; + start = s; while (!ISSPACE (*s) && *s != '(' && *s != '\0') - { - if (*s == '/') - file = s + 1; - ++s; - } - if (file != NULL) - { - file[-1] = '\0'; - impfile = file; - if (imppath == file - 1) - imppath = "/"; - } - else - { - impfile = imppath; - imppath = ""; - } + ++s; cs = *s; *s = '\0'; + if (!bfd_xcoff_split_import_path (link_info.output_bfd, + start, &imppath, &impfile)) + einfo ("%F%P: Could not parse import path: %E\n"); while (ISSPACE (cs)) { ++s; @@ -1155,7 +1271,7 @@ gld${EMULATION_NAME}_read_file (filename, import) { struct export_symbol_list *n; - ldlang_add_undef (symname); + ldlang_add_undef (symname, TRUE); n = ((struct export_symbol_list *) xmalloc (sizeof (struct export_symbol_list))); n->next = export_symbols; @@ -1173,7 +1289,8 @@ gld${EMULATION_NAME}_read_file (filename, import) } else { - if (!bfd_xcoff_import_symbol (output_bfd, &link_info, h, + if (!bfd_xcoff_import_symbol (link_info.output_bfd, + &link_info, h, address, imppath, impfile, impmember, syscall_flag)) einfo ("%X%s:%d: failed to import symbol %s: %E\n", @@ -1196,13 +1313,14 @@ gld${EMULATION_NAME}_read_file (filename, import) obstack_free (o, NULL); free (o); } + + fclose (f); } /* This routine saves us from worrying about declaring free. */ static void -gld${EMULATION_NAME}_free (p) - PTR p; +gld${EMULATION_NAME}_free (void *p) { free (p); } @@ -1212,8 +1330,7 @@ gld${EMULATION_NAME}_free (p) to symbols. */ static void -gld${EMULATION_NAME}_find_relocs (s) - lang_statement_union_type *s; +gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *s) { if (s->header.type == lang_reloc_statement_enum) { @@ -1222,7 +1339,8 @@ 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 (link_info.output_bfd, &link_info, + rs->name)) einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n"); } @@ -1233,8 +1351,7 @@ gld${EMULATION_NAME}_find_relocs (s) /* Look through an expression for an assignment statement. */ static void -gld${EMULATION_NAME}_find_exp_assignment (exp) - etree_type *exp; +gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp) { struct bfd_link_hash_entry *h; @@ -1249,7 +1366,8 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) case etree_assign: if (strcmp (exp->assign.dst, ".") != 0) { - if (!bfd_xcoff_record_link_assignment (output_bfd, &link_info, + if (!bfd_xcoff_record_link_assignment (link_info.output_bfd, + &link_info, exp->assign.dst)) einfo ("%P%F: failed to record assignment to %s: %E\n", exp->assign.dst); @@ -1278,18 +1396,17 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) } static char * -gld${EMULATION_NAME}_get_script (isfile) - int *isfile; +gld${EMULATION_NAME}_get_script (int *isfile) EOF -if test -n "$COMPILE_IN" +if test x"$COMPILE_IN" = xyes then # Scripts compiled in. # sed commands to quote an ld script as a C string. sc="-f ${srcdir}/emultempl/ostring.sed" -cat >>e${EMULATION_NAME}.c <> e${EMULATION_NAME}.c else # Scripts read from the filesystem. -cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <the_bfd = bfd_create ("initfini", output_bfd); + initfini_file->the_bfd = bfd_create ("initfini", link_info.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))) + bfd_get_arch (link_info.output_bfd), + bfd_get_mach (link_info.output_bfd))) { einfo ("%X%P: can not create BFD %E\n"); return; @@ -1371,15 +1488,44 @@ gld${EMULATION_NAME}_create_output_section_statements () } static void -gld${EMULATION_NAME}_set_output_arch () +gld${EMULATION_NAME}_set_output_arch (void) +{ + bfd_set_arch_mach (link_info.output_bfd, + bfd_xcoff_architecture (link_info.output_bfd), + bfd_xcoff_machine (link_info.output_bfd)); + + ldfile_output_architecture = bfd_get_arch (link_info.output_bfd); + ldfile_output_machine = bfd_get_mach (link_info.output_bfd); + ldfile_output_machine_name = bfd_printable_name (link_info.output_bfd); +} + +static bfd_boolean +gld${EMULATION_NAME}_open_dynamic_archive (const char *arch, + search_dirs_type *search, + lang_input_statement_type *entry) { - bfd_set_arch_mach (output_bfd, - bfd_xcoff_architecture (output_bfd), - bfd_xcoff_machine (output_bfd)); + char *path; + + if (!entry->flags.maybe_archive) + return FALSE; + + if (entry->flags.full_name_provided) + path = concat (search->name, "/", entry->filename, + (const char *) NULL); + else + path = concat (search->name, "/lib", entry->filename, arch, ".a", + (const char *) NULL); - 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); + if (!ldfile_try_open_bfd (path, entry)) + { + free (path); + return FALSE; + } + /* Don't include the searched directory in the import path. */ + bfd_xcoff_set_archive_import_path (&link_info, entry->the_bfd, + path + strlen (search->name) + 1); + entry->filename = path; + return TRUE; } struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { @@ -1395,9 +1541,9 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { gld${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", - 0, /* finish */ + finish_default, gld${EMULATION_NAME}_create_output_section_statements, - 0, /* open_dynamic_archive */ + gld${EMULATION_NAME}_open_dynamic_archive, 0, /* place_orphan */ 0, /* set_symbols */ gld${EMULATION_NAME}_parse_args, @@ -1407,6 +1553,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { NULL, /* list_options */ NULL, /* recognized_file */ NULL, /* find potential_libraries */ - NULL /* new_vers_pattern */ + NULL, /* new_vers_pattern */ + NULL /* extra_map_file_text */ }; EOF