* elf32-hppa.c (hppa_type_of_stub): Correct and simplify condition
authorAlan Modra <amodra@gmail.com>
Tue, 23 Apr 2002 05:11:23 +0000 (05:11 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 23 Apr 2002 05:11:23 +0000 (05:11 +0000)
under which a plt call stub is used.
(final_link_relocate): Similarly.
(allocate_plt_static): Clear h-plabel except when plt entry is
exclusively used for a plabel.
(allocate_dynrelocs): Use the above to simplify plt sizing.
(struct elf32_hppa_link_hash_table): Add has_22bit_branch.
(elf32_hppa_link_hash_table_create): Init.
(BL22_RP): Define.
(hppa_build_one_stub): Use BL22_RP if has_22bit_branch.
(elf32_hppa_check_relocs): Set has_22bit_branch.

* elf32-hppa.c (elf32_hppa_check_relocs): Remove debug message.
(final_link_relocate): Likewise.

bfd/ChangeLog
bfd/elf32-hppa.c

index bc5543a26e144e1eda8096879ac67847782bb002..eed424041af5a0b0c3725a9c46f50cf2c8783d8f 100644 (file)
@@ -1,3 +1,20 @@
+2002-04-23  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf32-hppa.c (hppa_type_of_stub): Correct and simplify condition
+       under which a plt call stub is used.
+       (final_link_relocate): Similarly.
+       (allocate_plt_static): Clear h-plabel except when plt entry is
+       exclusively used for a plabel.
+       (allocate_dynrelocs): Use the above to simplify plt sizing.
+       (struct elf32_hppa_link_hash_table): Add has_22bit_branch.
+       (elf32_hppa_link_hash_table_create): Init.
+       (BL22_RP): Define.
+       (hppa_build_one_stub): Use BL22_RP if has_22bit_branch.
+       (elf32_hppa_check_relocs): Set has_22bit_branch.
+
+       * elf32-hppa.c (elf32_hppa_check_relocs): Remove debug message.
+       (final_link_relocate): Likewise.
+
 2002-04-22  Jakub Jelinek  <jakub@redhat.com>
 
        * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't build
index 60ca08d7b19145f8e416366b0bc420f3776b6e2f..e0b317b5f320246fb404a39f6a0c3dd051edd4bc 100644 (file)
@@ -203,9 +203,6 @@ struct elf32_hppa_link_hash_entry {
 #endif
   } *dyn_relocs;
 
-  /* Set during a static link if we detect a function is PIC.  */
-  unsigned int maybe_pic_call:1;
-
   /* Set if the only reason we need a .plt entry is for a non-PIC to
      PIC function call.  */
   unsigned int pic_call:1;
@@ -255,10 +252,11 @@ struct elf32_hppa_link_hash_table {
   /* Whether we support multiple sub-spaces for shared libs.  */
   unsigned int multi_subspace:1;
 
-  /* Flags set when PCREL12F and PCREL17F branches detected.  Used to
+  /* Flags set when various size branches are detected.  Used to
      select suitable defaults for the stub group size.  */
   unsigned int has_12bit_branch:1;
   unsigned int has_17bit_branch:1;
+  unsigned int has_22bit_branch:1;
 
   /* Set if we need a .plt stub to support lazy dynamic linking.  */
   unsigned int need_plt_stub:1;
@@ -460,7 +458,6 @@ hppa_link_hash_newfunc (entry, table, string)
       eh = (struct elf32_hppa_link_hash_entry *) entry;
       eh->stub_cache = NULL;
       eh->dyn_relocs = NULL;
-      eh->maybe_pic_call = 0;
       eh->pic_call = 0;
       eh->plabel = 0;
     }
@@ -508,6 +505,7 @@ elf32_hppa_link_hash_table_create (abfd)
   ret->multi_subspace = 0;
   ret->has_12bit_branch = 0;
   ret->has_17bit_branch = 0;
+  ret->has_22bit_branch = 0;
   ret->need_plt_stub = 0;
   ret->sym_sec.abfd = NULL;
 
@@ -683,21 +681,12 @@ hppa_type_of_stub (input_sec, rel, hash, destination)
   unsigned int r_type;
 
   if (hash != NULL
-      && (((hash->elf.root.type == bfd_link_hash_defined
-           || hash->elf.root.type == bfd_link_hash_defweak)
-          && hash->elf.root.u.def.section->output_section == NULL)
-         || (hash->elf.root.type == bfd_link_hash_defweak
-             && hash->elf.dynindx != -1
-             && hash->elf.plt.offset != (bfd_vma) -1)
-         || hash->elf.root.type == bfd_link_hash_undefweak
-         || hash->elf.root.type == bfd_link_hash_undefined
-         || (hash->maybe_pic_call && !(input_sec->flags & SEC_HAS_GOT_REF))))
+      && hash->elf.plt.offset != (bfd_vma) -1
+      && (hash->elf.dynindx != -1 || hash->pic_call)
+      && !hash->plabel)
     {
-      /* If output_section is NULL, then it's a symbol defined in a
-        shared library.  We will need an import stub.  Decide between
-        hppa_stub_import and hppa_stub_import_shared later.  For
-        shared links we need stubs for undefined or weak syms too;
-        They will presumably be resolved by the dynamic linker.  */
+      /* We need an import stub.  Decide between hppa_stub_import
+        and hppa_stub_import_shared later.  */
       return hppa_stub_import;
     }
 
