/* Renesas / SuperH SH specific support for 32-bit ELF
- Copyright (C) 1996-2014 Free Software Foundation, Inc.
+ Copyright (C) 1996-2018 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
/* Given an ELF reloc, fill in the howto field of a relent. */
-static void
+static bfd_boolean
sh_elf_info_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
{
unsigned int r;
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))
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
cache_ptr->howto = get_howto_table (abfd) + r;
+ return TRUE;
}
\f
/* This function handles relaxing for SH ELF. See the corresponding
*again = FALSE;
- if (link_info->relocatable
+ if (bfd_link_relocatable (link_info)
|| (sec->flags & SEC_RELOC) == 0
|| sec->reloc_count == 0)
return TRUE;
laddr = irel->r_offset + 4 + irel->r_addend;
if (laddr >= sec->size)
{
- (*_bfd_error_handler) (_("%B: 0x%lx: warning: bad R_SH_USES offset"),
- abfd,
- (unsigned long) irel->r_offset);
+ /* xgettext:c-format */
+ _bfd_error_handler
+ (_("%pB: %#" PRIx64 ": warning: bad R_SH_USES offset"),
+ abfd, (uint64_t) irel->r_offset);
continue;
}
insn = bfd_get_16 (abfd, contents + laddr);
do. */
if ((insn & 0xf000) != 0xd000)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"),
- abfd, (unsigned long) irel->r_offset, insn));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": warning: "
+ "R_SH_USES points to unrecognized insn 0x%x"),
+ abfd, (uint64_t) irel->r_offset, insn);
continue;
}
paddr += (laddr + 4) &~ (bfd_vma) 3;
if (paddr >= sec->size)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: warning: bad R_SH_USES load offset"),
- abfd, (unsigned long) irel->r_offset));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": warning: bad R_SH_USES load offset"),
+ abfd, (uint64_t) irel->r_offset);
continue;
}
break;
if (irelfn >= irelend)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: warning: could not find expected reloc"),
- abfd, (unsigned long) paddr));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": warning: could not find expected reloc"),
+ abfd, (uint64_t) paddr);
continue;
}
if (isym->st_shndx
!= (unsigned int) _bfd_elf_section_from_bfd_section (abfd, sec))
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: warning: symbol in unexpected section"),
- abfd, (unsigned long) paddr));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": warning: symbol in unexpected section"),
+ abfd, (uint64_t) paddr);
continue;
}
elf_section_data (sec)->this_hdr.contents = contents;
symtab_hdr->contents = (unsigned char *) isymbuf;
- /* Replace the jsr with a bsr. */
+ /* Replace the jmp/jsr with a bra/bsr. */
/* Change the R_SH_USES reloc into an R_SH_IND12W reloc, and
- replace the jsr with a bsr. */
+ replace the jmp/jsr with a bra/bsr. */
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_SH_IND12W);
/* We used to test (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
here, but that only checks if the symbol is an external symbol,
/* We can't fully resolve this yet, because the external
symbol value may be changed by future relaxing. We let
the final link phase handle it. */
- bfd_put_16 (abfd, (bfd_vma) 0xb000, contents + irel->r_offset);
+ if (bfd_get_16 (abfd, contents + irel->r_offset) & 0x0020)
+ bfd_put_16 (abfd, (bfd_vma) 0xa000, contents + irel->r_offset);
+ else
+ bfd_put_16 (abfd, (bfd_vma) 0xb000, contents + irel->r_offset);
irel->r_addend = -4;
/* Now check whether we got a COUNT reloc. */
if (irelcount >= irelend)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: warning: could not find expected COUNT reloc"),
- abfd, (unsigned long) paddr));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": warning: "
+ "could not find expected COUNT reloc"),
+ abfd, (uint64_t) paddr);
continue;
}
just deleted one. */
if (irelcount->r_addend == 0)
{
- ((*_bfd_error_handler) (_("%B: 0x%lx: warning: bad count"),
- abfd,
- (unsigned long) paddr));
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: %#" PRIx64 ": warning: bad count"),
+ abfd, (uint64_t) paddr);
continue;
}
contents = elf_section_data (sec)->this_hdr.contents;
- /* The deletion must stop at the next ALIGN reloc for an aligment
+ /* The deletion must stop at the next ALIGN reloc for an alignment
power larger than the number of bytes we are deleting. */
irelalign = NULL;
if (overflow)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: fatal: reloc overflow while relaxing"),
- abfd, (unsigned long) irel->r_offset));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": fatal: reloc overflow while relaxing"),
+ abfd, (uint64_t) irel->r_offset);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
if (overflow)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: fatal: reloc overflow while relaxing"),
- abfd, (unsigned long) irel->r_offset));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": fatal: reloc overflow while relaxing"),
+ abfd, (uint64_t) irel->r_offset);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
+ (plt_index * info->symbol_entry_size));
}
-/* The sh linker needs to keep track of the number of relocs that it
- decides to copy as dynamic relocs in check_relocs for each symbol.
- This is so that it can later discard them if they are found to be
- unnecessary. We store the information in a field extending the
- regular ELF linker hash table. */
-
-struct elf_sh_dyn_relocs
-{
- struct elf_sh_dyn_relocs *next;
-
- /* The input section of the reloc. */
- asection *sec;
-
- /* Total number of relocs copied for the input section. */
- bfd_size_type count;
-
- /* Number of pc-relative relocs copied for the input section. */
- bfd_size_type pc_count;
-};
-
union gotref
{
bfd_signed_vma refcount;
#endif
/* Track dynamic relocs copied for this symbol. */
- struct elf_sh_dyn_relocs *dyn_relocs;
+ struct elf_dyn_relocs *dyn_relocs;
bfd_signed_vma gotplt_refcount;
struct elf_link_hash_table root;
/* Short-cuts to get to dynamic linker sections. */
- asection *sgot;
- asection *sgotplt;
- asection *srelgot;
- asection *splt;
- asection *srelplt;
asection *sdynbss;
asection *srelbss;
asection *sfuncdesc;
if (htab == NULL)
return FALSE;
- htab->sgot = bfd_get_linker_section (dynobj, ".got");
- htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
- htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got");
- if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
- abort ();
-
htab->sfuncdesc = bfd_make_section_anyway_with_flags (dynobj, ".got.funcdesc",
(SEC_ALLOC | SEC_LOAD
| SEC_HAS_CONTENTS
pltflags |= SEC_READONLY;
s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
- htab->splt = s;
+ htab->root.splt = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
return FALSE;
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;
}
bed->default_use_rela_p
? ".rela.plt" : ".rel.plt",
flags | SEC_READONLY);
- htab->srelplt = s;
+ htab->root.srelplt = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
- if (htab->sgot == NULL
+ if (htab->root.sgot == NULL
&& !create_got_section (abfd, info))
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
return TRUE;
}
\f
+/* Find dynamic relocs for H that apply to read-only sections. */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+ struct elf_dyn_relocs *p;
+
+ for (p = sh_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ return p->sec;
+ }
+ return NULL;
+}
+
/* 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
struct elf_link_hash_entry *h)
{
struct elf_sh_link_hash_table *htab;
- struct elf_sh_link_hash_entry *eh;
- struct elf_sh_dyn_relocs *p;
asection *s;
htab = sh_elf_hash_table (info);
/* Make sure we know what is going on here. */
BFD_ASSERT (htab->root.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;
if (info->nocopyreloc)
- h->non_got_ref = h->u.weakdef->non_got_ref;
+ h->non_got_ref = def->non_got_ref;
return TRUE;
}
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 TRUE;
/* If -z nocopyreloc was given, we won't generate them either. */
- if (info->nocopyreloc)
+ if (0 && info->nocopyreloc)
{
h->non_got_ref = 0;
return TRUE;
}
- eh = (struct elf_sh_link_hash_entry *) h;
- for (p = eh->dyn_relocs; p != NULL; p = p->next)
- {
- s = p->sec->output_section;
- if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
- break;
- }
-
- /* If we didn't find any dynamic relocs in sections which needs the
- copy reloc, then we'll be keeping the dynamic relocs and avoiding
- the copy reloc. */
- if (p == NULL)
+ /* If we don't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (0 && !readonly_dynrelocs (h))
{
h->non_got_ref = 0;
return TRUE;
h->needs_copy = 1;
}
- return _bfd_elf_adjust_dynamic_copy (h, s);
+ return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
struct bfd_link_info *info;
struct elf_sh_link_hash_table *htab;
struct elf_sh_link_hash_entry *eh;
- struct elf_sh_dyn_relocs *p;
+ struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
return FALSE;
}
- if (info->shared
+ if (bfd_link_pic (info)
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
{
- asection *s = htab->splt;
+ asection *s = htab->root.splt;
const struct elf_sh_plt_info *plt_info;
/* If this is the first .plt entry, make room for the special
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 .got.plt section, which
will be placed in the .got section by the linker script. */
if (!htab->fdpic_p)
- htab->sgotplt->size += 4;
+ htab->root.sgotplt->size += 4;
else
- htab->sgotplt->size += 8;
+ htab->root.sgotplt->size += 8;
/* We also need to make an entry in the .rel.plt section. */
- htab->srelplt->size += sizeof (Elf32_External_Rela);
+ htab->root.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
return FALSE;
}
- s = htab->sgot;
+ s = htab->root.sgot;
h->got.offset = s->size;
s->size += 4;
/* R_SH_TLS_GD needs 2 consecutive GOT slots. */
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. */
else if ((got_type == GOT_TLS_GD && h->dynindx == -1)
|| got_type == GOT_TLS_IE)
- htab->srelgot->size += sizeof (Elf32_External_Rela);
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
else if (got_type == GOT_TLS_GD)
- htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ htab->root.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);
+ htab->root.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
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
+ 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;
return FALSE;
}
- s = htab->sgot;
+ s = htab->root.sgot;
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))
- htab->srelgot->size += sizeof (Elf32_External_Rela);
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h))
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
}
else
eh->datalabel_got.offset = (bfd_vma) -1;
|| (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
+ htab->root.srelgot->size
+= eh->abs_funcdesc_refcount * sizeof (Elf32_External_Rela);
}
/* 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))
{
- struct elf_sh_dyn_relocs **pp;
+ struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{
if (htab->vxworks_p)
{
- struct elf_sh_dyn_relocs **pp;
+ struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{
if (eh->dyn_relocs != NULL
&& h->root.type == bfd_link_hash_undefweak)
{
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
eh->dyn_relocs = NULL;
/* Make sure undefined weak symbols are output as a dynamic
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);
}
return TRUE;
}
-/* Find any dynamic relocs that apply to read-only sections. */
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
+ read-only sections. */
static bfd_boolean
-readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
{
- struct elf_sh_link_hash_entry *eh;
- struct elf_sh_dyn_relocs *p;
+ asection *sec;
- eh = (struct elf_sh_link_hash_entry *) h;
- for (p = eh->dyn_relocs; p != NULL; p = p->next)
- {
- asection *s = p->sec->output_section;
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
- {
- struct bfd_link_info *info = (struct bfd_link_info *) inf;
+ sec = readonly_dynrelocs (h);
+ if (sec != NULL)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) info_p;
- info->flags |= DF_TEXTREL;
+ info->flags |= DF_TEXTREL;
+ info->callbacks->minfo
+ (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
+ sec->owner, h->root.root.string, sec);
- /* Not an error, just cut short the traversal. */
- return FALSE;
- }
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
}
return TRUE;
}
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);
/* Set up .got offsets for local syms, and space for local dynamic
relocs. */
- for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
{
bfd_signed_vma *local_got;
bfd_signed_vma *end_local_got;
for (s = ibfd->sections; s != NULL; s = s->next)
{
- struct elf_sh_dyn_relocs *p;
+ struct elf_dyn_relocs *p;
- for (p = ((struct elf_sh_dyn_relocs *)
+ for (p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel);
p != NULL;
p = p->next)
srel = elf_section_data (p->sec)->sreloc;
srel->size += p->count * sizeof (Elf32_External_Rela);
if ((p->sec->output_section->flags & SEC_READONLY) != 0)
- info->flags |= DF_TEXTREL;
+ {
+ info->flags |= DF_TEXTREL;
+ info->callbacks->minfo (_("%pB: dynamic relocation in read-only section `%pA'\n"),
+ p->sec->owner, p->sec);
+ }
/* 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);
}
}
/* Count datalabel local GOT. */
locsymcount *= 2;
#endif
- s = htab->sgot;
- srel = htab->srelgot;
+ s = htab->root.sgot;
+ srel = htab->root.srelgot;
local_got = elf_local_got_refcounts (ibfd);
if (local_got)
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);
{
/* Allocate 2 got entries and 1 dynamic reloc for R_SH_TLS_LD_32
relocs. */
- htab->tls_ldm_got.offset = htab->sgot->size;
- htab->sgot->size += 8;
- htab->srelgot->size += sizeof (Elf32_External_Rela);
+ htab->tls_ldm_got.offset = htab->root.sgot->size;
+ htab->root.sgot->size += 8;
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
}
else
htab->tls_ldm_got.offset = -1;
the end of .got.plt. */
if (htab->fdpic_p)
{
- BFD_ASSERT (htab->sgotplt && htab->sgotplt->size == 12);
- htab->sgotplt->size = 0;
+ BFD_ASSERT (htab->root.sgotplt && htab->root.sgotplt->size == 12);
+ htab->root.sgotplt->size = 0;
}
/* Allocate global sym .plt and .got entries, and space for global
end of the FDPIC .got.plt. */
if (htab->fdpic_p)
{
- htab->root.hgot->root.u.def.value = htab->sgotplt->size;
- htab->sgotplt->size += 12;
+ htab->root.hgot->root.u.def.value = htab->root.sgotplt->size;
+ htab->root.sgotplt->size += 12;
}
/* At the very end of the .rofixup section is a pointer to the GOT. */
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
- if (s == htab->splt
- || s == htab->sgot
- || s == htab->sgotplt
+ if (s == htab->root.splt
+ || s == htab->root.sgot
+ || s == htab->root.sgotplt
|| s == htab->sfuncdesc
|| s == htab->srofixup
|| s == htab->sdynbss)
}
else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
{
- if (s->size != 0 && s != htab->srelplt && s != htab->srelplt2)
+ if (s->size != 0 && s != htab->root.srelplt && s != htab->srelplt2)
relocs = TRUE;
/* We use the reloc_count field as a counter if we need
#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;
}
- if (htab->splt->size != 0)
+ if (htab->root.splt->size != 0)
{
if (! add_dynamic_entry (DT_PLTGOT, 0)
|| ! add_dynamic_entry (DT_PLTRELSZ, 0)
|| ! 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;
/* If any dynamic relocs apply to a read-only section,
then we need a DT_TEXTREL entry. */
if ((info->flags & DF_TEXTREL) == 0)
- elf_link_hash_traverse (&htab->root, readonly_dynrelocs, info);
+ elf_link_hash_traverse (&htab->root, maybe_set_textrel, info);
if ((info->flags & DF_TEXTREL) != 0)
{
static bfd_signed_vma
sh_elf_got_offset (struct elf_sh_link_hash_table *htab)
{
- return (htab->sgot->output_offset - htab->sgotplt->output_offset
+ return (htab->root.sgot->output_offset - htab->root.sgotplt->output_offset
- htab->root.hgot->root.u.def.value);
}
{
Elf_Internal_Phdr *p = NULL;
- if (output_bfd->xvec->flavour == bfd_target_elf_flavour)
+ if (output_bfd->xvec->flavour == bfd_target_elf_flavour
+ /* PR ld/17110: Do not look for output segments in an input bfd. */
+ && output_bfd->direction != read_direction)
p = _bfd_elf_find_segment_containing_section (output_bfd, osec);
/* FIXME: Nothing ever says what this index is relative to. The kernel
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)
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Rela *rel, *relend;
- bfd *dynobj = NULL;
bfd_vma *local_got_offsets;
asection *sgot = NULL;
asection *sgotplt = NULL;
htab = sh_elf_hash_table (info);
if (htab != NULL)
{
- dynobj = htab->root.dynobj;
- sgot = htab->sgot;
- sgotplt = htab->sgotplt;
- splt = htab->splt;
+ sgot = htab->root.sgot;
+ sgotplt = htab->root.sgotplt;
+ srelgot = htab->root.srelgot;
+ splt = htab->root.splt;
fdpic_p = htab->fdpic_p;
}
symtab_hdr = &elf_symtab_hdr (input_bfd);
/* 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"));
bfd_vma off;
enum got_type got_type;
const char *symname = NULL;
+ bfd_boolean resolved_to_zero;
r_symndx = ELF32_R_SYM (rel->r_info);
if (! howto->partial_inplace)
addend = rel->r_addend;
+ resolved_to_zero = FALSE;
h = NULL;
sym = NULL;
sec = NULL;
datalabel processing here. Make sure this does not change
without notice. */
if ((sym->st_other & STO_SH5_ISA32) != 0)
- ((*info->callbacks->reloc_dangerous)
- (info,
- _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
- input_bfd, input_section, rel->r_offset));
+ (*info->callbacks->reloc_dangerous)
+ (info,
+ _("unexpected STO_SH5_ISA32 on local symbol is not handled"),
+ input_bfd, input_section, rel->r_offset);
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,
if (howto->rightshift || howto->src_mask != 0xffffffff)
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "%s relocation against SEC_MERGE section"),
input_bfd, input_section,
- (long) rel->r_offset, howto->name);
+ (uint64_t) rel->r_offset, howto->name);
return FALSE;
}
|| 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)
!= (bfd_vma) -1))
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "unresolvable %s relocation against symbol `%s'"),
input_bfd,
input_section,
- (long) rel->r_offset,
+ (uint64_t) rel->r_offset,
howto->name,
h->root.root.string);
return FALSE;
}
}
else if (h->root.type == bfd_link_hash_undefweak)
- ;
+ resolved_to_zero = UNDEFWEAK_NO_DYNAMIC_RELOC (info, h);
else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
;
- else if (!info->relocatable)
- {
- if (! info->callbacks->undefined_symbol
- (info, h->root.root.string, input_bfd,
- input_section, rel->r_offset,
- (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
- || ELF_ST_VISIBILITY (h->other))))
- return FALSE;
- }
+ else if (!bfd_link_relocatable (info))
+ (*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other)));
}
if (sec != NULL && discarded_section (sec))
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
}
if (disp & mask)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
- input_section->owner,
- (unsigned long) rel->r_offset));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": fatal: "
+ "unaligned branch target for relax-support relocation"),
+ input_section->owner,
+ (uint64_t) rel->r_offset);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
case R_SH_DIR4UL:
if (relocation & 3)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
- input_section->owner,
- (unsigned long) rel->r_offset, howto->name,
- (unsigned long) relocation));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": fatal: "
+ "unaligned %s relocation %#" PRIx64),
+ input_section->owner, (uint64_t) rel->r_offset,
+ howto->name, (uint64_t) relocation);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
case R_SH_DIR4UW:
if (relocation & 1)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
- input_section->owner,
- (unsigned long) rel->r_offset, howto->name,
- (unsigned long) relocation));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": fatal: "
+ "unaligned %s relocation %#" PRIx64 ""),
+ input_section->owner,
+ (uint64_t) rel->r_offset, howto->name,
+ (uint64_t) relocation);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
if ((signed int)relocation < -32
|| (signed int)relocation > 32)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"),
- input_section->owner,
- (unsigned long) rel->r_offset,
- (unsigned long) relocation));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": fatal: R_SH_PSHA relocation %" PRId64
+ " not in range -32..32"),
+ input_section->owner,
+ (uint64_t) rel->r_offset,
+ (int64_t) relocation);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
if ((signed int)relocation < -16
|| (signed int)relocation > 16)
{
- ((*_bfd_error_handler)
- (_("%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"),
- input_section->owner,
- (unsigned long) rel->r_offset,
- (unsigned long) relocation));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: %#" PRIx64 ": fatal: R_SH_PSHL relocation %" PRId64
+ " not in range -32..32"),
+ input_section->owner,
+ (uint64_t) rel->r_offset,
+ (int64_t) relocation);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
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
+ || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && !resolved_to_zero)
|| h->root.type != bfd_link_hash_undefweak)
&& r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0
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)
{
if (sh_elf_osec_readonly_p (output_bfd,
input_section->output_section))
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "cannot emit fixup to `%s' in read-only section"),
input_bfd,
input_section,
- (long) rel->r_offset,
+ (uint64_t) rel->r_offset,
symname);
return FALSE;
}
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)
+ || ((ELF_ST_VISIBILITY (h->other)
+ || resolved_to_zero)
&& h->root.type == bfd_link_hash_undefweak))
{
/* This is actually a static link, or it is a
/* 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;
- if (srelgot == NULL)
- {
- srelgot = bfd_get_linker_section (dynobj,
- ".rela.got");
- BFD_ASSERT (srelgot != NULL);
- }
-
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
+ off);
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;
if (sh_elf_osec_readonly_p (output_bfd,
reloc_section->output_section))
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "cannot emit fixup to `%s' in read-only section"),
input_bfd,
input_section,
- (long) rel->r_offset,
+ (uint64_t) rel->r_offset,
symname);
return FALSE;
}
return FALSE;
}
- if (srelgot == NULL)
- {
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
- BFD_ASSERT (srelgot != NULL);
- }
-
offset = _bfd_elf_section_offset (output_bfd, info,
reloc_section, reloc_offset);
|| !SYMBOL_FUNCDESC_LOCAL (info, h)))
{
_bfd_error_handler
- (_("%B(%A+0x%lx): %s relocation against external symbol \"%s\""),
- input_bfd, input_section, (long) rel->r_offset, howto->name,
- h->root.root.string);
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "%s relocation against external symbol \"%s\""),
+ input_bfd, input_section, (uint64_t) rel->r_offset,
+ howto->name, h->root.root.string);
return FALSE;
}
else
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;
bfd_byte *loc;
int dr_type, indx;
- if (srelgot == NULL)
- {
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
- BFD_ASSERT (srelgot != NULL);
- }
-
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset + off);
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;
Elf_Internal_Rela outrel;
bfd_byte *loc;
- srelgot = htab->srelgot;
- if (srelgot == NULL)
- abort ();
-
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset + off);
outrel.r_addend = 0;
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
+ /* xgettext:c-format */
(_("%X%C: relocation to \"%s\" references a different segment\n"),
input_bfd, input_section, rel->r_offset, symname);
return FALSE;
}
else
info->callbacks->einfo
+ /* xgettext:c-format */
(_("%C: warning: 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)
if (*name == '\0')
name = bfd_section_name (input_bfd, sec);
}
- if (! ((*info->callbacks->reloc_overflow)
- (info, (h ? &h->root : NULL), name, howto->name,
- (bfd_vma) 0, input_bfd, input_section,
- rel->r_offset)))
- return FALSE;
+ (*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
}
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
-sh_elf_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;
- union gotref *local_funcdesc;
- const Elf_Internal_Rela *rel, *relend;
-
- if (info->relocatable)
- return TRUE;
-
- elf_section_data (sec)->local_dynrel = NULL;
-
- symtab_hdr = &elf_symtab_hdr (abfd);
- sym_hashes = elf_sym_hashes (abfd);
- local_got_refcounts = elf_local_got_refcounts (abfd);
- local_funcdesc = sh_elf_local_funcdesc (abfd);
-
- relend = relocs + sec->reloc_count;
- for (rel = relocs; rel < relend; rel++)
- {
- unsigned long r_symndx;
- unsigned int r_type;
- struct elf_link_hash_entry *h = NULL;
-#ifdef INCLUDE_SHMEDIA
- int seen_stt_datalabel = 0;
-#endif
-
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- struct elf_sh_link_hash_entry *eh;
- struct elf_sh_dyn_relocs **pp;
- struct elf_sh_dyn_relocs *p;
-
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- {
-#ifdef INCLUDE_SHMEDIA
- seen_stt_datalabel |= h->type == STT_DATALABEL;
-#endif
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
- }
- eh = (struct elf_sh_link_hash_entry *) h;
- for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
- if (p->sec == sec)
- {
- /* Everything must go for SEC. */
- *pp = p->next;
- break;
- }
- }
-
- r_type = ELF32_R_TYPE (rel->r_info);
- switch (sh_elf_optimized_tls_reloc (info, r_type, h != NULL))
- {
- case R_SH_TLS_LD_32:
- if (sh_elf_hash_table (info)->tls_ldm_got.refcount > 0)
- sh_elf_hash_table (info)->tls_ldm_got.refcount -= 1;
- break;
-
- case R_SH_GOT32:
- case R_SH_GOT20:
- case R_SH_GOTOFF:
- case R_SH_GOTOFF20:
- case R_SH_GOTPC:
-#ifdef INCLUDE_SHMEDIA
- case R_SH_GOT_LOW16:
- case R_SH_GOT_MEDLOW16:
- case R_SH_GOT_MEDHI16:
- case R_SH_GOT_HI16:
- case R_SH_GOT10BY4:
- case R_SH_GOT10BY8:
- case R_SH_GOTOFF_LOW16:
- case R_SH_GOTOFF_MEDLOW16:
- case R_SH_GOTOFF_MEDHI16:
- case R_SH_GOTOFF_HI16:
- case R_SH_GOTPC_LOW16:
- case R_SH_GOTPC_MEDLOW16:
- case R_SH_GOTPC_MEDHI16:
- case R_SH_GOTPC_HI16:
-#endif
- case R_SH_TLS_GD_32:
- case R_SH_TLS_IE_32:
- case R_SH_GOTFUNCDESC:
- case R_SH_GOTFUNCDESC20:
- if (h != NULL)
- {
-#ifdef INCLUDE_SHMEDIA
- if (seen_stt_datalabel)
- {
- struct elf_sh_link_hash_entry *eh;
- eh = (struct elf_sh_link_hash_entry *) h;
- if (eh->datalabel_got.refcount > 0)
- eh->datalabel_got.refcount -= 1;
- }
- else
-#endif
- if (h->got.refcount > 0)
- h->got.refcount -= 1;
- }
- else if (local_got_refcounts != NULL)
- {
-#ifdef INCLUDE_SHMEDIA
- if (rel->r_addend & 1)
- {
- if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
- local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
- }
- else
-#endif
- if (local_got_refcounts[r_symndx] > 0)
- local_got_refcounts[r_symndx] -= 1;
- }
- break;
-
- 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)
- sh_elf_hash_table (info)->srofixup->size -= 4;
-
- /* Fall through. */
-
- case R_SH_GOTOFFFUNCDESC:
- case R_SH_GOTOFFFUNCDESC20:
- if (h != NULL)
- sh_elf_hash_entry (h)->funcdesc.refcount -= 1;
- else
- local_funcdesc[r_symndx].refcount -= 1;
- break;
-
- case R_SH_DIR32:
- if (sh_elf_hash_table (info)->fdpic_p && !info->shared
- && (sec->flags & SEC_ALLOC) != 0)
- sh_elf_hash_table (info)->srofixup->size -= 4;
- /* Fall thru */
-
- case R_SH_REL32:
- if (info->shared)
- break;
- /* Fall thru */
-
- case R_SH_PLT32:
-#ifdef INCLUDE_SHMEDIA
- case R_SH_PLT_LOW16:
- case R_SH_PLT_MEDLOW16:
- case R_SH_PLT_MEDHI16:
- case R_SH_PLT_HI16:
-#endif
- if (h != NULL)
- {
- if (h->plt.refcount > 0)
- h->plt.refcount -= 1;
- }
- break;
-
- case R_SH_GOTPLT32:
-#ifdef INCLUDE_SHMEDIA
- case R_SH_GOTPLT_LOW16:
- case R_SH_GOTPLT_MEDLOW16:
- case R_SH_GOTPLT_MEDHI16:
- case R_SH_GOTPLT_HI16:
- case R_SH_GOTPLT10BY4:
- case R_SH_GOTPLT10BY8:
-#endif
- if (h != NULL)
- {
- struct elf_sh_link_hash_entry *eh;
- eh = (struct elf_sh_link_hash_entry *) h;
- if (eh->gotplt_refcount > 0)
- {
- eh->gotplt_refcount -= 1;
- if (h->plt.refcount > 0)
- h->plt.refcount -= 1;
- }
-#ifdef INCLUDE_SHMEDIA
- else if (seen_stt_datalabel)
- {
- if (eh->datalabel_got.refcount > 0)
- eh->datalabel_got.refcount -= 1;
- }
-#endif
- else if (h->got.refcount > 0)
- h->got.refcount -= 1;
- }
- else if (local_got_refcounts != NULL)
- {
-#ifdef INCLUDE_SHMEDIA
- if (rel->r_addend & 1)
- {
- if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
- local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
- }
- else
-#endif
- if (local_got_refcounts[r_symndx] > 0)
- local_got_refcounts[r_symndx] -= 1;
- }
- break;
-
- default:
- break;
- }
- }
-
- return TRUE;
-}
-
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
{
if (edir->dyn_relocs != NULL)
{
- struct elf_sh_dyn_relocs **pp;
- struct elf_sh_dyn_relocs *p;
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
- struct elf_sh_dyn_relocs *q;
+ struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec)
/* If called to transfer flags for a weakdef during processing
of elf_adjust_dynamic_symbol, don't copy non_got_ref.
We clear it ourselves for ELIMINATE_COPY_RELOCS. */
- dir->ref_dynamic |= ind->ref_dynamic;
+ if (dir->versioned != versioned_hidden)
+ dir->ref_dynamic |= ind->ref_dynamic;
dir->ref_regular |= ind->ref_regular;
dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
dir->needs_plt |= ind->needs_plt;
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;
+
+ /* Don't do anything special with non-loaded, non-alloced sections.
+ In particular, any relocs in such sections should not affect GOT
+ and PLT reference counting (ie. we don't allow them to create GOT
+ or PLT entries), there's no possibility or desire to optimize TLS
+ relocs, and there's not much point in propagating relocs to shared
+ libs that the dynamic linker won't relocate. */
+ if ((sec->flags & SEC_ALLOC) == 0)
return TRUE;
BFD_ASSERT (is_sh_elf (abfd));
#endif
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;
}
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
}
/* Some relocs require a global offset table. */
- if (htab->sgot == NULL)
+ if (htab->root.sgot == NULL)
{
switch (r_type)
{
/* This may require an rofixup. */
if (!htab->fdpic_p)
break;
+ /* Fall through. */
case R_SH_GOTPLT32:
case R_SH_GOT32:
case R_SH_GOT20:
break;
case R_SH_TLS_IE_32:
- if (info->shared)
+ if (bfd_link_pic (info))
info->flags |= DF_STATIC_TLS;
/* FALLTHROUGH */
if (local_got_refcounts == NULL)
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
-#ifdef INCLUDE_SHMEDIA
+#ifdef INCLUDE_SHMEDIA
/* Take care of both the datalabel and codelabel local
GOT offsets. */
sh_elf_local_got_type (abfd)
{
if ((old_got_type == GOT_FUNCDESC || got_type == GOT_FUNCDESC)
&& (old_got_type == GOT_NORMAL || got_type == GOT_NORMAL))
- (*_bfd_error_handler)
- (_("%B: `%s' accessed both as normal and FDPIC symbol"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%s' accessed both as normal and FDPIC symbol"),
abfd, h->root.root.string);
else if (old_got_type == GOT_FUNCDESC
|| got_type == GOT_FUNCDESC)
- (*_bfd_error_handler)
- (_("%B: `%s' accessed both as FDPIC and thread local symbol"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%s' accessed both as FDPIC and thread local symbol"),
abfd, h->root.root.string);
else
- (*_bfd_error_handler)
- (_("%B: `%s' accessed both as normal and thread local symbol"),
- abfd, h->root.root.string);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%s' accessed both as normal and thread local symbol"),
+ abfd, h->root.root.string);
return FALSE;
}
}
case R_SH_GOTOFFFUNCDESC20:
if (rel->r_addend)
{
- (*_bfd_error_handler)
- (_("%B: Function descriptor relocation with non-zero addend"),
+ _bfd_error_handler
+ (_("%pB: Function descriptor relocation with non-zero addend"),
abfd);
return FALSE;
}
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);
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
}
}
else
if (old_got_type != GOT_FUNCDESC && old_got_type != GOT_UNKNOWN)
{
if (old_got_type == GOT_NORMAL)
- (*_bfd_error_handler)
- (_("%B: `%s' accessed both as normal and FDPIC symbol"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%s' accessed both as normal and FDPIC symbol"),
abfd, h->root.root.string);
else
- (*_bfd_error_handler)
- (_("%B: `%s' accessed both as FDPIC and thread local symbol"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%s' accessed both as FDPIC and thread local symbol"),
abfd, h->root.root.string);
}
}
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
|| !h->def_regular)))
{
- struct elf_sh_dyn_relocs *p;
- struct elf_sh_dyn_relocs **head;
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
if (htab->root.dynobj == NULL)
htab->root.dynobj = abfd;
s = sec;
vpp = &elf_section_data (s)->local_dynrel;
- head = (struct elf_sh_dyn_relocs **) vpp;
+ head = (struct elf_dyn_relocs **) vpp;
}
p = *head;
/* 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"),
+ _bfd_error_handler
+ (_("%pB: TLS local exec code cannot be linked into shared objects"),
abfd);
return FALSE;
}
{
flagword flags = elf_elfheader (abfd)->e_flags & EF_SH_MACH_MASK;
- if (flags >= sizeof(sh_ef_bfd_table))
+ if (flags >= ARRAY_SIZE (sh_ef_bfd_table))
return FALSE;
if (sh_ef_bfd_table[flags] == 0)
return sh_elf_get_flags_from_mach (bfd_mach);
}
+/* Merge the architecture type of two BFD files, such that the
+ resultant architecture supports all the features required
+ by the two input BFDs.
+ If the input BFDs are multually incompatible - i.e. one uses
+ DSP while the other uses FPU - or there is no known architecture
+ that fits the requirements then an error is emitted. */
+
+static bfd_boolean
+sh_merge_bfd_arch (bfd *ibfd, struct bfd_link_info *info)
+{
+ bfd *obfd = info->output_bfd;
+ unsigned int old_arch, new_arch, merged_arch;
+
+ if (! _bfd_generic_verify_endian_match (ibfd, info))
+ return FALSE;
+
+ old_arch = sh_get_arch_up_from_bfd_mach (bfd_get_mach (obfd));
+ new_arch = sh_get_arch_up_from_bfd_mach (bfd_get_mach (ibfd));
+
+ merged_arch = SH_MERGE_ARCH_SET (old_arch, new_arch);
+
+ if (!SH_VALID_CO_ARCH_SET (merged_arch))
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: uses %s instructions while previous modules "
+ "use %s instructions"),
+ ibfd,
+ SH_ARCH_SET_HAS_DSP (new_arch) ? "dsp" : "floating point",
+ SH_ARCH_SET_HAS_DSP (new_arch) ? "floating point" : "dsp");
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else if (!SH_VALID_ARCH_SET (merged_arch))
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("internal error: merge of architecture '%s' with "
+ "architecture '%s' produced unknown architecture"),
+ bfd_printable_name (obfd),
+ bfd_printable_name (ibfd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ bfd_default_set_arch_mach (obfd, bfd_arch_sh,
+ sh_get_bfd_mach_from_arch_set (merged_arch));
+
+ return TRUE;
+}
+
/* This routine initialises the elf flags when required and
calls sh_merge_bfd_arch() to check dsp/fpu compatibility. */
static bfd_boolean
-sh_elf_merge_private_data (bfd *ibfd, bfd *obfd)
+sh_elf_merge_private_data (bfd *ibfd, struct bfd_link_info *info)
{
- extern bfd_boolean sh_merge_bfd_arch (bfd *, bfd *);
+ bfd *obfd = info->output_bfd;
if (! is_sh_elf (ibfd) || ! is_sh_elf (obfd))
return TRUE;
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))
+ if (! sh_merge_bfd_arch (ibfd, info))
{
- _bfd_error_handler ("%B: uses instructions which are incompatible "
- "with instructions used in previous modules",
+ _bfd_error_handler (_("%pB: uses instructions which are incompatible "
+ "with instructions used in previous modules"),
ibfd);
bfd_set_error (bfd_error_bad_value);
return FALSE;
if (fdpic_object_p (ibfd) != fdpic_object_p (obfd))
{
- _bfd_error_handler ("%B: attempt to mix FDPIC and non-FDPIC objects",
+ _bfd_error_handler (_("%pB: attempt to mix FDPIC and non-FDPIC objects"),
ibfd);
bfd_set_error (bfd_error_bad_value);
return FALSE;
BFD_ASSERT (h->dynindx != -1);
- splt = htab->splt;
- sgotplt = htab->sgotplt;
- srelplt = htab->srelplt;
+ splt = htab->root.splt;
+ sgotplt = htab->root.sgotplt;
+ srelplt = htab->root.srelplt;
BFD_ASSERT (splt != NULL && sgotplt != NULL && srelplt != NULL);
/* Get the index in the procedure linkage table which
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)
sgotplt->contents + got_offset);
if (htab->fdpic_p)
bfd_put_32 (output_bfd,
- sh_elf_osec_to_segment (output_bfd,
- htab->splt->output_section),
+ sh_elf_osec_to_segment (output_bfd, splt->output_section),
sgotplt->contents + got_offset + 4);
/* Fill in the entry in the .rela.plt section. */
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. */
/* Create a .rela.plt.unloaded R_SH_DIR32 relocation
for the PLT entry's pointer to the .got.plt entry. */
- rel.r_offset = (htab->splt->output_section->vma
- + htab->splt->output_offset
+ rel.r_offset = (splt->output_section->vma
+ + splt->output_offset
+ h->plt.offset
+ plt_info->symbol_fields.got_entry);
rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_SH_DIR32);
/* This symbol has an entry in the global offset table. Set it
up. */
- sgot = htab->sgot;
- srelgot = htab->srelgot;
+ sgot = htab->root.sgot;
+ srelgot = htab->root.srelgot;
BFD_ASSERT (sgot != NULL && srelgot != NULL);
rel.r_offset = (sgot->output_section->vma
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)
/* This symbol has a datalabel entry in the global offset table.
Set it up. */
- sgot = htab->sgot;
- srelgot = htab->srelgot;
+ sgot = htab->root.sgot;
+ srelgot = htab->root.srelgot;
BFD_ASSERT (sgot != NULL && srelgot != NULL);
rel.r_offset = (sgot->output_section->vma
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)
if (htab == NULL)
return FALSE;
- sgotplt = htab->sgotplt;
+ sgotplt = htab->root.sgotplt;
sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic");
if (htab->root.dynamic_sections_created)
break;
case DT_JMPREL:
- s = htab->srelplt->output_section;
+ s = htab->root.srelplt->output_section;
BFD_ASSERT (s != NULL);
dyn.d_un.d_ptr = s->vma;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
case DT_PLTRELSZ:
- s = htab->srelplt->output_section;
+ s = htab->root.srelplt->output_section;
BFD_ASSERT (s != NULL);
dyn.d_un.d_val = s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
-
- case DT_RELASZ:
- /* My reading of the SVR4 ABI indicates that the
- procedure linkage table relocs (DT_JMPREL) should be
- included in the overall relocs (DT_RELA). This is
- what Solaris does. However, UnixWare can not handle
- that case. Therefore, we override the DT_RELASZ entry
- here to make it not include the JMPREL relocs. Since
- the linker script arranges for .rela.plt to follow all
- other relocation sections, we don't have to worry
- about changing the DT_RELA entry. */
- if (htab->srelplt != NULL)
- {
- s = htab->srelplt->output_section;
- 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. */
- splt = htab->splt;
+ splt = htab->root.splt;
if (splt && splt->size > 0 && htab->plt_info->plt0_entry)
{
unsigned int i;
BFD_ASSERT (htab->srelfuncdesc->reloc_count * sizeof (Elf32_External_Rela)
== htab->srelfuncdesc->size);
- if (htab->srelgot)
- BFD_ASSERT (htab->srelgot->reloc_count * sizeof (Elf32_External_Rela)
- == htab->srelgot->size);
+ if (htab->root.srelgot)
+ BFD_ASSERT (htab->root.srelgot->reloc_count * sizeof (Elf32_External_Rela)
+ == htab->root.srelgot->size);
return TRUE;
}
sh_elf_merge_private_data
#define elf_backend_gc_mark_hook sh_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook sh_elf_gc_sweep_hook
#define elf_backend_check_relocs sh_elf_check_relocs
#define elf_backend_copy_indirect_symbol \
sh_elf_copy_indirect_symbol
#define elf_backend_plt_readonly 1
#define elf_backend_want_plt_sym 0
#define elf_backend_got_header_size 12
+#define elf_backend_dtrel_excludes_plt 1
+
+#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED