/* VAX series support for 32-bit ELF
- Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Matt Thomas <matt@3am-software.com>.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/vax.h"
-static reloc_howto_type *reloc_type_lookup
- PARAMS ((bfd *, bfd_reloc_code_real_type));
-static void rtype_to_howto
- PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
-static struct bfd_hash_entry *elf_vax_link_hash_newfunc
- PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-static struct bfd_link_hash_table *elf_vax_link_hash_table_create
- PARAMS ((bfd *));
-static boolean elf_vax_check_relocs
- PARAMS ((bfd *, struct bfd_link_info *, asection *,
- const Elf_Internal_Rela *));
-static asection *elf_vax_gc_mark_hook
- PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
- struct elf_link_hash_entry *, Elf_Internal_Sym *));
-static boolean elf_vax_gc_sweep_hook
- PARAMS ((bfd *, struct bfd_link_info *, asection *,
- const Elf_Internal_Rela *));
-static boolean elf_vax_adjust_dynamic_symbol
- PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
-static boolean elf_vax_size_dynamic_sections
- PARAMS ((bfd *, struct bfd_link_info *));
-static boolean elf_vax_relocate_section
- PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
- Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
-static boolean elf_vax_finish_dynamic_symbol
- PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
- Elf_Internal_Sym *));
-static boolean elf_vax_finish_dynamic_sections
- PARAMS ((bfd *, struct bfd_link_info *));
-
-static boolean elf32_vax_set_private_flags
- PARAMS ((bfd *, flagword));
-static boolean elf32_vax_merge_private_bfd_data
- PARAMS ((bfd *, bfd *));
-static boolean elf32_vax_print_private_bfd_data
- PARAMS ((bfd *, PTR));
+static reloc_howto_type *reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
+static void rtype_to_howto (bfd *, arelent *, Elf_Internal_Rela *);
+static struct bfd_hash_entry *elf_vax_link_hash_newfunc (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *);
+static struct bfd_link_hash_table *elf_vax_link_hash_table_create (bfd *);
+static bfd_boolean elf_vax_check_relocs (bfd *, struct bfd_link_info *,
+ asection *, const Elf_Internal_Rela *);
+static bfd_boolean elf_vax_adjust_dynamic_symbol (struct bfd_link_info *,
+ struct elf_link_hash_entry *);
+static bfd_boolean elf_vax_size_dynamic_sections (bfd *, struct bfd_link_info *);
+static bfd_boolean elf_vax_relocate_section (bfd *, struct bfd_link_info *,
+ bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *,
+ Elf_Internal_Sym *, asection **);
+static bfd_boolean elf_vax_finish_dynamic_symbol (bfd *, struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ 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 bfd_boolean elf32_vax_print_private_bfd_data (bfd *, PTR);
static reloc_howto_type howto_table[] = {
HOWTO (R_VAX_NONE, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_NONE", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0x00000000, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
HOWTO (R_VAX_32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_32", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
HOWTO (R_VAX_16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_16", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0x0000ffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
HOWTO (R_VAX_8, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_8", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0x000000ff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
HOWTO (R_VAX_PC32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_PC32", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
HOWTO (R_VAX_PC16, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_PC16", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0x0000ffff, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
HOWTO (R_VAX_PC8, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_PC8", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0x000000ff, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
HOWTO (R_VAX_GOT32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_GOT32", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
EMPTY_HOWTO (-1),
EMPTY_HOWTO (-1),
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_PLT32", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
EMPTY_HOWTO (-1),
EMPTY_HOWTO (-1),
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_COPY", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
HOWTO (R_VAX_GLOB_DAT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_GLOB_DAT", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
HOWTO (R_VAX_JMP_SLOT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_JMP_SLOT", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
HOWTO (R_VAX_RELATIVE, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_VAX_RELATIVE", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable hierarchy */
HOWTO (R_VAX_GNU_VTINHERIT, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
NULL, /* special_function */
"R_VAX_GNU_VTINHERIT", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
/* GNU extension to record C++ vtable member usage */
HOWTO (R_VAX_GNU_VTENTRY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- false, /* pc_relative */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_elf_rel_vtable_reloc_fn, /* special_function */
"R_VAX_GNU_VTENTRY", /* name */
- false, /* partial_inplace */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- false), /* pcrel_offset */
+ FALSE), /* pcrel_offset */
};
static void
-rtype_to_howto (abfd, cache_ptr, dst)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *cache_ptr;
- Elf_Internal_Rela *dst;
+rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
{
BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_VAX_max);
cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)];
};
static reloc_howto_type *
-reloc_type_lookup (abfd, code)
- bfd *abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
+reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
{
unsigned int i;
for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++)
return 0;
}
+static reloc_howto_type *
+reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup
#define ELF_ARCH bfd_arch_vax
/* end code generated by elf.el */
\f
static const bfd_byte elf_vax_plt_entry[PLT_ENTRY_SIZE] =
{
- 0x40, 0x00, /* .word ^M<r6> */
- 0x16, 0xef, /* jsb L^(pc) */
+ 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 */
};
bfd_vma got_addend;
};
-/* VAX ELF linker hash table. */
+/* Declare this now that the above structures are defined. */
-struct elf_vax_link_hash_table
-{
- struct elf_link_hash_table root;
-};
+static bfd_boolean elf_vax_discard_copies (struct elf_vax_link_hash_entry *,
+ void *);
/* Declare this now that the above structures are defined. */
-static boolean elf_vax_discard_copies
- PARAMS ((struct elf_vax_link_hash_entry *, PTR));
+static bfd_boolean elf_vax_instantiate_got_entries (struct elf_link_hash_entry *,
+ void *);
/* Traverse an VAX ELF linker hash table. */
#define elf_vax_link_hash_traverse(table, func, info) \
(elf_link_hash_traverse \
- (&(table)->root, \
- (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+ ((table), \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, PTR)) (func), \
(info)))
-/* Get the VAX ELF linker hash table from a link_info structure. */
-
-#define elf_vax_hash_table(p) \
- ((struct elf_vax_link_hash_table *) (p)->hash)
-
/* Create an entry in an VAX ELF linker hash table. */
static struct bfd_hash_entry *
-elf_vax_link_hash_newfunc (entry, table, string)
- struct bfd_hash_entry *entry;
- struct bfd_hash_table *table;
- const char *string;
+elf_vax_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
{
struct elf_vax_link_hash_entry *ret =
(struct elf_vax_link_hash_entry *) entry;
/* Allocate the structure if it has not already been allocated by a
subclass. */
- if (ret == (struct elf_vax_link_hash_entry *) NULL)
+ if (ret == NULL)
ret = ((struct elf_vax_link_hash_entry *)
bfd_hash_allocate (table,
sizeof (struct elf_vax_link_hash_entry)));
- if (ret == (struct elf_vax_link_hash_entry *) NULL)
+ if (ret == NULL)
return (struct bfd_hash_entry *) ret;
/* Call the allocation method of the superclass. */
ret = ((struct elf_vax_link_hash_entry *)
_bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
table, string));
- if (ret != (struct elf_vax_link_hash_entry *) NULL)
+ if (ret != NULL)
{
ret->pcrel_relocs_copied = NULL;
}
/* Create an VAX ELF linker hash table. */
static struct bfd_link_hash_table *
-elf_vax_link_hash_table_create (abfd)
- bfd *abfd;
+elf_vax_link_hash_table_create (bfd *abfd)
{
- struct elf_vax_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct elf_vax_link_hash_table);
+ struct elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_link_hash_table);
- ret = (struct elf_vax_link_hash_table *) bfd_malloc (amt);
- if (ret == (struct elf_vax_link_hash_table *) NULL)
+ ret = bfd_malloc (amt);
+ if (ret == NULL)
return NULL;
- if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
- elf_vax_link_hash_newfunc))
+ if (!_bfd_elf_link_hash_table_init (ret, abfd,
+ elf_vax_link_hash_newfunc,
+ sizeof (struct elf_vax_link_hash_entry),
+ GENERIC_ELF_DATA))
{
free (ret);
return NULL;
}
- return &ret->root.root;
+ return &ret->root;
}
/* Keep vax-specific flags in the ELF header */
-static boolean
-elf32_vax_set_private_flags (abfd, flags)
- bfd *abfd;
- flagword flags;
+static bfd_boolean
+elf32_vax_set_private_flags (bfd *abfd, flagword flags)
{
elf_elfheader (abfd)->e_flags = flags;
- elf_flags_init (abfd) = true;
- return true;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
}
/* Merge backend specific data from an object file to the output
object file when linking. */
-static boolean
-elf32_vax_merge_private_bfd_data (ibfd, obfd)
- bfd *ibfd;
- bfd *obfd;
+static bfd_boolean
+elf32_vax_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
{
- flagword out_flags;
flagword in_flags;
if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
- return true;
+ return TRUE;
in_flags = elf_elfheader (ibfd)->e_flags;
- out_flags = elf_elfheader (obfd)->e_flags;
if (!elf_flags_init (obfd))
{
- elf_flags_init (obfd) = true;
+ elf_flags_init (obfd) = TRUE;
elf_elfheader (obfd)->e_flags = in_flags;
}
- return true;
+ return TRUE;
}
/* Display the flags field */
-static boolean
-elf32_vax_print_private_bfd_data (abfd, ptr)
- bfd *abfd;
- PTR ptr;
+static bfd_boolean
+elf32_vax_print_private_bfd_data (bfd *abfd, PTR ptr)
{
FILE *file = (FILE *) ptr;
fputc ('\n', file);
- return true;
+ return TRUE;
}
/* Look through the relocs for a section during the first phase, and
allocate space in the global offset table or procedure linkage
table. */
-static boolean
-elf_vax_check_relocs (abfd, info, sec, relocs)
- bfd *abfd;
- struct bfd_link_info *info;
- asection *sec;
- const Elf_Internal_Rela *relocs;
+static bfd_boolean
+elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
+ const Elf_Internal_Rela *relocs)
{
bfd *dynobj;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
- bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
asection *sgot;
asection *srelgot;
asection *sreloc;
- if (info->relocateable)
- return true;
+ if (info->relocatable)
+ return TRUE;
dynobj = elf_hash_table (info)->dynobj;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
- local_got_refcounts = elf_local_got_refcounts (abfd);
sgot = NULL;
srelgot = NULL;
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
switch (ELF32_R_TYPE (rel->r_info))
{
case R_VAX_GOT32:
- if (h != NULL
- && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ BFD_ASSERT (h != NULL);
+ if (h->forced_local
+ || h == elf_hash_table (info)->hgot
+ || 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. */
/* Create the .got section. */
elf_hash_table (info)->dynobj = dynobj = abfd;
if (!_bfd_elf_create_got_section (dynobj, info))
- return false;
+ return FALSE;
}
if (sgot == NULL)
srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
if (srelgot == NULL)
{
- srelgot = bfd_make_section (dynobj, ".rela.got");
+ srelgot = bfd_make_section_with_flags (dynobj,
+ ".rela.got",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
if (srelgot == NULL
- || !bfd_set_section_flags (dynobj, srelgot,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY))
|| !bfd_set_section_alignment (dynobj, srelgot, 2))
- return false;
+ return FALSE;
}
}
{
h->got.refcount = 1;
eh->got_addend = rel->r_addend;
-
- /* Make sure this symbol is output as a dynamic symbol. */
- if (h->dynindx == -1)
- {
- if (!bfd_elf32_link_record_dynamic_symbol (info, h))
- return false;
- }
-
- /* Allocate space in the .got section. */
- sgot->_raw_size += 4;
- /* Allocate relocation space. */
- srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
else
{
h->got.refcount++;
if (eh->got_addend != (bfd_vma) rel->r_addend)
(*_bfd_error_handler)
- (_("%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"),
- bfd_get_filename (abfd), rel->r_addend,
- h->root.root.string,
- eh->got_addend);
+ (_("%s: warning: GOT addend of %ld to `%s' does"
+ " not match previous GOT addend of %ld"),
+ bfd_get_filename (abfd), rel->r_addend,
+ h->root.root.string,
+ eh->got_addend);
}
}
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
- if (h == NULL)
- continue;
+ BFD_ASSERT (h != NULL);
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT || h->forced_local)
+ break;
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->needs_plt = 1;
if (h->plt.refcount == -1)
h->plt.refcount = 1;
else
&& (sec->flags & SEC_ALLOC) != 0
&& h != NULL
&& (!info->symbolic
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+ || !h->def_regular)))
{
- if (h != NULL)
+ 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 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. */
section in dynobj and make room for this reloc. */
if (sreloc == NULL)
{
- const char *name;
-
- name = (bfd_elf_string_from_elf_section
- (abfd,
- elf_elfheader (abfd)->e_shstrndx,
- elf_section_data (sec)->rel_hdr.sh_name));
- if (name == NULL)
- return false;
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
- BFD_ASSERT (strncmp (name, ".rela", 5) == 0
- && strcmp (bfd_get_section_name (abfd, sec),
- name + 5) == 0);
-
- sreloc = bfd_get_section_by_name (dynobj, name);
if (sreloc == NULL)
- {
- sreloc = bfd_make_section (dynobj, name);
- if (sreloc == NULL
- || !bfd_set_section_flags (dynobj, sreloc,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY))
- || !bfd_set_section_alignment (dynobj, sreloc, 2))
- return false;
- }
+ return FALSE;
+
if (sec->flags & SEC_READONLY)
info->flags |= DF_TEXTREL;
}
- sreloc->_raw_size += sizeof (Elf32_External_Rela);
+ sreloc->size += sizeof (Elf32_External_Rela);
/* If we are linking with -Bsymbolic, we count the number of
PC relative relocations we have entered for this symbol,
so that we can discard them again if the symbol is later
defined by a regular object. Note that this function is
- only called if we are using an vaxelf linker hash table,
+ only called if we are using a vaxelf linker hash table,
which means that h is really a pointer to an
elf_vax_link_hash_entry. */
if ((ELF32_R_TYPE (rel->r_info) == R_VAX_PC8
- || ELF32_R_TYPE (rel->r_info) == R_VAX_PC16
- || ELF32_R_TYPE (rel->r_info) == R_VAX_PC32)
+ || ELF32_R_TYPE (rel->r_info) == R_VAX_PC16
+ || ELF32_R_TYPE (rel->r_info) == R_VAX_PC32)
&& info->symbolic)
{
struct elf_vax_link_hash_entry *eh;
p = ((struct elf_vax_pcrel_relocs_copied *)
bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
if (p == NULL)
- return false;
+ return FALSE;
p->next = eh->pcrel_relocs_copied;
eh->pcrel_relocs_copied = p;
p->section = sreloc;
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
case R_VAX_GNU_VTINHERIT:
- if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
- return false;
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return FALSE;
break;
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_VAX_GNU_VTENTRY:
- if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
- return false;
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
break;
default:
}
}
- return true;
+ return TRUE;
}
/* Return the section that should be marked against GC for a given
relocation. */
static asection *
-elf_vax_gc_mark_hook (sec, info, rel, h, sym)
- asection *sec;
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
- Elf_Internal_Rela *rel;
- struct elf_link_hash_entry *h;
- Elf_Internal_Sym *sym;
+elf_vax_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
{
if (h != NULL)
- {
- switch (ELF32_R_TYPE (rel->r_info))
- {
- case R_VAX_GNU_VTINHERIT:
- case R_VAX_GNU_VTENTRY:
- break;
-
- default:
- switch (h->root.type)
- {
- default:
- break;
-
- case bfd_link_hash_defined:
- case bfd_link_hash_defweak:
- return h->root.u.def.section;
-
- case bfd_link_hash_common:
- return h->root.u.c.p->section;
- }
- }
- }
- else
- return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-
- return NULL;
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_VAX_GNU_VTINHERIT:
+ case R_VAX_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}
/* Update the got entry reference counts for the section being removed. */
-static boolean
-elf_vax_gc_sweep_hook (abfd, info, sec, relocs)
- bfd *abfd;
- struct bfd_link_info *info;
- asection *sec;
- const Elf_Internal_Rela *relocs;
+static bfd_boolean
+elf_vax_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, asection *sec,
+ const Elf_Internal_Rela *relocs)
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
- bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
- unsigned long r_symndx;
- struct elf_link_hash_entry *h;
bfd *dynobj;
- asection *sgot;
- asection *srelgot;
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- sym_hashes = elf_sym_hashes (abfd);
- local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (info->relocatable)
+ return TRUE;
dynobj = elf_hash_table (info)->dynobj;
if (dynobj == NULL)
- return true;
+ return TRUE;
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
{
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
+
switch (ELF32_R_TYPE (rel->r_info))
{
case R_VAX_GOT32:
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- if (h->got.refcount > 0)
- {
- --h->got.refcount;
- if (h->got.refcount == 0)
- {
- /* We don't need the .got entry any more. */
- sgot->_raw_size -= 4;
- srelgot->_raw_size -= sizeof (Elf32_External_Rela);
- }
- }
- }
- else if (local_got_refcounts != NULL)
- {
- if (local_got_refcounts[r_symndx] > 0)
- {
- --local_got_refcounts[r_symndx];
- if (local_got_refcounts[r_symndx] == 0)
- {
- /* We don't need the .got entry any more. */
- sgot->_raw_size -= 4;
- if (info->shared)
- srelgot->_raw_size -= sizeof (Elf32_External_Rela);
- }
- }
- }
+ if (h != NULL && h->got.refcount > 0)
+ --h->got.refcount;
break;
case R_VAX_PLT32:
case R_VAX_8:
case R_VAX_16:
case R_VAX_32:
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- if (h->plt.refcount > 0)
- --h->plt.refcount;
- }
+ if (h != NULL && h->plt.refcount > 0)
+ --h->plt.refcount;
break;
default:
}
}
- return true;
+ return TRUE;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
change the definition to something the rest of the link can
understand. */
-static boolean
+static bfd_boolean
elf_vax_adjust_dynamic_symbol (info, h)
struct bfd_link_info *info;
struct elf_link_hash_entry *h;
{
bfd *dynobj;
asection *s;
- unsigned int power_of_two;
dynobj = elf_hash_table (info)->dynobj;
/* 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
- & ELF_LINK_HASH_REF_REGULAR) != 0
- && (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
/* 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. */
if (h->type == STT_FUNC
- || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ || h->needs_plt)
{
if (! info->shared
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
- && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0
+ && !h->def_dynamic
+ && !h->ref_dynamic
/* We must always create the plt entry if it was referenced
by a PLTxxO relocation. In this case we already recorded
it as a dynamic symbol. */
object. In such a case, we don't actually need to build
a procedure linkage table, and we can just do a PCxx
reloc instead. */
- BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+ BFD_ASSERT (h->needs_plt);
h->plt.offset = (bfd_vma) -1;
- return true;
+ return TRUE;
}
/* GC may have rendered this entry unused. */
if (h->plt.refcount <= 0)
{
- h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+ h->needs_plt = 0;
h->plt.offset = (bfd_vma) -1;
- return true;
+ return TRUE;
}
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
- if (! bfd_elf32_link_record_dynamic_symbol (info, h))
- return false;
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
}
s = bfd_get_section_by_name (dynobj, ".plt");
/* If this is the first .plt entry, make room for the special
first entry. */
- if (s->_raw_size == 0)
+ if (s->size == 0)
{
- s->_raw_size += PLT_ENTRY_SIZE;
+ s->size += PLT_ENTRY_SIZE;
}
/* If this symbol is not defined in a regular file, and we are
pointers compare as equal between the normal executable and
the shared library. */
if (!info->shared
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ && !h->def_regular)
{
h->root.u.def.section = s;
- h->root.u.def.value = s->_raw_size;
+ h->root.u.def.value = s->size;
}
- h->plt.offset = s->_raw_size;
+ h->plt.offset = s->size;
/* Make room for this entry. */
- s->_raw_size += PLT_ENTRY_SIZE;
+ s->size += PLT_ENTRY_SIZE;
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
s = bfd_get_section_by_name (dynobj, ".got.plt");
BFD_ASSERT (s != NULL);
- s->_raw_size += 4;
+ s->size += 4;
/* We also need to make an entry in the .rela.plt section. */
s = bfd_get_section_by_name (dynobj, ".rela.plt");
BFD_ASSERT (s != NULL);
- s->_raw_size += sizeof (Elf32_External_Rela);
+ s->size += sizeof (Elf32_External_Rela);
- return true;
+ return TRUE;
}
/* Reinitialize the plt offset now that it is not used as a reference
/* If this is a weak symbol, and there is a real definition, the
processor independent code will have arranged for us to see the
real definition first, and we can just use the same value. */
- if (h->weakdef != NULL)
+ if (h->u.weakdef != NULL)
{
- BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
- || h->weakdef->root.type == bfd_link_hash_defweak);
- h->root.u.def.section = h->weakdef->root.u.def.section;
- h->root.u.def.value = h->weakdef->root.u.def.value;
- return true;
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ return TRUE;
}
/* This is a reference to a symbol defined by a dynamic object which
For such cases we need not do anything here; the relocations will
be handled correctly by relocate_section. */
if (info->shared)
- return true;
+ return TRUE;
+
+ if (h->size == 0)
+ {
+ (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
+ h->root.root.string);
+ return TRUE;
+ }
/* We must allocate the symbol in our .dynbss section, which will
become part of the .bss section of the executable. There will be
srel = bfd_get_section_by_name (dynobj, ".rela.bss");
BFD_ASSERT (srel != NULL);
- srel->_raw_size += sizeof (Elf32_External_Rela);
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
- }
-
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
- s->_raw_size = BFD_ALIGN (s->_raw_size,
- (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (dynobj, s))
- {
- if (!bfd_set_section_alignment (dynobj, s, power_of_two))
- return false;
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
}
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->_raw_size;
-
- /* Increment the section size to make room for the symbol. */
- s->_raw_size += h->size;
-
- return true;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Set the sizes of the dynamic sections. */
-static boolean
-elf_vax_size_dynamic_sections (output_bfd, info)
- bfd *output_bfd;
- struct bfd_link_info *info;
+static bfd_boolean
+elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
{
bfd *dynobj;
asection *s;
- boolean plt;
- boolean relocs;
- boolean reltext;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+ bfd_boolean reltext;
dynobj = elf_hash_table (info)->dynobj;
BFD_ASSERT (dynobj != NULL);
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (!info->shared)
+ if (info->executable)
{
s = bfd_get_section_by_name (dynobj, ".interp");
BFD_ASSERT (s != NULL);
- s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
}
}
file below. */
s = bfd_get_section_by_name (dynobj, ".rela.got");
if (s != NULL)
- s->_raw_size = 0;
+ s->size = 0;
s = bfd_get_section_by_name (dynobj, ".got.plt");
if (s != NULL)
- s->_raw_size = 0;
+ s->size = 0;
s = bfd_get_section_by_name (dynobj, ".got");
if (s != NULL)
- s->_raw_size = 0;
+ s->size = 0;
}
/* If this is a -Bsymbolic shared link, then we need to discard all PC
allocated space for them in the check_relocs routine, but we will not
fill them in in the relocate_section routine. */
if (info->shared && info->symbolic)
- elf_vax_link_hash_traverse (elf_vax_hash_table (info),
- elf_vax_discard_copies,
- (PTR) NULL);
+ elf_vax_link_hash_traverse (elf_hash_table (info),
+ elf_vax_discard_copies,
+ NULL);
+
+ /* If this is a -Bsymbolic shared link or a static link, we need to
+ discard all the got entries we've recorded. Otherwise, we need to
+ instantiate (allocate space for them). */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_vax_instantiate_got_entries,
+ (PTR) info);
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */
- plt = false;
- relocs = false;
- reltext = false;
+ plt = FALSE;
+ relocs = FALSE;
+ reltext = FALSE;
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char *name;
- boolean strip;
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
of the dynobj section names depend upon the input files. */
name = bfd_get_section_name (dynobj, s);
- strip = false;
-
if (strcmp (name, ".plt") == 0)
{
- if (s->_raw_size == 0)
- {
- /* Strip this section if we don't need it; see the
- comment below. */
- strip = true;
- }
- else
- {
- /* Remember whether there is a PLT. */
- plt = true;
- }
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
}
- else if (strncmp (name, ".rela", 5) == 0)
+ else if (CONST_STRNEQ (name, ".rela"))
{
- if (s->_raw_size == 0)
- {
- /* If we don't need this section, strip it from the
- output file. This is mostly to handle .rela.bss and
- .rela.plt. We must create both sections in
- create_dynamic_sections, because they must be created
- before the linker maps input sections to output
- sections. The linker does that before
- adjust_dynamic_symbol is called, and it is that
- function which decides whether anything needs to go
- into these sections. */
- strip = true;
- }
- else
+ if (s->size != 0)
{
asection *target;
{
const char *outname;
- relocs = true;
+ relocs = TRUE;
/* If this relocation section applies to a read only
section, then we probably need a DT_TEXTREL
if (target != NULL
&& (target->flags & SEC_READONLY) != 0
&& (target->flags & SEC_ALLOC) != 0)
- reltext = true;
+ reltext = TRUE;
}
/* We use the reloc_count field as a counter if we need
s->reloc_count = 0;
}
}
- else if (strncmp (name, ".got", 4) != 0)
+ else if (! CONST_STRNEQ (name, ".got")
+ && strcmp (name, ".dynbss") != 0)
{
/* It's not one of our sections, so don't allocate space. */
continue;
}
- if (strip)
+ if (s->size == 0)
{
- _bfd_strip_section_from_output (info, s);
+ /* If we don't need this section, strip it from the
+ output file. This is mostly to handle .rela.bss and
+ .rela.plt. We must create both sections in
+ create_dynamic_sections, because they must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
+ s->flags |= SEC_EXCLUDE;
continue;
}
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
/* Allocate memory for the section contents. */
- s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
- if (s->contents == NULL && s->_raw_size != 0)
- return false;
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
}
if (elf_hash_table (info)->dynamic_sections_created)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!info->shared)
{
if (!add_dynamic_entry (DT_DEBUG, 0))
- return false;
+ return FALSE;
}
if (plt)
|| !add_dynamic_entry (DT_PLTRELSZ, 0)
|| !add_dynamic_entry (DT_PLTREL, DT_RELA)
|| !add_dynamic_entry (DT_JMPREL, 0))
- return false;
+ return FALSE;
}
if (relocs)
if (!add_dynamic_entry (DT_RELA, 0)
|| !add_dynamic_entry (DT_RELASZ, 0)
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
- return false;
+ return FALSE;
}
if (reltext || (info->flags & DF_TEXTREL) != 0)
{
if (!add_dynamic_entry (DT_TEXTREL, 0))
- return false;
+ return FALSE;
}
}
#undef add_dynamic_entry
- return true;
+ return TRUE;
}
/* This function is called via elf_vax_link_hash_traverse if we are
in regular objects. We allocated space for them in the check_relocs
routine, but we won't fill them in in the relocate_section routine. */
-/*ARGSUSED*/
-static boolean
-elf_vax_discard_copies (h, ignore)
- struct elf_vax_link_hash_entry *h;
- PTR ignore ATTRIBUTE_UNUSED;
+static bfd_boolean
+elf_vax_discard_copies (struct elf_vax_link_hash_entry *h,
+ PTR ignore ATTRIBUTE_UNUSED)
{
struct elf_vax_pcrel_relocs_copied *s;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct elf_vax_link_hash_entry *) h->root.root.u.i.link;
-
/* We only discard relocs for symbols defined in a regular object. */
- if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
- return true;
+ if (!h->root.def_regular)
+ return TRUE;
for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
- s->section->_raw_size -= s->count * sizeof (Elf32_External_Rela);
+ s->section->size -= s->count * sizeof (Elf32_External_Rela);
+
+ return TRUE;
+}
+
+/* This function is called via elf_link_hash_traverse. It looks for entries
+ that have GOT or PLT (.GOT) references. If creating a static object or a
+ shared object with -Bsymbolic, it resets the reference count back to 0
+ and sets the offset to -1 so normal PC32 relocation will be done. If
+ creating a shared object or executable, space in the .got and .rela.got
+ will be reserved for the symbol. */
+
+static bfd_boolean
+elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, PTR infoptr)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) infoptr;
+ bfd *dynobj;
+ asection *sgot;
+ asection *srelgot;
- return true;
+ /* We don't care about non-GOT (and non-PLT) entries. */
+ if (h->got.refcount <= 0 && h->plt.refcount <= 0)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+
+ if (!elf_hash_table (info)->dynamic_sections_created
+ || (info->shared && info->symbolic)
+ || h->forced_local)
+ {
+ h->got.refcount = 0;
+ h->got.offset = (bfd_vma) -1;
+ h->plt.refcount = 0;
+ h->plt.offset = (bfd_vma) -1;
+ }
+ else if (h->got.refcount > 0)
+ {
+ bfd_boolean dyn;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ dyn = elf_hash_table (info)->dynamic_sections_created;
+ /* Allocate space in the .got and .rela.got sections. */
+ 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;
}
/* Relocate an VAX ELF section. */
-static boolean
-elf_vax_relocate_section (output_bfd, info, input_bfd, input_section,
- contents, relocs, local_syms, local_sections)
- bfd *output_bfd;
- struct bfd_link_info *info;
- bfd *input_bfd;
- asection *input_section;
- bfd_byte *contents;
- Elf_Internal_Rela *relocs;
- Elf_Internal_Sym *local_syms;
- asection **local_sections;
+static bfd_boolean
+elf_vax_relocate_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ Elf_Internal_Rela *relocs,
+ Elf_Internal_Sym *local_syms,
+ asection **local_sections)
{
bfd *dynobj;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
- bfd_vma *local_got_offsets;
bfd_vma plt_index;
bfd_vma got_offset;
asection *sgot;
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
- if (info->relocateable)
- return true;
-
dynobj = elf_hash_table (info)->dynobj;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
- local_got_offsets = elf_local_got_offsets (input_bfd);
sgot = NULL;
splt = NULL;
if (r_type < 0 || r_type >= (int) R_VAX_max)
{
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
howto = howto_table + r_type;
- /* This is a final link. */
r_symndx = ELF32_R_SYM (rel->r_info);
h = NULL;
sym = NULL;
{
sym = local_syms + r_symndx;
sec = local_sections[r_symndx];
- relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
}
else
{
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
- if (h->root.type == bfd_link_hash_defined
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
+
+ if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
- {
- sec = h->root.u.def.section;
- if ((r_type == R_VAX_PLT32
+ && ((r_type == R_VAX_PLT32
&& h->plt.offset != (bfd_vma) -1
+ && !h->forced_local
&& elf_hash_table (info)->dynamic_sections_created)
|| (r_type == R_VAX_GOT32
- && strcmp (h->root.root.string,
- "_GLOBAL_OFFSET_TABLE_") != 0
+ && h->got.offset != (bfd_vma) -1
+ && !h->forced_local
&& elf_hash_table (info)->dynamic_sections_created
&& (! info->shared
|| (! info->symbolic && h->dynindx != -1)
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ || !h->def_regular))
|| (info->shared
&& ((! info->symbolic && h->dynindx != -1)
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ || !h->def_regular)
&& ((input_section->flags & SEC_ALLOC) != 0
/* DWARF will emit R_VAX_32 relocations in its
sections against symbols defined externally
with them here. */
|| ((input_section->flags & SEC_DEBUGGING) != 0
- && (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
+ && h->def_dynamic))
&& (r_type == R_VAX_8
|| r_type == R_VAX_16
- || r_type == R_VAX_32
- || r_type == R_VAX_PC8
- || r_type == R_VAX_PC16
- || r_type == R_VAX_PC32)))
- {
- /* In these cases, we don't need the relocation
- value. We check specially because in some
- obscure cases sec->output_section will be NULL. */
- relocation = 0;
- }
- else
- relocation = (h->root.u.def.value
- + sec->output_section->vma
- + sec->output_offset);
- }
- else if (h->root.type == bfd_link_hash_undefweak)
- relocation = 0;
- else if (info->shared
- && (!info->symbolic || info->allow_shlib_undefined)
- && !info->no_undefined
- && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ || r_type == R_VAX_32))))
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
relocation = 0;
- else
- {
- if (!(info->callbacks->undefined_symbol
- (info, h->root.root.string, input_bfd,
- input_section, rel->r_offset,
- (!info->shared || info->no_undefined
- || ELF_ST_VISIBILITY (h->other)))))
- return false;
- relocation = 0;
- }
}
+ if (sec != NULL && elf_discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, relend, howto, contents);
+
+ if (info->relocatable)
+ continue;
+
switch (r_type)
{
case R_VAX_GOT32:
/* Relocation is to the address of the entry for this symbol
in the global offset table. */
- if (h != NULL
- && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ 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 (!elf_hash_table (info)->dynamic_sections_created
- || (h == NULL)
- || (info->shared
- && info->symbolic
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
- {
- /* This is actually a static link, or it is a -Bsymbolic link
- and the symbol is defined locally or there is no symbol.
- Change the GOT32 entry to a PC32 entry. */
- break;
- }
-
if (sgot == NULL)
{
sgot = bfd_get_section_by_name (dynobj, ".got");
BFD_ASSERT (h != NULL);
off = h->got.offset;
BFD_ASSERT (off != (bfd_vma) -1);
+ BFD_ASSERT (off < sgot->size);
- if (info->shared
- && h->dynindx == -1
- && (h->elf_link_hash_flags & ELF_LINK_HASH_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
}
relocation = sgot->output_offset + off;
- /* Neither GOT relocation uses the addend. */
+ /* The GOT relocation uses the addend. */
rel->r_addend = 0;
- if (r_type == R_VAX_GOT32)
- {
- /* Change the reference to be indirect */
- contents[rel->r_offset - 1] |= 0x10;
- relocation += sgot->output_section->vma;
- }
+ /* Change the reference to be indirect. */
+ contents[rel->r_offset - 1] |= 0x10;
+ relocation += sgot->output_section->vma;
}
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)
+ if (h == NULL
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || h->forced_local)
break;
if (h->plt.offset == (bfd_vma) -1
if (sgotplt == NULL)
{
sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
- BFD_ASSERT (splt != NULL);
+ BFD_ASSERT (sgotplt != NULL);
}
plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
The first two are reserved. */
got_offset = (plt_index + 3) * 4;
- /* We want the relocate to point into the .got.plt instead
+ /* We want the relocation to point into the .got.plt instead
of the plt itself. */
relocation = (sgotplt->output_section->vma
+ sgotplt->output_offset
case R_VAX_PC8:
case R_VAX_PC16:
- case R_VAX_PC32:
- if (h == NULL)
+ r_vax_pc32_shared:
+ 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 (info->shared
- && r_symndx != 0
+ && r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0
&& ((r_type != R_VAX_PC8
&& r_type != R_VAX_PC16
&& r_type != R_VAX_PC32)
- || (!info->symbolic
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+ || ((input_section->flags & SEC_CODE)
+ && (!info->symbolic
+ || (!h->def_regular && h->type != STT_SECTION)))))
{
Elf_Internal_Rela outrel;
- boolean skip, relocate;
+ bfd_byte *loc;
+ bfd_boolean skip, relocate;
/* When generating a shared object, these relocations
are copied into the output file to be resolved at run
time. */
-
if (sreloc == NULL)
{
- const char *name;
-
- name = (bfd_elf_string_from_elf_section
- (input_bfd,
- elf_elfheader (input_bfd)->e_shstrndx,
- elf_section_data (input_section)->rel_hdr.sh_name));
- if (name == NULL)
- return false;
-
- BFD_ASSERT (strncmp (name, ".rela", 5) == 0
- && strcmp (bfd_get_section_name (input_bfd,
- input_section),
- name + 5) == 0);
-
- sreloc = bfd_get_section_by_name (dynobj, name);
- BFD_ASSERT (sreloc != NULL);
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ return FALSE;
}
- skip = false;
- relocate = false;
+ skip = FALSE;
+ relocate = FALSE;
outrel.r_offset =
_bfd_elf_section_offset (output_bfd, info, input_section,
rel->r_offset);
if (outrel.r_offset == (bfd_vma) -1)
- skip = true;
+ skip = TRUE;
if (outrel.r_offset == (bfd_vma) -2)
- skip = true, relocate = true;
+ skip = TRUE, relocate = TRUE;
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
become local. */
else if (h != NULL
&& ((! info->symbolic && h->dynindx != -1)
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ || !h->def_regular))
{
BFD_ASSERT (h->dynindx != -1);
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
{
if (r_type == R_VAX_32)
{
- relocate = true;
+ relocate = TRUE;
outrel.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE);
BFD_ASSERT (bfd_get_signed_32 (input_bfd,
&contents[rel->r_offset]) == 0);
{
long indx;
- if (h == NULL)
- sec = local_sections[r_symndx];
- else
- {
- BFD_ASSERT (h->root.type == bfd_link_hash_defined
- || (h->root.type
- == bfd_link_hash_defweak));
- sec = h->root.u.def.section;
- }
- if (sec != NULL && bfd_is_abs_section (sec))
+ if (bfd_is_abs_section (sec))
indx = 0;
else if (sec == NULL || sec->owner == NULL)
{
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
else
{
asection *osec;
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
osec = sec->output_section;
indx = elf_section_data (osec)->dynindx;
- BFD_ASSERT (indx > 0);
+ if (indx == 0)
+ {
+ struct elf_link_hash_table *htab;
+ htab = elf_hash_table (info);
+ osec = htab->text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
}
outrel.r_info = ELF32_R_INFO (indx, r_type);
outrel.r_addend,
bfd_get_section_name (input_bfd, input_section));
}
- bfd_elf32_swap_reloca_out (output_bfd, &outrel,
- (((Elf32_External_Rela *)
- sreloc->contents)
- + sreloc->reloc_count));
- ++sreloc->reloc_count;
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
/* This reloc will be computed at runtime, so there's no
need to do anything now, except for R_VAX_32
break;
}
- /* VAX PCREL relocations are from the end of relocation, not the start */
+ /* VAX PCREL relocations are from the end of relocation, not the start.
+ So subtract the difference from the relocation amount since we can't
+ add it to the offset. */
if (howto->pc_relative && howto->pcrel_offset)
- {
- relocation -= bfd_get_reloc_size(howto);
- }
+ relocation -= bfd_get_reloc_size(howto);
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset,
const char *name;
if (h != NULL)
- name = h->root.root.string;
+ name = NULL;
else
{
name = bfd_elf_string_from_elf_section (input_bfd,
symtab_hdr->sh_link,
sym->st_name);
if (name == NULL)
- return false;
+ return FALSE;
if (*name == '\0')
name = bfd_section_name (input_bfd, sec);
}
if (!(info->callbacks->reloc_overflow
- (info, name, howto->name, (bfd_vma) 0,
- input_bfd, input_section, rel->r_offset)))
- return false;
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
}
break;
}
}
}
- return true;
+ return TRUE;
}
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
-static boolean
-elf_vax_finish_dynamic_symbol (output_bfd, info, h, sym)
- bfd *output_bfd;
- struct bfd_link_info *info;
- struct elf_link_hash_entry *h;
- Elf_Internal_Sym *sym;
+static bfd_boolean
+elf_vax_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
{
bfd *dynobj;
bfd_vma got_offset;
bfd_vma addend;
Elf_Internal_Rela rela;
+ bfd_byte *loc;
/* This symbol has an entry in the procedure linkage table. Set
it up. */
-
BFD_ASSERT (h->dynindx != -1);
splt = bfd_get_section_by_name (dynobj, ".plt");
+ got_offset);
rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_JMP_SLOT);
rela.r_addend = addend;
- bfd_elf32_swap_reloca_out (output_bfd, &rela,
- ((Elf32_External_Rela *) srela->contents
- + plt_index));
+ loc = srela->contents + plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
- if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ if (!h->def_regular)
{
/* Mark the symbol as undefined, rather than as defined in
the .plt section. Leave the value alone. */
asection *sgot;
asection *srela;
Elf_Internal_Rela rela;
+ bfd_byte *loc;
/* This symbol has an entry in the global offset table. Set it
up. */
-
sgot = bfd_get_section_by_name (dynobj, ".got");
srela = bfd_get_section_by_name (dynobj, ".rela.got");
BFD_ASSERT (sgot != NULL && srela != NULL);
the relocate_section function. */
if (info->shared
&& h->dynindx == -1
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ && h->def_regular)
{
rela.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE);
}
(sgot->contents
+ (h->got.offset & ~1)));
- bfd_elf32_swap_reloca_out (output_bfd, &rela,
- ((Elf32_External_Rela *) srela->contents
- + srela->reloc_count));
- ++srela->reloc_count;
+ loc = srela->contents;
+ loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
}
- if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+ if (h->needs_copy)
{
asection *s;
Elf_Internal_Rela rela;
+ bfd_byte *loc;
/* This symbol needs a copy reloc. Set it up. */
-
BFD_ASSERT (h->dynindx != -1
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
+ h->root.u.def.section->output_offset);
rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_COPY);
rela.r_addend = 0;
- bfd_elf32_swap_reloca_out (output_bfd, &rela,
- ((Elf32_External_Rela *) s->contents
- + s->reloc_count));
- ++s->reloc_count;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
if (strcmp (h->root.root.string, "_DYNAMIC") == 0
- || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ || h == elf_hash_table (info)->hgot)
sym->st_shndx = SHN_ABS;
- return true;
+ return TRUE;
}
/* Finish up the dynamic sections. */
-static boolean
-elf_vax_finish_dynamic_sections (output_bfd, info)
- bfd *output_bfd;
- struct bfd_link_info *info;
+static bfd_boolean
+elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
{
bfd *dynobj;
asection *sgot;
BFD_ASSERT (splt != NULL && sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
- dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
case DT_PLTRELSZ:
s = bfd_get_section_by_name (output_bfd, ".rela.plt");
BFD_ASSERT (s != NULL);
- if (s->_cooked_size != 0)
- dyn.d_un.d_val = s->_cooked_size;
- else
- dyn.d_un.d_val = s->_raw_size;
+ dyn.d_un.d_val = s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
about changing the DT_RELA entry. */
s = bfd_get_section_by_name (output_bfd, ".rela.plt");
if (s != NULL)
- {
- if (s->_cooked_size != 0)
- dyn.d_un.d_val -= s->_cooked_size;
- else
- dyn.d_un.d_val -= s->_raw_size;
- }
+ dyn.d_un.d_val -= s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
}
}
/* Fill in the first entry in the procedure linkage table. */
- if (splt->_raw_size > 0)
+ if (splt->size > 0)
{
memcpy (splt->contents, elf_vax_plt0_entry, PLT_ENTRY_SIZE);
bfd_put_32 (output_bfd,
}
/* Fill in the first three entries in the global offset table. */
- if (sgot->_raw_size > 0)
+ if (sgot->size > 0)
{
if (sdyn == NULL)
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
- return true;
+ 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
_bfd_elf_create_dynamic_sections
#define bfd_elf32_bfd_link_hash_table_create \
elf_vax_link_hash_table_create
-#define bfd_elf32_bfd_final_link _bfd_elf32_gc_common_final_link
+#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
#define elf_backend_check_relocs elf_vax_check_relocs
#define elf_backend_adjust_dynamic_symbol \
elf_vax_adjust_dynamic_symbol
#define elf_backend_size_dynamic_sections \
elf_vax_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
#define elf_backend_relocate_section elf_vax_relocate_section
#define elf_backend_finish_dynamic_symbol \
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 \