@@ -755,6 +744,7 @@ hppa_type_of_stub (input_sec, rel, hash, destination)
 #define BE_SR0_R21     0xe2a00000      /* be    0(%sr0,%r21)           */
 #define STW_RP         0x6bc23fd1      /* stw   %rp,-24(%sr0,%sp)      */
 
+#define BL22_RP                0xe800a002      /* b,l,n XXX,%rp                */
 #define BL_RP          0xe8400002      /* b,l,n XXX,%rp                */
 #define NOP            0x08000240      /* nop                          */
 #define LDW_RP         0x4bc23fd1      /* ldw   -24(%sr0,%sp),%rp      */
@@ -944,7 +934,9 @@ hppa_build_one_stub (gen_entry, in_arg)
                    + stub_sec->output_offset
                    + stub_sec->output_section->vma);
 
-      if (sym_value - 8 + 0x40000 >= 0x80000)
+      if (sym_value - 8 + (1 << (17 + 1)) >= (1 << (17 + 2))
+         && (!htab->has_22bit_branch
+             || sym_value - 8 + (1 << (22 + 1)) >= (1 << (22 + 2))))
        {
          (*_bfd_error_handler)
            (_("%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"),
@@ -957,7 +949,10 @@ hppa_build_one_stub (gen_entry, in_arg)
        }
 
       val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_fsel) >> 2;
-      insn = hppa_rebuild_insn ((int) BL_RP, val, 17);
+      if (!htab->has_22bit_branch)
+       insn = hppa_rebuild_insn ((int) BL_RP, val, 17);
+      else
+       insn = hppa_rebuild_insn ((int) BL22_RP, val, 22);
       bfd_put_32 (stub_bfd, insn, loc);
 
       bfd_put_32 (stub_bfd, (bfd_vma) NOP,         loc + 4);
@@ -1276,12 +1271,16 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
 
        case R_PARISC_PCREL12F:
          htab->has_12bit_branch = 1;
-         /* Fall thru.  */
+         goto branch_common;
+
        case R_PARISC_PCREL17C:
        case R_PARISC_PCREL17F:
          htab->has_17bit_branch = 1;
-         /* Fall thru.  */
+         goto branch_common;
+
        case R_PARISC_PCREL22F:
+         htab->has_22bit_branch = 1;
+       branch_common:
          /* Function calls might need to go through the .plt, and
             might require long branch stubs.  */
          if (h == NULL)
@@ -1335,7 +1334,7 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
        case R_PARISC_DIR14F: /* Used for load/store from absolute locn.  */
        case R_PARISC_DIR14R:
        case R_PARISC_DIR21L: /* As above, and for ext branches too.  */
-#if 1
+#if 0
          /* Help debug shared library creation.  Any of the above
             relocs can be used in shared libs, but they may cause
             pages to become unshared.  */
