/* VAX series support for 32-bit ELF
Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Matt Thomas <matt@3am-software.com>.
This file is part of BFD, the Binary File Descriptor library.
Elf_Internal_Sym *);
static bfd_boolean elf_vax_finish_dynamic_sections (bfd *,
struct bfd_link_info *);
+static bfd_vma elf_vax_plt_sym_val (bfd_vma, const asection *,
+ const arelent *);
static bfd_boolean elf32_vax_set_private_flags (bfd *, flagword);
static bfd_boolean elf32_vax_merge_private_bfd_data (bfd *, bfd *);
static const bfd_byte elf_vax_plt_entry[PLT_ENTRY_SIZE] =
{
- 0x40, 0x00, /* .word ^M<r6> */
+ 0xfc, 0x0f, /* .word ^M<r11:r2> */
0x16, 0xef, /* jsb L^(pc) */
0, 0, 0, 0, /* replaced with offset to start of .plt */
0, 0, 0, 0, /* index into .rela.plt */
|| h == elf_hash_table (info)->hplt)
break;
+ /* If this is a local symbol, we resolve it directly without
+ creating a global offset table entry. */
+ if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ break;
+
/* This symbol requires a global offset table entry. */
if (dynobj == NULL)
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
BFD_ASSERT (h != NULL);
- if (h->forced_local)
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT || h->forced_local)
break;
h->needs_plt = 1;
&& (!info->symbolic
|| !h->def_regular)))
{
- if (h != NULL && !h->forced_local)
+ if (h != NULL
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && !h->forced_local)
{
/* Make sure a plt entry is created for this symbol if
it turns out to be a function defined by a dynamic
}
break;
}
- if (h != NULL && h->forced_local)
+ /* If this is a local symbol, we can resolve it directly. */
+ if (h != NULL
+ && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || h->forced_local))
break;
/* Fall through. */
case R_VAX_8:
case R_VAX_16:
case R_VAX_32:
- if (h != NULL)
+ if (h != NULL && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
{
/* Make sure a plt entry is created for this symbol if it
turns out to be a function defined by a dynamic object. */
}
else if (h->got.refcount > 0)
{
+ bfd_boolean dyn;
+
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
return FALSE;
}
+ dyn = elf_hash_table (info)->dynamic_sections_created;
/* Allocate space in the .got and .rela.got sections. */
- sgot->size += 4;
- srelgot->size += sizeof (Elf32_External_Rela);
+ if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ {
+ sgot->size += 4;
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
}
return TRUE;
case R_VAX_GOT32:
/* Relocation is to the address of the entry for this symbol
in the global offset table. */
- if (h == NULL || h->got.offset == (bfd_vma) -1 || h->forced_local)
+ if (h == NULL
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || h->got.offset == (bfd_vma) -1
+ || h->forced_local)
break;
/* Relocation is the offset of the entry for this symbol in
the global offset table. */
{
+ bfd_boolean dyn;
bfd_vma off;
if (sgot == NULL)
BFD_ASSERT (off != (bfd_vma) -1);
BFD_ASSERT (off < sgot->size);
- if (info->shared
- && h->dynindx == -1
- && h->def_regular)
+ dyn = elf_hash_table (info)->dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h)))
{
/* The symbol was forced to be local
because of a version file.. We must initialize
}
break;
+ case R_VAX_PC32:
+ /* If we are creating an executable and the function this
+ reloc refers to is in a shared lib, then we made a PLT
+ entry for this symbol and need to handle the reloc like
+ a PLT reloc. */
+ if (info->shared)
+ goto r_vax_pc32_shared;
+ /* Fall through. */
case R_VAX_PLT32:
/* Relocation is to the entry for this symbol in the
procedure linkage table. */
/* Resolve a PLTxx reloc against a local symbol directly,
without using the procedure linkage table. */
- if (h == NULL || h->forced_local)
+ if (h == NULL
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || h->forced_local)
break;
if (h->plt.offset == (bfd_vma) -1
case R_VAX_PC8:
case R_VAX_PC16:
- case R_VAX_PC32:
- if (h == NULL || h->forced_local)
+ r_vax_pc32_shared:
+ if (h == NULL
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || h->forced_local)
break;
/* Fall through. */
case R_VAX_8:
return TRUE;
}
+static enum elf_reloc_type_class
+elf_vax_reloc_type_class (const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_VAX_RELATIVE:
+ return reloc_class_relative;
+ case R_VAX_JMP_SLOT:
+ return reloc_class_plt;
+ case R_VAX_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+static bfd_vma
+elf_vax_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
#define TARGET_LITTLE_SYM bfd_elf32_vax_vec
#define TARGET_LITTLE_NAME "elf32-vax"
#define ELF_MACHINE_CODE EM_VAX
elf_vax_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
elf_vax_finish_dynamic_sections
+#define elf_backend_reloc_type_class elf_vax_reloc_type_class
#define elf_backend_gc_mark_hook elf_vax_gc_mark_hook
#define elf_backend_gc_sweep_hook elf_vax_gc_sweep_hook
+#define elf_backend_plt_sym_val elf_vax_plt_sym_val
#define bfd_elf32_bfd_merge_private_bfd_data \
elf32_vax_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags \