aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-sparc.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1995-11-27 17:42:27 +0000
committerIan Lance Taylor <ian@airs.com>1995-11-27 17:42:27 +0000
commit3b3f7625966bf05284a60fec702bac32dbaf8b36 (patch)
treeb1940c9555020fa6243d33fd43c4f6af414e7253 /bfd/elf32-sparc.c
parentd38644cd593c10fbbcd1b24d7a6873ff2ff07562 (diff)
downloadgdb-3b3f7625966bf05284a60fec702bac32dbaf8b36.zip
gdb-3b3f7625966bf05284a60fec702bac32dbaf8b36.tar.gz
gdb-3b3f7625966bf05284a60fec702bac32dbaf8b36.tar.bz2
* elf32-i386.c (elf_backend_plt_readonly): Set correctly, to 1.
* elf32-sparc.c (elf_backend_plt_readonly): Set correctly, to 0. PR 8513.
Diffstat (limited to 'bfd/elf32-sparc.c')
-rw-r--r--bfd/elf32-sparc.c84
1 files changed, 57 insertions, 27 deletions
diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c
index a3dca6a..c3ac311 100644
--- a/bfd/elf32-sparc.c
+++ b/bfd/elf32-sparc.c
@@ -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"