* elf32-i386.c (elf_backend_plt_readonly): Set correctly, to 1.
authorIan Lance Taylor <ian@airs.com>
Mon, 27 Nov 1995 17:42:27 +0000 (17:42 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 27 Nov 1995 17:42:27 +0000 (17:42 +0000)
* elf32-sparc.c (elf_backend_plt_readonly): Set correctly, to 0.
PR 8513.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf32-sparc.c

index 823a31e..01f1854 100644 (file)
@@ -1,3 +1,8 @@
+Mon Nov 27 12:27:46 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * elf32-i386.c (elf_backend_plt_readonly): Set correctly, to 1.
+       * elf32-sparc.c (elf_backend_plt_readonly): Set correctly, to 0.
+
 Wed Nov 22 12:02:09 1995  Ian Lance Taylor  <ian@cygnus.com>
 
        * ecoff.c (_bfd_ecoff_new_section_hook): Handle .rconst section.
index e206516..3dc2970 100644 (file)
@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "sysdep.h"
 #include "bfdlink.h"
 #include "libbfd.h"
-#include "libelf.h"
+#include "elf-bfd.h"
 
 static reloc_howto_type *elf_i386_reloc_type_lookup
   PARAMS ((bfd *, bfd_reloc_code_real_type));
@@ -275,7 +275,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
-      long r_symndx;
+      unsigned long r_symndx;
       struct elf_link_hash_entry *h;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
@@ -358,7 +358,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
              if (local_got_offsets == NULL)
                {
                  size_t size;
-                 register int i;
+                 register unsigned int i;
 
                  size = symtab_hdr->sh_info * sizeof (bfd_vma);
                  local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
@@ -418,7 +418,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
        case R_386_PC32:
          if (info->shared
              && (sec->flags & SEC_ALLOC) != 0
-             && (r_type != R_386_PC32 || h != NULL))
+             && (ELF32_R_TYPE (rel->r_info) != R_386_PC32 || h != NULL))
            {
              /* When creating a shared object, we must copy these
                  reloc types into the output file.  We create a reloc
@@ -848,7 +848,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
     {
       int r_type;
       reloc_howto_type *howto;
-      long r_symndx;
+      unsigned long r_symndx;
       struct elf_link_hash_entry *h;
       Elf_Internal_Sym *sym;
       asection *sec;
@@ -1143,7 +1143,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
                    outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
                  else
                    {
-                     BFD_ASSERT (h->dynindx != (bfd_vma) -1);
+                     BFD_ASSERT (h->dynindx != -1);
                      outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_32);
                    }
                }
@@ -1519,7 +1519,7 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
 #define elf_backend_finish_dynamic_sections \
                                        elf_i386_finish_dynamic_sections
 #define elf_backend_want_got_plt 1
-#define elf_backend_plt_readonly 0
+#define elf_backend_plt_readonly 1
 #define elf_backend_want_plt_sym 0
 
 #include "elf32-target.h"
index a3dca6a..c3ac311 100644 (file)
@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "sysdep.h"
 #include "bfdlink.h"
 #include "libbfd.h"
-#include "libelf.h"
+#include "elf-bfd.h"
 
 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
   PARAMS ((bfd *, bfd_reloc_code_real_type));
@@ -148,7 +148,7 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
      bfd *abfd;
      bfd_reloc_code_real_type code;
 {
-  int i;
+  unsigned int i;
   for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++)
     {
       if (sparc_reloc_map[i].bfd_reloc_val == code)
@@ -231,7 +231,7 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
-      long r_symndx;
+      unsigned long r_symndx;
       struct elf_link_hash_entry *h;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
@@ -305,7 +305,7 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
              if (local_got_offsets == NULL)
                {
                  size_t size;
-                 register int i;
+                 register unsigned int i;
 
                  size = symtab_hdr->sh_info * sizeof (bfd_vma);
                  local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
@@ -370,14 +370,17 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
              && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
            break;
          /* Fall through.  */
-       case R_SPARC_8:
-       case R_SPARC_16:
-       case R_SPARC_32:
        case R_SPARC_DISP8:
        case R_SPARC_DISP16:
        case R_SPARC_DISP32:
        case R_SPARC_WDISP30:
        case R_SPARC_WDISP22:
+         if (h == NULL)
+           break;
+         /* Fall through.  */
+       case R_SPARC_8:
+       case R_SPARC_16:
+       case R_SPARC_32:
        case R_SPARC_HI22:
        case R_SPARC_22:
        case R_SPARC_13:
@@ -453,6 +456,7 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL
              && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+                 || h->weakdef != NULL
                  || ((h->elf_link_hash_flags
                       & ELF_LINK_HASH_DEF_DYNAMIC) != 0
                      && (h->elf_link_hash_flags
@@ -838,7 +842,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
     {
       int r_type;
       reloc_howto_type *howto;
-      long r_symndx;
+      unsigned long r_symndx;
       struct elf_link_hash_entry *h;
       Elf_Internal_Sym *sym;
       asection *sec;
@@ -898,7 +902,11 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
                  || ((r_type == R_SPARC_GOT10
                       || r_type == R_SPARC_GOT13
                       || r_type == R_SPARC_GOT22)
-                     && elf_hash_table (info)->dynamic_sections_created)
+                     && elf_hash_table (info)->dynamic_sections_created
+                     && (! info->shared
+                         || ! info->symbolic
+                         || (h->elf_link_hash_flags
+                             & ELF_LINK_HASH_DEF_REGULAR) == 0))
                  || (info->shared
                      && (input_section->flags & SEC_ALLOC) != 0
                      && (r_type == R_SPARC_8
@@ -931,7 +939,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
            }
          else if (h->root.type == bfd_link_hash_undefweak)
            relocation = 0;
-         else if (info->shared)
+         else if (info->shared && !info->symbolic)
            relocation = 0;
          else
            {
@@ -963,13 +971,18 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
              off = h->got_offset;
              BFD_ASSERT (off != (bfd_vma) -1);
 
-             if (! elf_hash_table (info)->dynamic_sections_created)
+             if (! elf_hash_table (info)->dynamic_sections_created
+                 || (info->shared
+                     && info->symbolic
+                     && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
                {
-                 /* This is actually a static link.  We must
-                     initialize this entry in the global offset table.
-                     Since the offset must always be a multiple of 4,
-                     we use the least significant bit to record
-                     whether we have initialized it already.
+                 /* This is actually a static link, or it is a
+                     -Bsymbolic link and the symbol is defined
+                     locally.  We must initialize this entry in the
+                     global offset table.  Since the offset must
+                     always be a multiple of 4, we use the least
+                     significant bit to record whether we have
+                     initialized it already.
 
                     When doing a dynamic link, we create a .rela.got
                     relocation entry to initialize the value.  This
@@ -1042,7 +1055,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
          if (h->plt_offset == (bfd_vma) -1)
            {
              /* We didn't make a PLT entry for this symbol.  This
-                 happens when statically linking PIC code.  */
+                 happens when statically linking PIC code, or when
+                 using -Bsymbolic.  */
              break;
            }
 
@@ -1063,14 +1077,17 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
              && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
            break;
          /* Fall through.  */
-       case R_SPARC_8:
-       case R_SPARC_16:
-       case R_SPARC_32:
        case R_SPARC_DISP8:
        case R_SPARC_DISP16:
        case R_SPARC_DISP32:
        case R_SPARC_WDISP30:
        case R_SPARC_WDISP22:
+         if (h == NULL)
+           break;
+         /* Fall through.  */
+       case R_SPARC_8:
+       case R_SPARC_16:
+       case R_SPARC_32:
        case R_SPARC_HI22:
        case R_SPARC_22:
        case R_SPARC_13:
@@ -1280,12 +1297,24 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
       srela = bfd_get_section_by_name (dynobj, ".rela.got");
       BFD_ASSERT (sgot != NULL && srela != NULL);
 
-      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset);
-
       rela.r_offset = (sgot->output_section->vma
                       + sgot->output_offset
-                      + h->got_offset);
-      rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_GLOB_DAT);
+                      + (h->got_offset &~ 1));
+
+      /* If this is a -Bsymbolic link, and the symbol is defined
+        locally, we just want to emit a RELATIVE reloc.  The entry in
+        the global offset table will already have been initialized in
+        the relocate_section function.  */
+      if (info->shared
+         && info->symbolic
+         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+       rela.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
+      else
+       {
+         bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset);
+         rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_GLOB_DAT);
+       }
+
       rela.r_addend = 0;
       bfd_elf32_swap_reloca_out (output_bfd, &rela,
                                 ((Elf32_External_Rela *) srela->contents
@@ -1446,8 +1475,9 @@ elf32_sparc_finish_dynamic_sections (output_bfd, info)
          sym.st_shndx = indx;
 
          bfd_elf32_swap_symbol_out (output_bfd, &sym,
-(char*)                                     ((Elf32_External_Sym *) sdynsym->contents
-                                     + elf_section_data (s)->dynindx));
+                                    (PTR) (((Elf32_External_Sym *)
+                                            sdynsym->contents)
+                                           + elf_section_data (s)->dynindx));
        }
 
       /* Set the sh_info field of the output .dynsym section to the
@@ -1477,7 +1507,7 @@ elf32_sparc_finish_dynamic_sections (output_bfd, info)
 #define elf_backend_finish_dynamic_sections \
                                        elf32_sparc_finish_dynamic_sections
 #define elf_backend_want_got_plt 0
-#define elf_backend_plt_readonly 1
+#define elf_backend_plt_readonly 0
 #define elf_backend_want_plt_sym 1
 
 #include "elf32-target.h"