]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - ld/emultempl/aix.em
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / ld / emultempl / aix.em
index 9aa0d500aeea29bcb2f103b9399e13b055851f8b..d578b6eae7974f066232a3ea280c64d2e04d173f 100644 (file)
@@ -9,9 +9,7 @@ fragment <<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, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1991-2021 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>
@@ -42,6 +40,7 @@ fragment <<EOF
 #include "getopt.h"
 #include "obstack.h"
 #include "bfdlink.h"
+#include "ctf-api.h"
 
 #include "ld.h"
 #include "ldmain.h"
@@ -57,6 +56,7 @@ fragment <<EOF
 #include "coff/xcoff.h"
 #include "libcoff.h"
 #include "libxcoff.h"
+#include "xcofflink.h"
 
 static void gld${EMULATION_NAME}_read_file (const char *, bfd_boolean);
 static void gld${EMULATION_NAME}_free (void *);
@@ -84,6 +84,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;
 
@@ -137,6 +145,7 @@ gld${EMULATION_NAME}_before_parse (void)
 {
   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.
@@ -155,6 +164,8 @@ enum
     OPTION_AUTOIMP,
     OPTION_ERNOTOK,
     OPTION_EROK,
+    OPTION_EXPALL,
+    OPTION_EXPFULL,
     OPTION_EXPORT,
     OPTION_IMPORT,
     OPTION_INITFINI,
@@ -163,6 +174,8 @@ enum
     OPTION_MAXSTACK,
     OPTION_MODTYPE,
     OPTION_NOAUTOIMP,
+    OPTION_NOEXPALL,
+    OPTION_NOEXPFULL,
     OPTION_NOSTRCMPCT,
     OPTION_PD,
     OPTION_PT,
@@ -200,7 +213,10 @@ gld${EMULATION_NAME}_add_options
     {"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},
@@ -215,6 +231,8 @@ gld${EMULATION_NAME}_add_options
     {"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},
@@ -241,7 +259,7 @@ gld${EMULATION_NAME}_add_options
     {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,
@@ -285,6 +303,76 @@ gld${EMULATION_NAME}_parse_args (int argc, char **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 (int optc)
 {
@@ -300,10 +388,16 @@ gld${EMULATION_NAME}_handle_option (int 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);
+       einfo (_("%P: warning: ignoring invalid -D number %s\n"), optarg);
       else if (val != -1)
        lang_section_start (".data", exp_intop (val), NULL);
       break;
@@ -311,7 +405,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case 'H':
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0' || (val & (val - 1)) != 0)
-       einfo ("%P: warning: ignoring invalid -H number %s\n", optarg);
+       einfo (_("%P: warning: ignoring invalid -H number %s\n"), optarg);
       else
        file_align = val;
       break;
@@ -378,11 +472,23 @@ gld${EMULATION_NAME}_handle_option (int optc)
       break;
 
     case OPTION_ERNOTOK:
-      force_make_executable = FALSE;
+      link_info.unresolved_syms_in_objects = RM_DIAGNOSE;
+      link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE;
       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:
@@ -411,7 +517,8 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case OPTION_MAXDATA:
       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;
@@ -419,7 +526,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case OPTION_MAXSTACK:
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')
-       einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n",
+       einfo (_("%P: warning: ignoring invalid -bmaxstack number %s\n"),
               optarg);
       else
        maxstack = val;
@@ -428,11 +535,11 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case OPTION_MODTYPE:
       if (*optarg == 'S')
        {
-         link_info.shared = TRUE;
+         link_info.type = type_dll;
          ++optarg;
        }
       if (*optarg == '\0' || optarg[1] == '\0')
-       einfo ("%P: warning: ignoring invalid module type %s\n", optarg);
+       einfo (_("%P: warning: ignoring invalid module type %s\n"), optarg);
       else
        modtype = (*optarg << 8) | optarg[1];
       break;
@@ -441,6 +548,16 @@ gld${EMULATION_NAME}_handle_option (int 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;
@@ -452,7 +569,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
         expression.  */
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')
-       einfo ("%P: warning: ignoring invalid -pD number %s\n", optarg);
+       einfo (_("%P: warning: ignoring invalid -pD number %s\n"), optarg);
       else
        {
          etree_type *t;
@@ -475,7 +592,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
         within the file.  */
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')
-       einfo ("%P: warning: ignoring invalid -pT number %s\n", optarg);
+       einfo (_("%P: warning: ignoring invalid -pT number %s\n"), optarg);
       else
        {
          etree_type *t;
@@ -553,7 +670,7 @@ gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry)
       *flpp = n;
 
       ret = TRUE;
-      entry->loaded = TRUE;
+      entry->flags.loaded = TRUE;
     }
 
   fclose (e);
@@ -566,19 +683,21 @@ gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry)
 static void
 gld${EMULATION_NAME}_after_open (void)
 {
-  bfd_boolean r;
+  enum output_type t;
   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)
-    link_info.relocatable = TRUE;
+  t = link_info.type;
+  if (strstr (bfd_get_target (link_info.output_bfd), "xcoff") != NULL)
+    link_info.type = type_relocatable;
   ldctor_build_sets ();
-  link_info.relocatable = r;
+  link_info.type = t;
 
   /* For each set, record the size, so that the XCOFF backend can
      output the correct csect length.  */
@@ -600,8 +719,9 @@ gld${EMULATION_NAME}_after_open (void)
        }
 
       size = (p->count + 2) * 4;
-      if (!bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size))
-       einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n");
+      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"));
     }
 }
 
@@ -615,7 +735,12 @@ gld${EMULATION_NAME}_before_allocation (void)
   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)
@@ -626,9 +751,9 @@ gld${EMULATION_NAME}_before_allocation (void)
 
       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))
