Find the first .init and .fini sections correctly.
authorAlan Modra <amodra@gmail.com>
Fri, 15 Sep 2000 10:24:50 +0000 (10:24 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 15 Sep 2000 10:24:50 +0000 (10:24 +0000)
Clobber millicode syms via a hash traversal here.  elf_adjust_dynamic_symbol
really ought to let us look at all dynamic symbols, but it doesn't.

bfd/ChangeLog
bfd/elf32-hppa.c

index d1d8b5be5aed409c246be809b6f27269051bf2f6..f0e8ea96d5e657c7c00704aa10dbd4c7c993b483 100644 (file)
@@ -1,3 +1,15 @@
+2000-09-15  Alan Modra  <alan@linuxcare.com.au>
+
+       * elf32-hppa.c (hppa_add_stub): Dont set first_init_sec and
+       first_fini_sec here.
+       (elf32_hppa_size_stubs): Instead correctly find the first .init
+       and .fini section here.
+
+2000-09-15  David Huggins-Daines  <dhd@linuxcare.com>
+
+       * elf32-hppa.c (clobber_millicode_symbols): New function.
+       (elf32_hppa_size_dynamic_sections): Call it.
+
 2000-09-14  Alan Modra  <alan@linuxcare.com.au>
 
        * elf32-hppa.c (elf32_hppa_link_hash_entry): Make pic_call
index e2f7e10d69bef1c91737ac5072624853d1716e82..5b2d1c915ba2b4cb7c3e83f0fa22bbed873ce498 100644 (file)
@@ -345,6 +345,9 @@ static boolean hppa_discard_copies
   PARAMS ((struct elf_link_hash_entry *, PTR));
 #endif
 
+static boolean clobber_millicode_symbols
+  PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *));
+
 static boolean elf32_hppa_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 
@@ -621,27 +624,11 @@ hppa_add_stub (stub_name, section, sec_count, info)
   stub_sec = hplink->stub_section_created[sec_count];
   if (stub_sec == NULL)
     {
-      int special_sec = 0;
-
-      /* We only want one stub for .init and .fini because glibc
-        splits the _init and _fini functions into two parts.  We
-        don't want to put a stub in the middle of a function.
-        It would be better to merge all the stub sections for an
-        output section if the output section + stubs is small enough.
-        This would fix the .init and .fini case and also allow stubs
-        to be merged.  It's more linker work though.  */
       if (strncmp (section->name, ".init", 5) == 0)
-       {
-         if (hplink->first_init_sec != 0)
-           stub_sec = hplink->stub_section_created[hplink->first_init_sec-1];
-         special_sec = 1;
-       }
+       stub_sec = hplink->stub_section_created[hplink->first_init_sec - 1];
       else if (strncmp (section->name, ".fini", 5) == 0)
-       {
-         if (hplink->first_fini_sec != 0)
-           stub_sec = hplink->stub_section_created[hplink->first_fini_sec-1];
-         special_sec = 2;
-       }
+       stub_sec = hplink->stub_section_created[hplink->first_fini_sec - 1];
+
       if (stub_sec == NULL)
        {
          size_t len;
@@ -657,14 +644,6 @@ hppa_add_stub (stub_name, section, sec_count, info)
          stub_sec = (*hplink->add_stub_section) (s_name, section);
          if (stub_sec == NULL)
            return NULL;
-
-         if (special_sec != 0)
-           {
-             if (special_sec == 1)
-               hplink->first_init_sec = sec_count + 1;
-             else
-               hplink->first_fini_sec = sec_count + 1;
-           }
        }
       hplink->stub_section_created[sec_count] = stub_sec;
     }
@@ -2127,6 +2106,27 @@ hppa_discard_copies (h, inf)
 #endif
 
 
+/* This function is called via elf_link_hash_traverse to force
+   millicode symbols local so they do not end up as globals in the
+   dynamic symbol table.  We ought to be able to do this in
+   adjust_dynamic_symbol, but our adjust_dynamic_symbol is not called
+   for all dynamic symbols.  Arguably, this is a bug in
+   elf_adjust_dynamic_symbol.  */
+
+static boolean
+clobber_millicode_symbols (h, info)
+     struct elf_link_hash_entry *h;
+     struct bfd_link_info *info;
+{
+  if (h->type == STT_PARISC_MILLI)
+    {
+      h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
+      elf32_hppa_hide_symbol(info, h);
+    }
+  return true;
+}
+
+
 /* Set the sizes of the dynamic sections.  */
 
 static boolean
