/* Renesas / SuperH SH specific support for 32-bit ELF
- Copyright (C) 1996-2015 Free Software Foundation, Inc.
+ Copyright (C) 1996-2016 Free Software Foundation, Inc.
Contributed by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
&& bfd_is_und_section (symbol_in->section))
return bfd_reloc_undefined;
+ /* PR 17512: file: 9891ca98. */
+ if (addr * bfd_octets_per_byte (abfd) + bfd_get_reloc_size (reloc_entry->howto)
+ > bfd_get_section_limit_octets (abfd, input_section))
+ return bfd_reloc_outofrange;
+
if (bfd_is_com_section (symbol_in->section))
sym_value = 0;
else
r = ELF32_R_TYPE (dst->r_info);
- BFD_ASSERT (r < (unsigned int) R_SH_max);
- BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC || r > R_SH_LAST_INVALID_RELOC);
- BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_2 || r > R_SH_LAST_INVALID_RELOC_2);
- BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_LAST_INVALID_RELOC_3);
- BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
- BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_5 || r > R_SH_LAST_INVALID_RELOC_5);
- BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_6 || r > R_SH_LAST_INVALID_RELOC_6);
+ if (r >= R_SH_max
+ || (r >= R_SH_FIRST_INVALID_RELOC && r <= R_SH_LAST_INVALID_RELOC)
+ || (r >= R_SH_FIRST_INVALID_RELOC_2 && r <= R_SH_LAST_INVALID_RELOC_2)
+ || (r >= R_SH_FIRST_INVALID_RELOC_3 && r <= R_SH_LAST_INVALID_RELOC_3)
+ || (r >= R_SH_FIRST_INVALID_RELOC_4 && r <= R_SH_LAST_INVALID_RELOC_4)
+ || (r >= R_SH_FIRST_INVALID_RELOC_5 && r <= R_SH_LAST_INVALID_RELOC_5)
+ || (r >= R_SH_FIRST_INVALID_RELOC_6 && r <= R_SH_LAST_INVALID_RELOC_6))
+ {
+ (*_bfd_error_handler) (_("%B: unrecognised SH reloc number: %d"),
+ abfd, r);
+ bfd_set_error (bfd_error_bad_value);
+ r = R_SH_NONE;
+ }
cache_ptr->howto = get_howto_table (abfd) + r;
}
*again = FALSE;
- if (link_info->relocatable
+ if (bfd_link_relocatable (link_info)
|| (sec->flags & SEC_RELOC) == 0
|| sec->reloc_count == 0)
return TRUE;
h->type = STT_OBJECT;
htab->root.hplt = h;
- if (info->shared
+ if (bfd_link_pic (info)
&& ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
be needed, we can discard it later. We will never need this
section when generating a shared object, since they do not use
copy relocs. */
- if (! info->shared)
+ if (! bfd_link_pic (info))
{
s = bfd_make_section_anyway_with_flags (abfd,
(bed->default_use_rela_p
only references to the symbol are via the global offset table.
For such cases we need not do anything here; the relocations will
be handled correctly by relocate_section. */
- if (info->shared)
+ if (bfd_link_pic (info))
return TRUE;
/* If there are no references to this symbol that do not use the
return FALSE;
}
- if (info->shared
+ if (bfd_link_pic (info)
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
{
asection *s = htab->splt;
the shared library. Skip this for FDPIC, since the
function's address will be the address of the canonical
function descriptor. */
- if (!htab->fdpic_p && !info->shared && !h->def_regular)
+ if (!htab->fdpic_p && !bfd_link_pic (info) && !h->def_regular)
{
h->root.u.def.section = s;
h->root.u.def.value = h->plt.offset;
/* We also need to make an entry in the .rel.plt section. */
htab->srelplt->size += sizeof (Elf32_External_Rela);
- if (htab->vxworks_p && !info->shared)
+ if (htab->vxworks_p && !bfd_link_pic (info))
{
/* VxWorks executables have a second set of relocations
for each PLT entry. They go in a separate relocation
if (!dyn)
{
/* No dynamic relocations required. */
- if (htab->fdpic_p && !info->shared
+ if (htab->fdpic_p && !bfd_link_pic (info)
&& h->root.type != bfd_link_hash_undefweak
&& (got_type == GOT_NORMAL || got_type == GOT_FUNCDESC))
htab->srofixup->size += 4;
}
/* No dynamic relocations required when IE->LE conversion happens. */
- else if (got_type == GOT_TLS_IE && !h->def_dynamic && !info->shared)
+ else if (got_type == GOT_TLS_IE
+ && !h->def_dynamic
+ && !bfd_link_pic (info))
;
/* R_SH_TLS_IE_32 needs one dynamic relocation if dynamic,
R_SH_TLS_GD needs one if local symbol and two if global. */
htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
else if (got_type == GOT_FUNCDESC)
{
- if (!info->shared && SYMBOL_FUNCDESC_LOCAL (info, h))
+ if (!bfd_link_pic (info) && SYMBOL_FUNCDESC_LOCAL (info, h))
htab->srofixup->size += 4;
else
htab->srelgot->size += sizeof (Elf32_External_Rela);
}
else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
- && (info->shared
+ && (bfd_link_pic (info)
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
htab->srelgot->size += sizeof (Elf32_External_Rela);
- else if (htab->fdpic_p && !info->shared && got_type == GOT_NORMAL
+ else if (htab->fdpic_p
+ && !bfd_link_pic (info)
+ && got_type == GOT_NORMAL
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
htab->srofixup->size += 4;
eh->datalabel_got.offset = s->size;
s->size += 4;
dyn = htab->root.dynamic_sections_created;
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h))
htab->srelgot->size += sizeof (Elf32_External_Rela);
}
else
|| (htab->root.dynamic_sections_created
&& ! SYMBOL_CALLS_LOCAL (info, h))))
{
- if (!info->shared && SYMBOL_FUNCDESC_LOCAL (info, h))
+ if (!bfd_link_pic (info) && SYMBOL_FUNCDESC_LOCAL (info, h))
htab->srofixup->size += eh->abs_funcdesc_refcount * 4;
else
htab->srelgot->size
/* We will need a relocation or two fixups to initialize the
function descriptor, so allocate those too. */
- if (!info->shared && SYMBOL_CALLS_LOCAL (info, h))
+ if (!bfd_link_pic (info) && SYMBOL_CALLS_LOCAL (info, h))
htab->srofixup->size += 8;
else
htab->srelfuncdesc->size += sizeof (Elf32_External_Rela);
space for pc-relative relocs that have become local due to symbol
visibility changes. */
- if (info->shared)
+ if (bfd_link_pic (info))
{
if (SYMBOL_CALLS_LOCAL (info, h))
{
sreloc->size += p->count * sizeof (Elf32_External_Rela);
/* If we need relocations, we do not need fixups. */
- if (htab->fdpic_p && !info->shared)
+ if (htab->fdpic_p && !bfd_link_pic (info))
htab->srofixup->size -= 4 * (p->count - p->pc_count);
}
static bfd_boolean
sh_elf_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
{
- sh_elf_hash_table (info)->plt_info = get_plt_info (output_bfd, info->shared);
+ sh_elf_hash_table (info)->plt_info = get_plt_info (output_bfd,
+ bfd_link_pic (info));
- if (sh_elf_hash_table (info)->fdpic_p && !info->relocatable
+ if (sh_elf_hash_table (info)->fdpic_p && !bfd_link_relocatable (info)
&& !bfd_elf_stack_segment_size (output_bfd, info,
"__stacksize", DEFAULT_STACK_SIZE))
return FALSE;
if (htab->root.dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (info->executable)
+ if (bfd_link_executable (info) && !info->nointerp)
{
s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
info->flags |= DF_TEXTREL;
/* If we need relocations, we do not need fixups. */
- if (htab->fdpic_p && !info->shared)
+ if (htab->fdpic_p && !bfd_link_pic (info))
htab->srofixup->size -= 4 * (p->count - p->pc_count);
}
}
s->size += 4;
if (*local_got_type == GOT_TLS_GD)
s->size += 4;
- if (info->shared)
+ if (bfd_link_pic (info))
srel->size += sizeof (Elf32_External_Rela);
else
htab->srofixup->size += 4;
{
local_funcdesc->offset = htab->sfuncdesc->size;
htab->sfuncdesc->size += 8;
- if (!info->shared)
+ if (!bfd_link_pic (info))
htab->srofixup->size += 8;
else
htab->srelfuncdesc->size += sizeof (Elf32_External_Rela);
#define add_dynamic_entry(TAG, VAL) \
_bfd_elf_add_dynamic_entry (info, TAG, VAL)
- if (info->executable)
+ if (bfd_link_executable (info))
{
if (! add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
|| ! add_dynamic_entry (DT_JMPREL, 0))
return FALSE;
}
- else if ((elf_elfheader (output_bfd)->e_flags & EF_SH_FDPIC)
- && htab->sgot->size != 0)
+ else if ((elf_elfheader (output_bfd)->e_flags & EF_SH_FDPIC))
{
if (! add_dynamic_entry (DT_PLTGOT, 0))
return FALSE;
addr = seg = 0;
}
- if (!info->shared && SYMBOL_CALLS_LOCAL (info, h))
+ if (!bfd_link_pic (info) && SYMBOL_CALLS_LOCAL (info, h))
{
if (h == NULL || h->root.type != bfd_link_hash_undefweak)
{
/* We have to handle relocations in vxworks .tls_vars sections
specially, because the dynamic loader is 'weird'. */
- is_vxworks_tls = (htab && htab->vxworks_p && info->shared
+ is_vxworks_tls = (htab && htab->vxworks_p && bfd_link_pic (info)
&& !strcmp (input_section->output_section->name,
".tls_vars"));
if (sec != NULL && discarded_section (sec))
/* Handled below. */
;
- else if (info->relocatable)
+ else if (bfd_link_relocatable (info))
{
/* This is a relocatable link. We don't have to change
anything, unless the reloc is against a section symbol,
|| r_type == R_SH_GOT_MEDLOW16
|| r_type == R_SH_GOT_MEDHI16
|| r_type == R_SH_GOT_HI16)
- && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
- && (! info->shared
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+ bfd_link_pic (info),
+ h)
+ && (! bfd_link_pic (info)
|| (! info->symbolic && h->dynindx != -1)
|| !h->def_regular))
/* The cases above are those in which relocation is
below are those in which we must defer relocation
to run-time, because we can't resolve absolute
addresses when creating a shared library. */
- || (info->shared
+ || (bfd_link_pic (info)
&& ((! info->symbolic && h->dynindx != -1)
|| !h->def_regular)
&& ((r_type == R_SH_DIR32
STT_DATALABEL on the way to it. */
| ((h->other & STO_SH5_ISA32) != 0
&& ! seen_stt_datalabel));
- else if (!info->relocatable
+ else if (!bfd_link_relocatable (info)
&& (_bfd_elf_section_offset (output_bfd, info,
input_section,
rel->r_offset)
else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
;
- else if (!info->relocatable)
+ else if (!bfd_link_relocatable (info))
{
if (! info->callbacks->undefined_symbol
(info, h->root.root.string, input_bfd,
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
rel, 1, relend, howto, 0, contents);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
continue;
/* Check for inter-segment relocations in FDPIC files. Most
case R_SH_IMM_MEDHI16_PCREL:
case R_SH_IMM_HI16_PCREL:
#endif
- if (info->shared
+ if (bfd_link_pic (info)
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
if (! relocate)
continue;
}
- else if (fdpic_p && !info->shared
+ else if (fdpic_p && !bfd_link_pic (info)
&& r_type == R_SH_DIR32
&& (input_section->flags & SEC_ALLOC) != 0)
{
symbols. */
else if (r_type == R_SH_REL32
&& h
- && h->root.type == bfd_link_hash_undefweak)
+ && h->root.type == bfd_link_hash_undefweak)
check_segment[0] = check_segment[1] = -1;
goto final_link_relocate;
if (h == NULL
|| h->forced_local
- || ! info->shared
+ || ! bfd_link_pic (info)
|| info->symbolic
|| h->dynindx == -1
|| h->plt.offset == (bfd_vma) -1
BFD_ASSERT (off != (bfd_vma) -1);
dyn = htab->root.dynamic_sections_created;
- if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
- || (info->shared
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+ bfd_link_pic (info),
+ h)
+ || (bfd_link_pic (info)
&& SYMBOL_REFERENCES_LOCAL (info, h))
|| (ELF_ST_VISIBILITY (h->other)
&& h->root.type == bfd_link_hash_undefweak))
/* If we initialize the GOT entry here with a valid
symbol address, also add a fixup. */
- if (fdpic_p && !info->shared
+ if (fdpic_p && !bfd_link_pic (info)
&& sh_elf_hash_entry (h)->got_type == GOT_NORMAL
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
{
bfd_put_32 (output_bfd, relocation, sgot->contents + off);
- if (info->shared)
+ if (bfd_link_pic (info))
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
relocation = htab->sfuncdesc->output_offset + (offset & ~1);
}
- if (!info->shared && SYMBOL_FUNCDESC_LOCAL (info, h))
+ if (!bfd_link_pic (info) && SYMBOL_FUNCDESC_LOCAL (info, h))
{
bfd_vma offset;
else if (h != NULL)
{
got_type = sh_elf_hash_entry (h)->got_type;
- if (! info->shared
+ if (! bfd_link_pic (info)
&& (h->dynindx == -1
|| h->def_regular))
r_type = R_SH_TLS_LE_32;
case R_SH_TLS_LD_32:
BFD_ASSERT (htab);
check_segment[0] = check_segment[1] = -1;
- if (! info->shared)
+ if (! bfd_link_pic (info))
{
bfd_vma offset;
unsigned short insn;
case R_SH_TLS_LDO_32:
check_segment[0] = check_segment[1] = -1;
- if (! info->shared)
+ if (! bfd_link_pic (info))
relocation = tpoff (info, relocation);
else
relocation -= dtpoff_base (info);
check_segment[0] = check_segment[1] = -1;
- if (! info->shared || info->pie)
+ if (!bfd_link_dll (info))
{
relocation = tpoff (info, relocation);
addend = rel->r_addend;
/* We don't want duplicate errors for undefined symbols. */
if (!h || h->root.type != bfd_link_hash_undefined)
{
- if (info->shared)
+ if (bfd_link_pic (info))
{
info->callbacks->einfo
(_("%X%C: relocation to \"%s\" references a different segment\n"),
input_bfd, input_section, rel->r_offset, symname);
}
- elf_elfheader (output_bfd)->e_flags &= ~EF_SH_PIC;
+ elf_elfheader (output_bfd)->e_flags |= EF_SH_PIC;
}
if (r != bfd_reloc_ok)
union gotref *local_funcdesc;
const Elf_Internal_Rela *rel, *relend;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
elf_section_data (sec)->local_dynrel = NULL;
case R_SH_FUNCDESC:
if (h != NULL)
sh_elf_hash_entry (h)->abs_funcdesc_refcount -= 1;
- else if (sh_elf_hash_table (info)->fdpic_p && !info->shared)
+ else if (sh_elf_hash_table (info)->fdpic_p && !bfd_link_pic (info))
sh_elf_hash_table (info)->srofixup->size -= 4;
/* Fall through. */
break;
case R_SH_DIR32:
- if (sh_elf_hash_table (info)->fdpic_p && !info->shared
+ if (sh_elf_hash_table (info)->fdpic_p && !bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0)
sh_elf_hash_table (info)->srofixup->size -= 4;
/* Fall thru */
case R_SH_REL32:
- if (info->shared)
+ if (bfd_link_pic (info))
break;
/* Fall thru */
sh_elf_optimized_tls_reloc (struct bfd_link_info *info, int r_type,
int is_local)
{
- if (info->shared)
+ if (bfd_link_pic (info))
return r_type;
switch (r_type)
sreloc = NULL;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
BFD_ASSERT (is_sh_elf (abfd));
}
r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
- if (! info->shared
+ if (! bfd_link_pic (info)
&& r_type == R_SH_TLS_IE_32
&& h != NULL
&& h->root.type != bfd_link_hash_undefined
break;
case R_SH_TLS_IE_32:
- if (info->shared)
+ if (bfd_link_pic (info))
info->flags |= DF_STATIC_TLS;
/* FALLTHROUGH */
if (r_type == R_SH_FUNCDESC)
{
- if (!info->shared)
+ if (!bfd_link_pic (info))
htab->srofixup->size += 4;
else
htab->srelgot->size += sizeof (Elf32_External_Rela);
if (h == NULL
|| h->forced_local
- || ! info->shared
+ || ! bfd_link_pic (info)
|| info->symbolic
|| h->dynindx == -1)
goto force_got;
case R_SH_IMM_MEDHI16_PCREL:
case R_SH_IMM_HI16_PCREL:
#endif
- if (h != NULL && ! info->shared)
+ if (h != NULL && ! bfd_link_pic (info))
{
h->non_got_ref = 1;
h->plt.refcount += 1;
may need to keep relocations for symbols satisfied by a
dynamic library if we manage to avoid copy relocs for the
symbol. */
- if ((info->shared
+ if ((bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& (r_type != R_SH_REL32
|| (h != NULL
&& (! info->symbolic
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
- || (! info->shared
+ || (! bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& h != NULL
&& (h->root.type == bfd_link_hash_defweak
/* Allocate the fixup regardless of whether we need a relocation.
If we end up generating the relocation, we'll unallocate the
fixup. */
- if (htab->fdpic_p && !info->shared
+ if (htab->fdpic_p && !bfd_link_pic (info)
&& r_type == R_SH_DIR32
&& (sec->flags & SEC_ALLOC) != 0)
htab->srofixup->size += 4;
break;
case R_SH_TLS_LE_32:
- if (info->shared && !info->pie)
+ if (bfd_link_dll (info))
{
(*_bfd_error_handler)
(_("%B: TLS local exec code cannot be linked into shared objects"),
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
sh_elf_set_mach_from_flags (obfd);
if (elf_elfheader (obfd)->e_flags & EF_SH_FDPIC)
- elf_elfheader (obfd)->e_flags |= EF_SH_PIC;
+ elf_elfheader (obfd)->e_flags &= ~EF_SH_PIC;
}
if (! sh_merge_bfd_arch (ibfd, obfd))
got_offset = (plt_index + 3) * 4;
#ifdef GOT_BIAS
- if (info->shared)
+ if (bfd_link_pic (info))
got_offset -= GOT_BIAS;
#endif
plt_info->symbol_entry,
plt_info->symbol_entry_size);
- if (info->shared || htab->fdpic_p)
+ if (bfd_link_pic (info) || htab->fdpic_p)
{
if (plt_info->symbol_fields.got20)
{
/* Make got_offset relative to the start of .got.plt. */
#ifdef GOT_BIAS
- if (info->shared)
+ if (bfd_link_pic (info))
got_offset += GOT_BIAS;
#endif
if (htab->fdpic_p)
loc = srelplt->contents + plt_index * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
- if (htab->vxworks_p && !info->shared)
+ if (htab->vxworks_p && !bfd_link_pic (info))
{
/* Create the .rela.plt.unloaded relocations for this PLT entry.
Begin by pointing LOC to the first such relocation. */
of a version file, 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
+ if (bfd_link_pic (info)
&& SYMBOL_REFERENCES_LOCAL (info, h))
{
if (htab->fdpic_p)
of a version file, 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
+ if (bfd_link_pic (info)
&& SYMBOL_REFERENCES_LOCAL (info, h))
{
if (htab->fdpic_p)