-       einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n");
+       einfo (_("%F%P: bfd_link_hash_lookup of export symbol failed: %E\n"));
+      if (!bfd_xcoff_export_symbol (link_info.output_bfd, &link_info, h))
+       einfo (_("%F%P: bfd_xcoff_export_symbol failed: %E\n"));
     }
 
   /* Track down all relocations called for by the linker script (these
@@ -701,13 +826,18 @@ gld${EMULATION_NAME}_before_allocation (void)
        }
     }
 
+  /* 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");
+    einfo (_("%F%P: 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.  */
@@ -727,9 +857,9 @@ gld${EMULATION_NAME}_before_allocation (void)
       /* 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",
+       einfo (_("%F%P: can't find output section %s\n"),
               sec->output_section->name);
 
       for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->header.next)
@@ -766,8 +896,8 @@ gld${EMULATION_NAME}_before_allocation (void)
 
       if (is == NULL)
        {
-         einfo ("%P%F: can't find %s in output section\n",
-                bfd_get_section_name (sec->owner, sec));
+         einfo (_("%F%P: can't find %s in output section\n"),
+                bfd_section_name (sec));
        }
 
       /* Now figure out where the section should go.  */
@@ -817,12 +947,28 @@ gld${EMULATION_NAME}_before_allocation (void)
       else
        {
          is->header.next = NULL;
-         lang_statement_append (&os->children,
-                                (lang_statement_union_type *) is,
-                                &is->header.next);
+         *os->children.tail = (lang_statement_union_type *) is;
+         os->children.tail = &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 (!bfd_link_relocatable (&link_info))
+    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 ();
 }
 
@@ -964,7 +1110,8 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
   if (f == NULL)
     {
       bfd_set_error (bfd_error_system_call);
-      einfo ("%F%s: %E\n", filename);
+      einfo ("%F%P: %s: %E\n", filename);
+      return;
     }
 
   keep = FALSE;
@@ -1025,37 +1172,24 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
              obstack_free (o, obstack_base (o));
            }
          else if (*s == '(')
-           einfo ("%F%s%d: #! ([member]) is not supported in import files\n",
+           einfo (_("%F%P:%s:%d: #! ([member]) is not supported "
+                    "in import files\n"),
                   filename, lineno);
          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;
@@ -1065,7 +1199,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
                {
                  impmember = "";
                  if (cs != '\0')
-                   einfo ("%s:%d: warning: syntax error in import file\n",
+                   einfo (_("%P:%s:%d: warning: syntax error in import file\n"),
                           filename, lineno);
                }
              else
@@ -1077,7 +1211,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
                  if (*s == ')')
                    *s = '\0';
                  else
-                   einfo ("%s:%d: warning: syntax error in import file\n",
+                   einfo (_("%P:%s:%d: warning: syntax error in import file\n"),
                           filename, lineno);
                }
            }
@@ -1112,7 +1246,8 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
                  while (ISSPACE (*se))
                    ++se;
                  if (*se != '\0')
-                   einfo ("%s%d: warning: syntax error in import/export file\n",
+                   einfo (_("%P:%s%d: warning: syntax error in "
+                            "import/export file\n"),
                           filename, lineno);
                }
 
@@ -1129,7 +1264,8 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
                      address = bfd_scan_vma (s, &end, 0);
                      if (*end != '\0')
                        {
-                         einfo ("%s:%d: warning: syntax error in import/export file\n",
+                         einfo (_("%P:%s:%d: warning: syntax error in "
+                                  "import/export file\n"),
                                 filename, lineno);
 
                        }
@@ -1141,7 +1277,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean 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;
@@ -1159,10 +1295,11 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean 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",
+                   einfo (_("%X%P:%s:%d: failed to import symbol %s: %E\n"),
                           filename, lineno, symname);
                }
            }
@@ -1172,7 +1309,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
 
   if (obstack_object_size (o) > 0)
     {
-      einfo ("%s:%d: warning: ignoring unterminated last line\n",
+      einfo (_("%P:%s:%d: warning: ignoring unterminated last line\n"),
             filename, lineno);
       obstack_free (o, obstack_base (o));
     }
@@ -1182,6 +1319,8 @@ gld${EMULATION_NAME}_read_file (const char *filename, bfd_boolean import)
       obstack_free (o, NULL);
       free (o);
     }
+
+  fclose (f);
 }
 
 /* This routine saves us from worrying about declaring free.  */
