Sat Mar 15 18:10:38 1997 H.J. Lu <hjl@lucon.org>
authorIan Lance Taylor <ian@airs.com>
Sat, 15 Mar 1997 23:17:46 +0000 (23:17 +0000)
committerIan Lance Taylor <ian@airs.com>
Sat, 15 Mar 1997 23:17:46 +0000 (23:17 +0000)
* ldemul.h (ldemul_list_emulations): Use full prototype.
* ldlang.c (print_one_symbol): Add declaration.
* ldlang.h (dprint_statements): Declare.
* ldmain.c (remove_output): Declare.
* ldmisc.c (vfinfo): Declare.
* ldwrite.c (clone_section): Declare.
(split_sections): Make static.  Declare.
* mri.c: Include libiberty.h.
(strdup): Don't declare.
(mri_alias): Use xstrdup rather than strdup.

ld/ChangeLog
ld/ldlang.c

index 3ccd300e3827284a539c1f8a1b309c1088e79918..ab7a48ad9899334f24c20d1e0fbb64b7d0e001ac 100644 (file)
@@ -1,3 +1,16 @@
+Sat Mar 15 18:10:38 1997  H.J. Lu  <hjl@lucon.org>
+
+       * ldemul.h (ldemul_list_emulations): Use full prototype.
+       * ldlang.c (print_one_symbol): Add declaration.
+       * ldlang.h (dprint_statements): Declare.
+       * ldmain.c (remove_output): Declare.
+       * ldmisc.c (vfinfo): Declare.
+       * ldwrite.c (clone_section): Declare.
+       (split_sections): Make static.  Declare.
+       * mri.c: Include libiberty.h.
+       (strdup): Don't declare.
+       (mri_alias): Use xstrdup rather than strdup.
+
 Fri Mar 14 21:30:06 1997  Ian Lance Taylor  <ian@cygnus.com>
 
        * scripttempl/elfmips.sc: Change handling of data area when
 Fri Mar 14 21:30:06 1997  Ian Lance Taylor  <ian@cygnus.com>
 
        * scripttempl/elfmips.sc: Change handling of data area when
index 3656a8a26fc2a00188d8a8a9714003450efadf19..aaf09e2a3f1f8e46c6a2547fbfe793756e950e51 100644 (file)
@@ -1,5 +1,5 @@
 /* Linker command language support.
 /* Linker command language support.
-   Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
 This file is part of GLD, the Gnu Linker.
 
 
 This file is part of GLD, the Gnu Linker.
 
@@ -101,6 +101,7 @@ static void print_assignment
   PARAMS ((lang_assignment_statement_type *assignment,
           lang_output_section_statement_type *output_section));
 static void print_input_statement PARAMS ((lang_input_statement_type *statm));
   PARAMS ((lang_assignment_statement_type *assignment,
           lang_output_section_statement_type *output_section));
 static void print_input_statement PARAMS ((lang_input_statement_type *statm));
+static boolean print_one_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
 static void print_input_section PARAMS ((lang_input_section_type *in));
 static void print_fill_statement PARAMS ((lang_fill_statement_type *fill));
 static void print_data_statement PARAMS ((lang_data_statement_type *data));
 static void print_input_section PARAMS ((lang_input_section_type *in));
 static void print_fill_statement PARAMS ((lang_fill_statement_type *fill));
 static void print_data_statement PARAMS ((lang_data_statement_type *data));
@@ -647,11 +648,12 @@ exp_init_os (exp)
 
 /*ARGSUSED*/
 static void
 
 /*ARGSUSED*/
 static void
-section_already_linked (abfd, sec, ignore)
+section_already_linked (abfd, sec, data)
      bfd *abfd;
      asection *sec;
      bfd *abfd;
      asection *sec;