@@ -1851,19 +1850,10 @@ elf32_hppa_adjust_dynamic_symbol (info, h)
   unsigned int power_of_two;
 
   /* If this is a function, put it in the procedure linkage table.  We
-     will fill in the contents of the procedure linkage table later,
-     when we know the address of the .got section.  */
+     will fill in the contents of the procedure linkage table later.  */
   if (h->type == STT_FUNC
       || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
     {
-      if (!info->shared
-         && h->plt.refcount > 0
-         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
-         && (h->root.u.def.section->flags & SEC_HAS_GOT_REF) != 0)
-       {
-         ((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call = 1;
-       }
-
       if (h->plt.refcount <= 0
          || ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
              && h->root.type != bfd_link_hash_defweak
@@ -1880,7 +1870,10 @@ elf32_hppa_adjust_dynamic_symbol (info, h)
 
          /* As a special sop to the hppa ABI, we keep a .plt entry
             for functions in sections containing PIC code.  */
-         if (((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call)
+         if (!info->shared
+             && h->plt.refcount > 0
+             && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
+             && (h->root.u.def.section->flags & SEC_HAS_GOT_REF) != 0)
            ((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1;
          else
            {
@@ -2009,7 +2002,6 @@ mark_PIC_calls (h, inf)
     }
 
   h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-  ((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call = 1;
   ((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1;
 
   return true;
@@ -2039,6 +2031,7 @@ allocate_plt_static (h, inf)
     {
       /* Make an entry in the .plt section for non-pic code that is
         calling pic code.  */
+      ((struct elf32_hppa_link_hash_entry *) h)->plabel = 0;
       s = htab->splt;
       h->plt.offset = s->_raw_size;
       s->_raw_size += PLT_ENTRY_SIZE;
@@ -2058,7 +2051,11 @@ allocate_plt_static (h, inf)
 
       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
        {
-         /* Allocate these later.  */
+         /* Allocate these later.  From this point on, h->plabel
+            means that the plt entry is only used by a plabel.
+            We'll be using a normal plt entry for this symbol, so
+            clear the plabel indicator.  */
+         ((struct elf32_hppa_link_hash_entry *) h)->plabel = 0;
        }
       else if (((struct elf32_hppa_link_hash_entry *) h)->plabel)
        {
@@ -2109,7 +2106,7 @@ allocate_dynrelocs (h, inf)
   if (htab->elf.dynamic_sections_created
       && h->plt.offset != (bfd_vma) -1
       && !((struct elf32_hppa_link_hash_entry *) h)->pic_call
-      && WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
+      && !((struct elf32_hppa_link_hash_entry *) h)->plabel)
     {
       /* Make an entry in the .plt section.  */
       s = htab->splt;
@@ -3359,19 +3356,14 @@ final_link_relocate (input_section, contents, rel, value, htab, sym_sec, h)
     case R_PARISC_PCREL12F:
     case R_PARISC_PCREL17F:
     case R_PARISC_PCREL22F:
-      /* If this is a call to a function defined in another dynamic
-        library, or if it is a call to a PIC function in the same
-        object, or if this is a shared link and it is a call to a
-        weak symbol which may or may not be in the same object, then
-        find the import stub in the stub hash.  */
+      /* If this call should go via the plt, find the import stub in
+        the stub hash.  */
       if (sym_sec == NULL
          || sym_sec->output_section == NULL
          || (h != NULL
-             && ((h->maybe_pic_call
-                  && !(input_section->flags & SEC_HAS_GOT_REF))
-                 || (h->elf.root.type == bfd_link_hash_defweak
-                     && h->elf.dynindx != -1
-                     && h->elf.plt.offset != (bfd_vma) -1))))
+             && h->elf.plt.offset != (bfd_vma) -1
+             && (h->elf.dynindx != -1 || h->pic_call)
+             && !h->plabel))
        {
          stub_entry = hppa_get_stub_entry (input_section, sym_sec,
                                            h, rel, htab);
@@ -3426,7 +3418,7 @@ final_link_relocate (input_section, contents, rel, value, htab, sym_sec, h)
              == (((int) OP_ADDIL << 26) | (27 << 21)))
            {
              insn &= ~ (0x1f << 21);
-#if 1 /* debug them.  */
+#if 0 /* debug them.  */
              (*_bfd_error_handler)
                (_("%s(%s+0x%lx): fixing %s"),
                 bfd_archive_filename (input_bfd),