@@ -1205,9 +1344,10 @@ gld${EMULATION_NAME}_find_relocs (lang_statement_union_type *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))
-       einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n");
+       einfo (_("%F%P: only relocations against symbols are permitted\n"));
+      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"));
     }
 
   if (s->header.type == lang_assignment_statement_enum)
@@ -1224,6 +1364,7 @@ gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
   switch (exp->type.node_class)
     {
     case etree_provide:
+    case etree_provided:
       h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
                                FALSE, FALSE, FALSE);
       if (h == NULL)
@@ -1232,9 +1373,10 @@ gld${EMULATION_NAME}_find_exp_assignment (etree_type *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",
+           einfo (_("%F%P: failed to record assignment to %s: %E\n"),
                   exp->assign.dst);
        }
       gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
@@ -1264,7 +1406,7 @@ static char *
 gld${EMULATION_NAME}_get_script (int *isfile)
 EOF
 
-if test -n "$COMPILE_IN"
+if test x"$COMPILE_IN" = xyes
 then
 # Scripts compiled in.
 
@@ -1275,11 +1417,11 @@ fragment <<EOF
 {
   *isfile = 0;
 
-  if (link_info.relocatable && config.build_constructors)
+  if (bfd_link_relocatable (&link_info) && config.build_constructors)
     return
 EOF
 sed $sc ldscripts/${EMULATION_NAME}.xu                >> e${EMULATION_NAME}.c
-echo '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_relocatable (&link_info)) 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
@@ -1296,9 +1438,9 @@ fragment <<EOF
 {
   *isfile = 1;
 
-  if (link_info.relocatable && config.build_constructors)
+  if (bfd_link_relocatable (&link_info) && config.build_constructors)
     return "ldscripts/${EMULATION_NAME}.xu";
-  else if (link_info.relocatable)
+  else if (bfd_link_relocatable (&link_info))
     return "ldscripts/${EMULATION_NAME}.xr";
   else if (!config.text_read_only)
     return "ldscripts/${EMULATION_NAME}.xbn";
@@ -1317,7 +1459,7 @@ static void
 gld${EMULATION_NAME}_create_output_section_statements (void)
 {
   /* __rtinit */
-  if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour)
+  if ((bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour)
       && (link_info.init_function != NULL
          || link_info.fini_function != NULL
          || rtld))
@@ -1326,13 +1468,13 @@ gld${EMULATION_NAME}_create_output_section_statements (void)
                                           lang_input_file_is_file_enum,
                                           NULL);
 
-      initfini_file->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");
+         einfo (_("%F%P: can not create BFD: %E\n"));
          return;
        }
 
@@ -1342,7 +1484,7 @@ gld${EMULATION_NAME}_create_output_section_statements (void)
                                            link_info.fini_function,
                                            rtld))
        {
-         einfo ("%X%P: can not create BFD %E\n");
+         einfo (_("%F%P: can not create BFD: %E\n"));
          return;
        }
 
@@ -1355,13 +1497,72 @@ gld${EMULATION_NAME}_create_output_section_statements (void)
 static void
 gld${EMULATION_NAME}_set_output_arch (void)
 {
-  bfd_set_arch_mach (output_bfd,
-                    bfd_xcoff_architecture (output_bfd),
-                    bfd_xcoff_machine (output_bfd));
+  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)
+{
+  char *path;
 
-  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 (!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);
+
+  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;
+}
+
+static bfd_boolean
+gld${EMULATION_NAME}_print_symbol (struct bfd_link_hash_entry *hash_entry,
+                                  void *ptr)
+{
+  asection *sec = (asection *) ptr;
+
+  if ((hash_entry->type == bfd_link_hash_defined
+       || hash_entry->type == bfd_link_hash_defweak)
+      && sec == hash_entry->u.def.section)
+    {
+      int i;
+      struct xcoff_link_hash_entry *h;
+
+      for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
+       print_space ();
+      minfo ("0x%V   ",
+            (hash_entry->u.def.value
+             + hash_entry->u.def.section->output_offset
+             + hash_entry->u.def.section->output_section->vma));
+
+      /* Flag symbol if it has been garbage collected.  */
+      h = (struct xcoff_link_hash_entry *) hash_entry;
+      if ((h != NULL) && !(h->flags & XCOFF_MARK))
+       minfo (" -->gc");
+      minfo ("             %pT\n", hash_entry->root.string);
+    }
+
+  return TRUE;
 }
 
 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
@@ -1370,6 +1571,8 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
   hll_default,
   after_parse_default,
   gld${EMULATION_NAME}_after_open,
+  after_check_relocs_default,
+  before_place_orphans_default,
   after_allocation_default,
   gld${EMULATION_NAME}_set_output_arch,
   gld${EMULATION_NAME}_choose_target,
@@ -1379,7 +1582,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
   "${OUTPUT_FORMAT}",
   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,
@@ -1389,6 +1592,11 @@ 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 */
+  ${LDEMUL_EMIT_CTF_EARLY-NULL},
+  ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
+  ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
+  gld${EMULATION_NAME}_print_symbol
 };
 EOF