@@ -2158,6 +2158,11 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
        }
 
+      /* Force millicode symbols local.  */
+      elf_link_hash_traverse (&hplink->root,
+                             clobber_millicode_symbols,
+                             info);
+
       /* DT_INIT and DT_FINI need a .plt entry.  Make sure they have
         one.  */
       funcname = info->init_function;
@@ -2511,6 +2516,50 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info,
       /* Now we can free the external symbols.  */
       free (ext_syms);
 
+      /* Go looking for .init and .fini sections.  We only want one
+        stub section for each of .init* and .fini* because glibc
+        splits the _init and _fini functions into multiple parts, and
+        putting a stub in the middle of a function is not a good idea.
+        It would be better to merge all the stub sections for an
+        output section if the output section + stubs is small enough.
+        This would fix the .init and .fini case and also allow stubs
+        to be merged.  It's more linker work though.  */
+      for (section = input_bfd->sections;
+          section != NULL;
+          section = section->next, sec_count++)
+       {
+         if (hplink->first_init_sec == 0)
+           {
+             if (strncmp (section->name, ".init", 5) == 0)
+               hplink->first_init_sec = sec_count + 1;
+           }
+         if (hplink->first_fini_sec == 0)
+           {
+             if (strncmp (section->name, ".fini", 5) == 0)
+               hplink->first_fini_sec = sec_count + 1;
+           }
+
+#if ! LONG_BRANCH_PIC_IN_SHLIB
+         /* If this is a shared link, find all the stub reloc
+            sections.  */
+         if (info->shared)
+           {
+             char *name;
+             asection *reloc_sec;
+
+             name = bfd_malloc (strlen (section->name)
+                                + sizeof STUB_SUFFIX
+                                + 5);
+             if (name == NULL)
+               return false;
+             sprintf (name, ".rela%s%s", section->name, STUB_SUFFIX);
+             reloc_sec = bfd_get_section_by_name (hplink->root.dynobj, name);
+             hplink->reloc_section_created[sec_count] = reloc_sec;
+             free (name);
+           }
+#endif
+       }
+
       if (info->shared && hplink->multi_subspace)
        {
          unsigned int symndx;
@@ -2558,7 +2607,8 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info,
                    {
                      stub_entry = hppa_add_stub (stub_name,
                                                  sec,
-                                                 sec_count + sec->index,
+                                                 (sec_count + sec->index
+                                                  - input_bfd->section_count),
                                                  info);
                      if (!stub_entry)
                        goto error_ret_free_local;
@@ -2578,30 +2628,6 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info,
                }
            }
        }
-#if LONG_BRANCH_PIC_IN_SHLIB
-      sec_count += input_bfd->section_count;
-#else
-      if (! info->shared)
-       sec_count += input_bfd->section_count;
-      else
-       for (section = input_bfd->sections;
-            section != NULL;
-            section = section->next, sec_count++)
-         {
-           char *name;
-           asection *reloc_sec;
-
-           name = bfd_malloc (strlen (section->name)
-                              + sizeof STUB_SUFFIX
-                              + 5);
-           if (name == NULL)
-             return false;
-           sprintf (name, ".rela%s%s", section->name, STUB_SUFFIX);
-           reloc_sec = bfd_get_section_by_name (hplink->root.dynobj, name);
-           hplink->reloc_section_created[sec_count] = reloc_sec;
-           free (name);
-         }
-#endif
     }
 
   while (1)
@@ -3735,11 +3761,6 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
   hplink = hppa_link_hash_table (info);
   dynobj = hplink->root.dynobj;
 
-  /* Millicode symbols should not be put in the dynamic
-     symbol table under any circumstances.  */
-  if (ELF_ST_TYPE (sym->st_info) == STT_PARISC_MILLI)
-    h->dynindx = -1;
-
   if (h->plt.offset != (bfd_vma) -1)
     {
       bfd_vma value;