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 bfd_boolean elf32_vax_print_private_bfd_data (bfd *, void *);
static reloc_howto_type howto_table[] = {
HOWTO (R_VAX_NONE, /* type */
#define elf_vax_link_hash_traverse(table, func, info) \
(elf_link_hash_traverse \
((table), \
- (bfd_boolean (*) (struct elf_link_hash_entry *, PTR)) (func), \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
(info)))
/* Create an entry in an VAX ELF linker hash table. */
struct elf_link_hash_table *ret;
bfd_size_type amt = sizeof (struct elf_link_hash_table);
- ret = bfd_malloc (amt);
+ ret = bfd_zmalloc (amt);
if (ret == NULL)
return NULL;
/* Display the flags field */
static bfd_boolean
-elf32_vax_print_private_bfd_data (bfd *abfd, PTR ptr)
+elf32_vax_print_private_bfd_data (bfd *abfd, void * ptr)
{
FILE *file = (FILE *) ptr;
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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
}
switch (ELF32_R_TYPE (rel->r_info))
{
case R_VAX_GOT32:
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)
+ if (h->forced_local
+ || h == elf_hash_table (info)->hgot
+ || h == elf_hash_table (info)->hplt)
break;
/* This symbol requires a global offset table entry. */
if (sgot == NULL)
{
- sgot = bfd_get_section_by_name (dynobj, ".got");
+ sgot = bfd_get_linker_section (dynobj, ".got");
BFD_ASSERT (sgot != NULL);
}
if (srelgot == NULL
&& (h != NULL || info->shared))
{
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
if (srelgot == NULL)
{
- srelgot = bfd_make_section_with_flags (dynobj,
- ".rela.got",
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
if (srelgot == NULL
|| !bfd_set_section_alignment (dynobj, srelgot, 2))
return FALSE;
never referenced by a dynamic object, in which case we
don't need to generate a procedure linkage table entry
after all. */
+ BFD_ASSERT (h != NULL);
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
- BFD_ASSERT (h != NULL);
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT || h->forced_local)
+ if (h->forced_local)
break;
h->needs_plt = 1;
understand. */
static bfd_boolean
-elf_vax_adjust_dynamic_symbol (info, h)
- struct bfd_link_info *info;
- struct elf_link_hash_entry *h;
+elf_vax_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
{
bfd *dynobj;
asection *s;
if (h->type == STT_FUNC
|| h->needs_plt)
{
- if (! info->shared
- && !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. */
- && h->dynindx == -1)
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
{
/* This case can occur if we saw a PLTxx reloc in an input
file, but the symbol was never referred to by a dynamic
- 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->needs_plt);
+ object, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PCxx reloc instead. */
h->plt.offset = (bfd_vma) -1;
- return TRUE;
- }
-
- /* GC may have rendered this entry unused. */
- if (h->plt.refcount <= 0)
- {
h->needs_plt = 0;
- h->plt.offset = (bfd_vma) -1;
return TRUE;
}
- /* 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;
- }
-
- s = bfd_get_section_by_name (dynobj, ".plt");
+ s = bfd_get_linker_section (dynobj, ".plt");
BFD_ASSERT (s != NULL);
/* If this is the first .plt entry, make room for the special
/* 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");
+ s = bfd_get_linker_section (dynobj, ".got.plt");
BFD_ASSERT (s != NULL);
s->size += 4;
/* We also need to make an entry in the .rela.plt section. */
- s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
BFD_ASSERT (s != NULL);
s->size += sizeof (Elf32_External_Rela);
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
- s = bfd_get_section_by_name (dynobj, ".dynbss");
+ s = bfd_get_linker_section (dynobj, ".dynbss");
BFD_ASSERT (s != NULL);
/* We must generate a R_VAX_COPY reloc to tell the dynamic linker to
{
asection *srel;
- srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
BFD_ASSERT (srel != NULL);
srel->size += sizeof (Elf32_External_Rela);
h->needs_copy = 1;
return _bfd_elf_adjust_dynamic_copy (h, s);
}
+/* This function is called via elf_link_hash_traverse. It resets GOT
+ and PLT (.GOT) reference counts back to -1 so normal PC32 relocation
+ will be done. */
+
+static bfd_boolean
+elf_vax_discard_got_entries (struct elf_link_hash_entry *h,
+ void *infoptr ATTRIBUTE_UNUSED)
+{
+ h->got.refcount = -1;
+ h->plt.refcount = -1;
+
+ return TRUE;
+}
+
+/* Discard unused dynamic data if this is a static link. */
+
+static bfd_boolean
+elf_vax_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (dynobj && !elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* We may have created entries in the .rela.got and .got sections.
+ However, if we are not creating the dynamic sections, we will
+ not actually use these entries. Reset the size of .rela.got
+ and .got, which will cause them to get stripped from the output
+ file below. */
+ s = bfd_get_linker_section (dynobj, ".rela.got");
+ if (s != NULL)
+ s->size = 0;
+ s = bfd_get_linker_section (dynobj, ".got.plt");
+ if (s != NULL)
+ s->size = 0;
+ s = bfd_get_linker_section (dynobj, ".got");
+ if (s != NULL)
+ s->size = 0;
+ }
+
+ /* If this is a static link, we need to discard all the got entries we've
+ recorded. */
+ if (!dynobj || !elf_hash_table (info)->dynamic_sections_created)
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_vax_discard_got_entries,
+ info);
+
+ return TRUE;
+}
+
/* Set the sizes of the dynamic sections. */
static bfd_boolean
/* Set the contents of the .interp section to the interpreter. */
if (info->executable)
{
- s = bfd_get_section_by_name (dynobj, ".interp");
+ s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
}
}
- else
- {
- /* We may have created entries in the .rela.got and .got sections.
- However, if we are not creating the dynamic sections, we will
- not actually use these entries. Reset the size of .rela.got
- and .got, which will cause it to get stripped from the output
- file below. */
- s = bfd_get_section_by_name (dynobj, ".rela.got");
- if (s != NULL)
- s->size = 0;
- s = bfd_get_section_by_name (dynobj, ".got.plt");
- if (s != NULL)
- s->size = 0;
- s = bfd_get_section_by_name (dynobj, ".got");
- if (s != NULL)
- s->size = 0;
- }
/* If this is a -Bsymbolic shared link, then we need to discard all PC
relative relocs against symbols defined in a regular object. We
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). */
+ /* If this is a -Bsymbolic shared 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);
+ info);
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
static bfd_boolean
elf_vax_discard_copies (struct elf_vax_link_hash_entry *h,
- PTR ignore ATTRIBUTE_UNUSED)
+ void * ignore ATTRIBUTE_UNUSED)
{
struct elf_vax_pcrel_relocs_copied *s;
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. */
+/* This function is called via elf_link_hash_traverse. It looks for
+ entries that have GOT or PLT (.GOT) references. If creating a shared
+ object with -Bsymbolic, or the symbol has been forced local, then it
+ resets the reference count back to -1 so normal PC32 relocation will
+ be done. Otherwise 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)
+elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
{
struct bfd_link_info *info = (struct bfd_link_info *) infoptr;
bfd *dynobj;
return TRUE;
dynobj = elf_hash_table (info)->dynobj;
- if (dynobj == NULL)
- return TRUE;
+ BFD_ASSERT (dynobj != NULL);
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
- if (!elf_hash_table (info)->dynamic_sections_created
- || (info->shared && info->symbolic)
- || h->forced_local)
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
{
- h->got.refcount = 0;
- h->got.offset = (bfd_vma) -1;
- h->plt.refcount = 0;
- h->plt.offset = (bfd_vma) -1;
+ h->got.refcount = -1;
+ h->plt.refcount = -1;
}
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. */
- 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);
- }
+ sgot->size += 4;
+ srelgot->size += sizeof (Elf32_External_Rela);
}
return TRUE;
else
{
bfd_boolean unresolved_reloc;
- bfd_boolean warned;
+ bfd_boolean warned, ignored;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
h, sec, relocation,
- unresolved_reloc, warned);
+ unresolved_reloc, warned, ignored);
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
case R_VAX_GOT32:
/* Relocation is to the address of the entry for this symbol
in the global offset table. */
+
+ /* Resolve a GOTxx reloc against a local symbol directly,
+ without using the global offset table. */
if (h == NULL
- || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
- || h->got.offset == (bfd_vma) -1
- || h->forced_local)
+ || h->got.offset == (bfd_vma) -1)
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)
{
- sgot = bfd_get_section_by_name (dynobj, ".got");
+ sgot = bfd_get_linker_section (dynobj, ".got");
BFD_ASSERT (sgot != NULL);
}
- BFD_ASSERT (h != NULL);
off = h->got.offset;
- BFD_ASSERT (off != (bfd_vma) -1);
BFD_ASSERT (off < sgot->size);
- 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
- 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
- is done in the finish_dynamic_symbol routine. */
- if ((off & 1) != 0)
- off &= ~1;
- else
- {
- bfd_put_32 (output_bfd, relocation + rel->r_addend,
- sgot->contents + off);
- h->got.offset |= 1;
- }
- } else {
- bfd_put_32 (output_bfd, rel->r_addend, sgot->contents + off);
- }
+ bfd_put_32 (output_bfd, rel->r_addend, sgot->contents + off);
relocation = sgot->output_offset + off;
/* The GOT relocation uses the addend. */
/* Resolve a PLTxx reloc against a local symbol directly,
without using the procedure linkage table. */
if (h == NULL
- || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
- || h->forced_local)
+ || h->plt.offset == (bfd_vma) -1)
break;
- if (h->plt.offset == (bfd_vma) -1
- || !elf_hash_table (info)->dynamic_sections_created)
- {
- /* We didn't make a PLT entry for this symbol. This
- happens when statically linking PIC code, or when
- using -Bsymbolic. */
- break;
- }
-
if (splt == NULL)
{
- splt = bfd_get_section_by_name (dynobj, ".plt");
+ splt = bfd_get_linker_section (dynobj, ".plt");
BFD_ASSERT (splt != NULL);
}
if (sgotplt == NULL)
{
- sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+ sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
BFD_ASSERT (sgotplt != NULL);
}
}
}
- if (!strcmp (bfd_get_section_name (input_bfd, input_section),
- ".text") != 0 ||
- (info->shared
- && ELF32_R_TYPE(outrel.r_info) != R_VAX_32
- && ELF32_R_TYPE(outrel.r_info) != R_VAX_RELATIVE
- && ELF32_R_TYPE(outrel.r_info) != R_VAX_COPY
- && ELF32_R_TYPE(outrel.r_info) != R_VAX_JMP_SLOT
- && ELF32_R_TYPE(outrel.r_info) != R_VAX_GLOB_DAT))
+ if ((input_section->flags & SEC_CODE) != 0
+ || (ELF32_R_TYPE (outrel.r_info) != R_VAX_32
+ && ELF32_R_TYPE (outrel.r_info) != R_VAX_RELATIVE
+ && ELF32_R_TYPE (outrel.r_info) != R_VAX_COPY
+ && ELF32_R_TYPE (outrel.r_info) != R_VAX_JMP_SLOT
+ && ELF32_R_TYPE (outrel.r_info) != R_VAX_GLOB_DAT))
{
if (h != NULL)
(*_bfd_error_handler)
it up. */
BFD_ASSERT (h->dynindx != -1);
- splt = bfd_get_section_by_name (dynobj, ".plt");
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
- srela = bfd_get_section_by_name (dynobj, ".rela.plt");
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ srela = bfd_get_linker_section (dynobj, ".rela.plt");
BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
addend = 2 * (h->plt.offset & 1);
/* 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");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srela = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (sgot != NULL && srela != NULL);
rela.r_offset = (sgot->output_section->vma
+ sgot->output_offset
- + (h->got.offset &~ 1));
-
- /* If the symbol was forced to be local because of a version file
- 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
- && h->dynindx == -1
- && h->def_regular)
- {
- rela.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE);
- }
- else
- {
- rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_GLOB_DAT);
- }
+ + h->got.offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_GLOB_DAT);
rela.r_addend = bfd_get_signed_32 (output_bfd,
- (sgot->contents
- + (h->got.offset & ~1)));
+ sgot->contents + h->got.offset);
loc = srela->contents;
loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
- s = bfd_get_section_by_name (h->root.u.def.section->owner,
- ".rela.bss");
+ s = bfd_get_linker_section (dynobj, ".rela.bss");
BFD_ASSERT (s != NULL);
rela.r_offset = (h->root.u.def.value
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
- if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ if (h == elf_hash_table (info)->hdynamic
|| h == elf_hash_table (info)->hgot)
sym->st_shndx = SHN_ABS;
dynobj = elf_hash_table (info)->dynobj;
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
BFD_ASSERT (sgot != NULL);
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)
{
asection *splt;
Elf32_External_Dyn *dyncon, *dynconend;
- splt = bfd_get_section_by_name (dynobj, ".plt");
+ splt = bfd_get_linker_section (dynobj, ".plt");
BFD_ASSERT (splt != NULL && sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
}
- elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+ if (elf_section_data (sgot->output_section) != NULL)
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
return TRUE;
}
static enum elf_reloc_type_class
-elf_vax_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_vax_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
#define elf_backend_check_relocs elf_vax_check_relocs
#define elf_backend_adjust_dynamic_symbol \
elf_vax_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ elf_vax_always_size_sections
#define elf_backend_size_dynamic_sections \
elf_vax_size_dynamic_sections
#define elf_backend_init_index_section _bfd_elf_init_1_index_section