* emultempl/aix.em: Include ldctor.h.
authorIan Lance Taylor <ian@airs.com>
Fri, 27 Oct 1995 22:21:43 +0000 (22:21 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 27 Oct 1995 22:21:43 +0000 (22:21 +0000)
(gld${EMULATION_NAME}_after_open): New static function.
(gld${EMULATION_NAME}_before_allocation): Call find_relocs.
(gld${EMULATION_NAME}_find_relocs): New static function.
(gld${EMULATION_NAME}_find_exp_assignment): New static function.
(ld_${EMULATION_NAME}_emulation): Use new after_open function.
* scripttempl/aix.sc: Use CONSTRUCTORS in .data.
* ldctor.c (struct set_info): Move definition into ldctor.h.
(struct set_element): Likewise.
(sets): Make non-static.
(ldctor_add_set_entry): Add name parameter.  Save it in the new
set element.
(ldctor_build_sets): Avoid being called twice.  Pass set element
name to lang_add_reloc.
* ldctor.h (struct set_info): Move definition here from ldctor.c.
(struct set_element): Likewise.  Add new field name.
(sets): Declare.
(ldctor_add_set_entry): Declare new name parameter.
* ldwrite.c (build_link_order): Don't insist that either name or
section be NULL in a lang_reloc_statement.
* ldmain.c (add_to_set): Pass NULL to ldctor_add_new_set_entry for
new name parameter.
(constructor_callback): Pass name to ldctor_add_new_set_entry for
new name parameter.

ld/ChangeLog
ld/emultempl/aix.em

index 339481498625344150f4a40c179b181954b72f2e..72c2a7ba0479ceca626bf985838df589c38318f5 100644 (file)
@@ -1,3 +1,32 @@
+Fri Oct 27 17:59:09 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * emultempl/aix.em: Include ldctor.h.
+       (gld${EMULATION_NAME}_after_open): New static function.
+       (gld${EMULATION_NAME}_before_allocation): Call find_relocs.
+       (gld${EMULATION_NAME}_find_relocs): New static function.
+       (gld${EMULATION_NAME}_find_exp_assignment): New static function.
+       (ld_${EMULATION_NAME}_emulation): Use new after_open function.
+       * scripttempl/aix.sc: Use CONSTRUCTORS in .data.
+       * ldctor.c (struct set_info): Move definition into ldctor.h.
+       (struct set_element): Likewise.
+       (sets): Make non-static.
+       (ldctor_add_set_entry): Add name parameter.  Save it in the new
+       set element.
+       (ldctor_build_sets): Avoid being called twice.  Pass set element
+       name to lang_add_reloc.
+       * ldctor.h (struct set_info): Move definition here from ldctor.c.
+       (struct set_element): Likewise.  Add new field name.
+       (sets): Declare.
+       (ldctor_add_set_entry): Declare new name parameter.
+       * ldwrite.c (build_link_order): Don't insist that either name or
+       section be NULL in a lang_reloc_statement.
+       * ldmain.c (add_to_set): Pass NULL to ldctor_add_new_set_entry for
+       new name parameter.
+       (constructor_callback): Pass name to ldctor_add_new_set_entry for
+       new name parameter.
+       
+       * ldmisc.c (demangle): Fix indentation.  Remove a leading period.
+
 Thu Oct 26 22:22:49 1995  Stan Shebs  <shebs@andros.cygnus.com>
 
        * mpw-config.in: Add PowerMac target support, generate config.h.
index 08c79b20f6afdf46c10ec4c54b8f92f1560a55fe..f234dd2d4247198e86f713010158436a12e80d2c 100644 (file)
@@ -41,12 +41,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "ldmisc.h"
 #include "ldexp.h"
 #include "ldlang.h"
+#include "ldctor.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));
+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));
 
 /* The file alignment required for each section.  */
@@ -313,6 +318,48 @@ gld${EMULATION_NAME}_parse_args (argc, argv)
   return 1;
 }
 
+/* This is called after the input files have been opened.  */
+
+static void
+gld${EMULATION_NAME}_after_open ()
+{
+  boolean r;
+  struct set_info *p;
+
+  /* Call ldctor_build_sets, after pretending that this is a
+     relocateable link.  We do this because AIX requires relocation
+     entries for all references to symbols, even in a final
+     executable.  */
+  r = link_info.relocateable;
+  link_info.relocateable = true;
+  ldctor_build_sets ();
+  link_info.relocateable = r;
+
+  /* For each set, record the size, so that the XCOFF backend can
+     output the correct csect length.  */
+  for (p = sets; p != (struct set_info *) NULL; p = p->next)
+    {
+      bfd_size_type size;
+
+      /* If the symbol is defined, we may have been invoked from
+        collect, and the sets may already have been built, so we do
+        not do anything.  */
+      if (p->h->type == bfd_link_hash_defined
+         || p->h->type == bfd_link_hash_defweak)
+       continue;
+
+      if (p->reloc != BFD_RELOC_CTOR)
+       {
+         /* Handle this if we need to.  */
+         abort ();
+       }
+
+      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");
+    }
+}
+
 /* This is called after the sections have been attached to output
    sections, but before any sizes or addresses have been set.  */
 
@@ -328,6 +375,12 @@ gld${EMULATION_NAME}_before_allocation ()
   for (fl = export_files; fl != NULL; fl = fl->next)
     gld${EMULATION_NAME}_read_file (fl->name, false);
 
+  /* Track down all relocations called for by the linker script (these
+     are typically constructor/destructor entries created by
+     CONSTRUCTORS) and let the backend know it will need to create
+     .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.  */
@@ -592,6 +645,76 @@ gld${EMULATION_NAME}_free (p)
   free (p);
 }
 
+/* This is called by the before_allocation routine via
+   lang_for_each_statement.  It looks for relocations and assignments
+   to symbols.  */
+
+static void
+gld${EMULATION_NAME}_find_relocs (s)
+     lang_statement_union_type *s;
+{
+  if (s->header.type == lang_reloc_statement_enum)
+    {
+      lang_reloc_statement_type *rs;
+
+      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");
+    }
+
+  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;
+      /* Fall through.  */
+    case etree_assign:
+      if (strcmp (exp->assign.dst, ".") != 0)
+       {
+         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);
+       }
+      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;
+    }
+}
+
 static char *
 gld${EMULATION_NAME}_get_script(isfile)
      int *isfile;
@@ -652,7 +775,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   syslib_default,
   hll_default,
   after_parse_default,
-  after_open_default,
+  gld${EMULATION_NAME}_after_open,
   after_allocation_default,
   set_output_arch_default,
   ldemul_default_target,