-     PTR ignore;
+     PTR data;
 {
 {
+  lang_input_statement_type *entry = (lang_input_statement_type *) data;
   struct sec_link_once
     {
       struct sec_link_once *next;
   struct sec_link_once
     {
       struct sec_link_once *next;
@@ -662,6 +664,15 @@ section_already_linked (abfd, sec, ignore)
   const char *name;
   struct sec_link_once *l;
 
   const char *name;
   struct sec_link_once *l;
 
+  /* If we are only reading symbols from this object, then we want to
+     discard all sections.  */
+  if (entry->just_syms_flag)
+    {
+      sec->output_section = bfd_abs_section_ptr;
+      sec->output_offset = sec->vma;
+      return;
+    }
+
   flags = bfd_get_section_flags (abfd, sec);
 
   if ((flags & SEC_LINK_ONCE) == 0)
   flags = bfd_get_section_flags (abfd, sec);
 
   if ((flags & SEC_LINK_ONCE) == 0)
@@ -2064,7 +2075,15 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
           }
           dot = os->region->current;
           if (os->section_alignment == -1)
           }
           dot = os->region->current;
           if (os->section_alignment == -1)
-            dot = align_power (dot, os->bfd_section->alignment_power);
+            {
+              bfd_vma olddot;
+
+              olddot = dot;
+              dot = align_power (dot, os->bfd_section->alignment_power);
+              if (dot != olddot && config.warn_section_align)
+                einfo ("%P: warning: changing start of section %s by %u bytes\n",
+                       os->name, (unsigned int) (dot - olddot));
+            }
         }
         else
         {
         }
         else
         {
@@ -2669,8 +2688,10 @@ lang_one_common (h, info)
   /* Increase the size of the section.  */
   section->_raw_size += size;
 
   /* Increase the size of the section.  */
   section->_raw_size += size;
 
-  /* Make sure the section is allocated in memory.  */
+  /* Make sure the section is allocated in memory, and make sure that
+     it is no longer a common section.  */
   section->flags |= SEC_ALLOC;
   section->flags |= SEC_ALLOC;
+  section->flags &= ~ SEC_IS_COMMON;
 
   if (config.map_file != NULL)
     {
 
   if (config.map_file != NULL)
     {
@@ -2928,7 +2949,7 @@ ldlang_add_file (entry)
      each backend which might set the SEC_LINK_ONCE flag.  If we do
      this, we should probably handle SEC_EXCLUDE in the same way.  */
 
      each backend which might set the SEC_LINK_ONCE flag.  If we do
      this, we should probably handle SEC_EXCLUDE in the same way.  */
 
-  bfd_map_over_sections (entry->the_bfd, section_already_linked, (PTR) NULL);
+  bfd_map_over_sections (entry->the_bfd, section_already_linked, (PTR) entry);
 }
 
 void
 }
 
 void
@@ -3519,7 +3540,7 @@ lang_record_phdrs ()
   lang_statement_union_type *u;
 
   alc = 10;
   lang_statement_union_type *u;
 
   alc = 10;
-  secs = xmalloc (alc * sizeof (asection *));
+  secs = (asection **) xmalloc (alc * sizeof (asection *));
   last = NULL;
   for (l = lang_phdr_list; l != NULL; l = l->next)
     {
   last = NULL;
   for (l = lang_phdr_list; l != NULL; l = l->next)
     {
@@ -3559,7 +3580,8 @@ lang_record_phdrs ()
                  if (c >= alc)
                    {
                      alc *= 2;
                  if (c >= alc)
                    {
                      alc *= 2;
-                     secs = xrealloc (secs, alc * sizeof (asection *));
+                     secs = ((asection **)
+                             xrealloc (secs, alc * sizeof (asection *)));
                    }
                  secs[c] = os->bfd_section;
                  ++c;
                    }
                  secs[c] = os->bfd_section;
                  ++c;
@@ -3634,6 +3656,9 @@ static etree_type *overlay_vma;
 /* The overlay load address.  */
 static etree_type *overlay_lma;
 
 /* The overlay load address.  */
 static etree_type *overlay_lma;
 
+/* Whether nocrossrefs is set for this overlay.  */
+static int overlay_nocrossrefs;
+
 /* An expression for the maximum section size seen so far.  */
 static etree_type *overlay_max;
 
 /* An expression for the maximum section size seen so far.  */
 static etree_type *overlay_max;
 
@@ -3650,9 +3675,10 @@ static struct overlay_list *overlay_list;
 /* Start handling an overlay.  */
 
 void
 /* Start handling an overlay.  */
 
 void
-lang_enter_overlay (vma_expr, lma_expr)
+lang_enter_overlay (vma_expr, lma_expr, nocrossrefs)
      etree_type *vma_expr;
      etree_type *lma_expr;
      etree_type *vma_expr;
      etree_type *lma_expr;
+     int nocrossrefs;
 {
   /* The grammar should prevent nested overlays from occurring.  */
   ASSERT (overlay_vma == NULL
 {
   /* The grammar should prevent nested overlays from occurring.  */
   ASSERT (overlay_vma == NULL
@@ -3662,6 +3688,7 @@ lang_enter_overlay (vma_expr, lma_expr)
 
   overlay_vma = vma_expr;
   overlay_lma = lma_expr;
 
   overlay_vma = vma_expr;
   overlay_lma = lma_expr;
+  overlay_nocrossrefs = nocrossrefs;
 }
 
 /* Start a section in an overlay.  We handle this by calling
 }
 
 /* Start a section in an overlay.  We handle this by calling
@@ -3768,7 +3795,6 @@ lang_leave_overlay (fill, memspec, phdrs)
   l = overlay_list;
   while (l != NULL)
     {
   l = overlay_list;
   while (l != NULL)
     {
-      struct lang_nocrossref *nc;
       struct overlay_list *next;
 
       if (fill != 0 && l->os->fill == 0)
       struct overlay_list *next;
 
       if (fill != 0 && l->os->fill == 0)
@@ -3778,10 +3804,15 @@ lang_leave_overlay (fill, memspec, phdrs)
       if (phdrs != NULL && l->os->phdrs == NULL)
        l->os->phdrs = phdrs;
 
       if (phdrs != NULL && l->os->phdrs == NULL)
        l->os->phdrs = phdrs;
 
-      nc = (struct lang_nocrossref *) xmalloc (sizeof *nc);
-      nc->name = l->os->name;
-      nc->next = nocrossref;
-      nocrossref = nc;
+      if (overlay_nocrossrefs)
+       {
+         struct lang_nocrossref *nc;
+
+         nc = (struct lang_nocrossref *) xmalloc (sizeof *nc);
+         nc->name = l->os->name;
+         nc->next = nocrossref;
+         nocrossref = nc;
+       }
 
       next = l->next;
       free (l);
 
       next = l->next;
       free (l);
@@ -3797,6 +3828,147 @@ lang_leave_overlay (fill, memspec, phdrs)
 
   overlay_vma = NULL;
   overlay_lma = NULL;
 
   overlay_vma = NULL;
   overlay_lma = NULL;
+  overlay_nocrossrefs = 0;
   overlay_list = NULL;
   overlay_max = NULL;
 }
   overlay_list = NULL;
   overlay_max = NULL;
 }
+\f
+/* Version handling.  This is only useful for ELF.  */
+
+/* This global variable holds the version tree that we build.  */
+
+struct bfd_elf_version_tree *lang_elf_version_info;
+
+/* This is called for each variable name or match expression.  */
+
+struct bfd_elf_version_expr *
+lang_new_vers_regex (orig, new)
+     struct bfd_elf_version_expr *orig;
+     const char *new;
+{
+  struct bfd_elf_version_expr *ret;
+
+  ret = (struct bfd_elf_version_expr *) xmalloc (sizeof *ret);
+  ret->next = orig;
+  ret->match = new;
+  return ret;
+}
+
+/* This is called for each set of variable names and match
+   expressions.  */
+
+struct bfd_elf_version_tree *
+lang_new_vers_node (globals, locals)
+     struct bfd_elf_version_expr *globals;
+     struct bfd_elf_version_expr *locals;
+{
+  struct bfd_elf_version_tree *ret;
+
+  ret = (struct bfd_elf_version_tree *) xmalloc (sizeof *ret);
+  ret->next = NULL;
+  ret->name = NULL;
+  ret->vernum = 0;
+  ret->globals = globals;
+  ret->locals = locals;
+  ret->deps = NULL;
+  ret->name_indx = (unsigned int) -1;
+  ret->used = 0;
+  return ret;
+}
+
+/* This static variable keeps track of version indices.  */
+
+static int version_index;
+
+/* This is called when we know the name and dependencies of the
+   version.  */
+
+void
+lang_register_vers_node (name, version, deps)
+     const char *name;
+     struct bfd_elf_version_tree *version;
+     struct bfd_elf_version_deps *deps;
+{
+  struct bfd_elf_version_tree *t, **pp;
+  struct bfd_elf_version_expr *e1;
+
+  /* Make sure this node has a unique name.  */
+  for (t = lang_elf_version_info; t != NULL; t = t->next)
+    if (strcmp (t->name, name) == 0)
+      einfo ("%X%P: duplicate version tag `%s'\n", name);
+
+  /* Check the global and local match names, and make sure there
+     aren't any duplicates.  */
+
+  for (e1 = version->globals; e1 != NULL; e1 = e1->next)
+    {
+      for (t = lang_elf_version_info; t != NULL; t = t->next)
+       {
+         struct bfd_elf_version_expr *e2;
+
+         for (e2 = t->globals; e2 != NULL; e2 = e2->next)
+           if (strcmp (e1->match, e2->match) == 0)
+             einfo ("%X%P: duplicate expression `%s' in version information\n",
+                    e1->match);
+
+         for (e2 = t->locals; e2 != NULL; e2 = e2->next)
+           if (strcmp (e1->match, e2->match) == 0)
+             einfo ("%X%P: duplicate expression `%s' in version information\n",
+                    e1->match);
+       }
+    }
+
+  for (e1 = version->locals; e1 != NULL; e1 = e1->next)
+    {
+      for (t = lang_elf_version_info; t != NULL; t = t->next)
+       {
+         struct bfd_elf_version_expr *e2;
+
+         for (e2 = t->globals; e2 != NULL; e2 = e2->next)
+           if (strcmp (e1->match, e2->match) == 0)
+             einfo ("%X%P: duplicate expression `%s' in version information\n",
+                    e1->match);
+
+         for (e2 = t->locals; e2 != NULL; e2 = e2->next)
+           if (strcmp (e1->match, e2->match) == 0)
+             einfo ("%X%P: duplicate expression `%s' in version information\n",
+                    e1->match);
+       }
+    }
+
+  version->deps = deps;
+  version->name = name;
+  ++version_index;
+  version->vernum = version_index;
+
+  for (pp = &lang_elf_version_info; *pp != NULL; pp = &(*pp)->next)
+    ;
+  *pp = version;
+}
+
+/* This is called when we see a version dependency.  */
+
+struct bfd_elf_version_deps *
+lang_add_vers_depend (list, name)
+     struct bfd_elf_version_deps *list;
+     const char *name;
+{
+  struct bfd_elf_version_deps *ret;
+  struct bfd_elf_version_tree *t;
+
+  ret = (struct bfd_elf_version_deps *) xmalloc (sizeof *ret);
+  ret->next = list;
+
+  for (t = lang_elf_version_info; t != NULL; t = t->next)
+    {
+      if (strcmp (t->name, name) == 0)
+       {
+         ret->version_needed = t;
+         return ret;
+       }
+    }
+
+  einfo ("%X%P: unable to find version dependency `%s'\n", name);
+
+  return ret;
+}