/* VAX series support for 32-bit ELF
- Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ Copyright (C) 1993-2020 Free Software Foundation, Inc.
Contributed by Matt Thomas <matt@3am-software.com>.
This file is part of BFD, the Binary File Descriptor library.
#include "elf/vax.h"
static reloc_howto_type *reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
-static void rtype_to_howto (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean 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 *);
FALSE), /* pcrel_offset */
};
-static void
+static bfd_boolean
rtype_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
{
unsigned int r_type;
if (r_type >= R_VAX_max)
{
/* xgettext:c-format */
- _bfd_error_handler (_("%B: unrecognised VAX reloc number: %d"),
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
abfd, r_type);
bfd_set_error (bfd_error_bad_value);
- r_type = R_VAX_NONE;
+ return FALSE;
}
cache_ptr->howto = &howto_table[r_type];
+ return TRUE;
}
#define elf_info_to_howto rtype_to_howto
elf_vax_link_hash_table_create (bfd *abfd)
{
struct elf_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct elf_link_hash_table);
+ size_t amt = sizeof (struct elf_link_hash_table);
ret = bfd_zmalloc (amt);
if (ret == NULL)
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))
if (eh->got_addend != (bfd_vma) rel->r_addend)
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: warning: GOT addend of %ld to `%s' does"
- " not match previous GOT addend of %ld"),
- abfd, rel->r_addend, h->root.root.string,
- eh->got_addend);
+ (_("%pB: warning: GOT addend of %" PRId64 " to `%s' does"
+ " not match previous GOT addend of %" PRId64),
+ abfd, (int64_t) rel->r_addend, h->root.root.string,
+ (int64_t) eh->got_addend);
}
}
case R_VAX_PLT32:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
- because this might be a case of linking PIC code which is
- never referenced by a dynamic object, in which case we
- don't need to generate a procedure linkage table entry
- after all. */
+ because this might be a case of linking PIC code which is
+ 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
h->plt.refcount++;
}
+ /* Non-GOT reference may need a copy reloc in executable or
+ a dynamic reloc in shared library. */
+ if (h != NULL)
+ h->non_got_ref = 1;
+
/* If we are creating a shared library, we need to copy the
reloc into the shared library. */
if (bfd_link_pic (info)
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_VAX_GNU_VTENTRY:
- BFD_ASSERT (h != NULL);
- if (h != NULL
- && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}
-/* Update the got entry reference counts for the section being removed. */
-
-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;
- const Elf_Internal_Rela *rel, *relend;
- bfd *dynobj;
-
- if (bfd_link_relocatable (info))
- return TRUE;
-
- dynobj = elf_hash_table (info)->dynobj;
- if (dynobj == NULL)
- return TRUE;
-
- 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:
- if (h != NULL && h->got.refcount > 0)
- --h->got.refcount;
- break;
-
- case R_VAX_PLT32:
- case R_VAX_PC8:
- case R_VAX_PC16:
- case R_VAX_PC32:
- case R_VAX_8:
- case R_VAX_16:
- case R_VAX_32:
- if (h != NULL && h->plt.refcount > 0)
- --h->plt.refcount;
- break;
-
- default:
- break;
- }
- }
-
- return TRUE;
-}
-
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
/* Make sure we know what is going on here. */
BFD_ASSERT (dynobj != NULL
&& (h->needs_plt
- || h->u.weakdef != NULL
+ || h->is_weakalias
|| (h->def_dynamic
&& h->ref_regular
&& !h->def_regular)));
/* 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->u.weakdef != NULL)
+ if (h->is_weakalias)
{
- 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;
+ struct elf_link_hash_entry *def = weakdef (h);
+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+ h->root.u.def.section = def->root.u.def.section;
+ h->root.u.def.value = def->root.u.def.value;
return TRUE;
}
if (bfd_link_pic (info))
return TRUE;
+ /* If there are no references to this symbol that do not use the
+ GOT relocation, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ 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
an entry for this symbol in the .dynsym section. The dynamic
{
bfd *dynobj;
asection *s;
- bfd_boolean plt;
bfd_boolean relocs;
- bfd_boolean reltext;
dynobj = elf_hash_table (info)->dynobj;
BFD_ASSERT (dynobj != NULL);
/* 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;
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char *name;
/* It's OK to base decisions on the section name, because none
of the dynobj section names depend upon the input files. */
- name = bfd_get_section_name (dynobj, s);
+ name = bfd_section_name (s);
if (strcmp (name, ".plt") == 0)
{
/* Remember whether there is a PLT. */
- plt = s->size != 0;
+ ;
}
else if (CONST_STRNEQ (name, ".rela"))
{
if (s->size != 0)
{
- asection *target;
-
- /* Remember whether there are any reloc sections other
- than .rela.plt. */
if (strcmp (name, ".rela.plt") != 0)
- {
- const char *outname;
-
- relocs = TRUE;
-
- /* If this relocation section applies to a read only
- section, then we probably need a DT_TEXTREL
- entry. .rela.plt is actually associated with
- .got.plt, which is never readonly. */
- outname = bfd_get_section_name (output_bfd,
- s->output_section);
- target = bfd_get_section_by_name (output_bfd, outname + 5);
- if (target != NULL
- && (target->flags & SEC_READONLY) != 0
- && (target->flags & SEC_ALLOC) != 0)
- reltext = TRUE;
- }
+ relocs = TRUE;
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
return FALSE;
}
- if (elf_hash_table (info)->dynamic_sections_created)
- {
- /* Add some entries to the .dynamic section. We fill in the
- values later, in elf_vax_finish_dynamic_sections, but we
- must add the entries now so that we get the correct size for
- 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_elf_add_dynamic_entry (info, TAG, VAL)
-
- if (!bfd_link_pic (info))
- {
- if (!add_dynamic_entry (DT_DEBUG, 0))
- return FALSE;
- }
-
- if (plt)
- {
- if (!add_dynamic_entry (DT_PLTGOT, 0)
- || !add_dynamic_entry (DT_PLTRELSZ, 0)
- || !add_dynamic_entry (DT_PLTREL, DT_RELA)
- || !add_dynamic_entry (DT_JMPREL, 0))
- 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;
- }
-
- if (reltext || (info->flags & DF_TEXTREL) != 0)
- {
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- }
- }
-#undef add_dynamic_entry
-
- return TRUE;
+ return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs);
}
/* This function is called via elf_vax_link_hash_traverse if we are
else if (rel->r_addend != 0)
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: warning: PLT addend of %d to `%s'"
- " from %A section ignored"),
- input_bfd, rel->r_addend, h->root.root.string, input_section);
+ (_("%pB: warning: PLT addend of %" PRId64 " to `%s'"
+ " from %pA section ignored"),
+ input_bfd, (int64_t) rel->r_addend, h->root.root.string,
+ input_section);
rel->r_addend = 0;
break;
if (skip)
memset (&outrel, 0, sizeof outrel);
/* h->dynindx may be -1 if the symbol was marked to
- become local. */
+ become local. */
else if (h != NULL
&& ((! info->symbolic && h->dynindx != -1)
|| !h->def_regular))
if (h != NULL)
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: warning: %s relocation against symbol `%s'"
- " from %A section"),
+ (_("%pB: warning: %s relocation against symbol `%s'"
+ " from %pA section"),
input_bfd, howto->name, h->root.root.string,
input_section);
else
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: warning: %s relocation to 0x%x from %A section"),
- input_bfd, howto->name, outrel.r_addend,
+ (_("%pB: warning: %s relocation to %#" PRIx64
+ " from %pA section"),
+ input_bfd, howto->name, (uint64_t) outrel.r_addend,
input_section);
}
loc = sreloc->contents;
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
- relocations that have been turned into
- R_VAX_RELATIVE. */
+ need to do anything now, except for R_VAX_32
+ relocations that have been turned into
+ R_VAX_RELATIVE. */
if (!relocate)
continue;
}
}
/* 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. */
+ 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);
if (name == NULL)
return FALSE;
if (*name == '\0')
- name = bfd_section_name (input_bfd, sec);
+ name = bfd_section_name (sec);
}
info->callbacks->reloc_overflow
(info, (h ? &h->root : NULL), name, howto->name,
/* Fill in the entry in the procedure linkage table. */
memcpy (splt->contents + h->plt.offset, elf_vax_plt_entry,
- PLT_ENTRY_SIZE);
+ PLT_ENTRY_SIZE);
/* The offset is relative to the first extension word. */
bfd_put_32 (output_bfd,
{
memcpy (splt->contents, elf_vax_plt0_entry, PLT_ENTRY_SIZE);
bfd_put_32 (output_bfd,
- (sgot->output_section->vma
- + sgot->output_offset + 4
- - (splt->output_section->vma + 6)),
- splt->contents + 2);
+ (sgot->output_section->vma
+ + sgot->output_offset + 4
+ - (splt->output_section->vma + 6)),
+ splt->contents + 2);
bfd_put_32 (output_bfd,
- (sgot->output_section->vma
- + sgot->output_offset + 8
- - (splt->output_section->vma + 12)),
- splt->contents + 8);
- elf_section_data (splt->output_section)->this_hdr.sh_entsize
- = PLT_ENTRY_SIZE;
+ (sgot->output_section->vma
+ + sgot->output_offset + 8
+ - (splt->output_section->vma + 12)),
+ splt->contents + 8);
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
+ = PLT_ENTRY_SIZE;
}
}
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
+ elf32_vax_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags \
- elf32_vax_set_private_flags
+ elf32_vax_set_private_flags
#define bfd_elf32_bfd_print_private_bfd_data \
- elf32_vax_print_private_bfd_data
+ elf32_vax_print_private_bfd_data
#define elf_backend_can_gc_sections 1
#define elf_backend_want_got_plt 1