/* CRIS-specific support for 32-bit ELF.
- Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
Contributed by Axis Communications AB.
Written by Hans-Peter Nilsson, based on elf32-fr30.c
PIC and shlib bits based primarily on elf32-m68k.c and elf32-i386.c.
/* This reloc does nothing. */
HOWTO (R_CRIS_NONE, /* type */
0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
+ 3, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_dont, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_CRIS_NONE", /* name */
FALSE, /* partial_inplace */
enum elf_cris_reloc_type r_type;
r_type = ELF32_R_TYPE (dst->r_info);
- BFD_ASSERT (r_type < (unsigned int) R_CRIS_max);
+ if (r_type >= R_CRIS_max)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: invalid CRIS reloc number: %d"), abfd, r_type);
+ r_type = 0;
+ }
cache_ptr->howto = & cris_elf_howto_table [r_type];
}
if (htab == NULL)
return FALSE;
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = htab->root.dynobj;
local_got_offsets = elf_local_got_offsets (input_bfd);
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
if (dynobj != NULL)
{
- splt = bfd_get_linker_section (dynobj, ".plt");
- sgot = bfd_get_linker_section (dynobj, ".got");
+ splt = htab->root.splt;
+ sgot = htab->root.sgot;
}
for (rel = relocs; rel < relend; rel ++)
time. FIXME: Not sure this example covers the
h->elf_link_hash_flags test, though it's there in
other targets. */
- if (info->shared
- && ((! info->symbolic && h->dynindx != -1)
+ if (bfd_link_pic (info)
+ && ((!SYMBOLIC_BIND (info, h) && h->dynindx != -1)
|| !h->def_regular)
&& (input_section->flags & SEC_ALLOC) != 0
&& (r_type == R_CRIS_8
|| r_type == R_CRIS_16_PCREL
|| r_type == R_CRIS_32_PCREL))
relocation = 0;
- else if (!info->relocatable && unresolved_reloc
+ else if (!bfd_link_relocatable (info) && unresolved_reloc
&& (_bfd_elf_section_offset (output_bfd, info,
input_section,
rel->r_offset)
!= (bfd_vma) -1))
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: unresolvable relocation %s against symbol `%s'"),
input_bfd,
input_section,
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
rel, 1, relend, howto, 0, contents);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
continue;
switch (r_type)
if (h != NULL
&& ((struct elf_cris_link_hash_entry *) h)->gotplt_offset != 0)
{
- asection *sgotplt
- = bfd_get_linker_section (dynobj, ".got.plt");
+ asection *sgotplt = htab->root.sgotplt;
bfd_vma got_offset;
BFD_ASSERT (h->dynindx != -1);
these call-specific relocs don't address non-functions. */
if (h != NULL
&& (h->got.offset == (bfd_vma) -1
- || (!info->shared
+ || (!bfd_link_pic (info)
&& !(h->def_regular
|| (!h->def_dynamic
&& h->root.type == bfd_link_hash_undefweak)))))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
((h->got.offset == (bfd_vma) -1)
+ /* xgettext:c-format */
? _("%B, section %A: No PLT nor GOT for relocation %s"
" against symbol `%s'")
+ /* xgettext:c-format */
: _("%B, section %A: No PLT for relocation %s"
" against symbol `%s'"),
input_bfd,
BFD_ASSERT (off != (bfd_vma) -1);
if (!elf_hash_table (info)->dynamic_sections_created
- || (! info->shared
+ || (! bfd_link_pic (info)
&& (h->def_regular
|| h->type == STT_FUNC
|| h->needs_plt))
- || (info->shared
- && (info->symbolic || h->dynindx == -1)
+ || (bfd_link_pic (info)
+ && (SYMBOLIC_BIND (info, h) || h->dynindx == -1)
&& h->def_regular))
{
- /* This wasn't checked above for ! info->shared, but
+ /* This wasn't checked above for ! bfd_link_pic (info), but
must hold there if we get here; the symbol must
be defined in the regular program or be undefweak
or be a function or otherwise need a PLT. */
BFD_ASSERT (!elf_hash_table (info)->dynamic_sections_created
- || info->shared
+ || bfd_link_pic (info)
|| h->def_regular
|| h->type == STT_FUNC
|| h->needs_plt
{
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");
+ srelgot = htab->root.srelgot;
BFD_ASSERT (srelgot != NULL);
outrel.r_offset = (sgot->output_section->vma
symbols. Make this an error; the compiler isn't
allowed to pass us these kinds of things. */
if (h == NULL)
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s with non-zero addend %d"
" against local symbol"),
input_bfd,
cris_elf_howto_table[r_type].name,
rel->r_addend);
else
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s with non-zero addend %d"
" against symbol `%s'"),
input_bfd,
defined in an ordinary (non-DSO) object or is undefined weak. */
if (h != NULL
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- && !(!info->shared
+ && !(!bfd_link_pic (info)
&& (h->def_regular
|| (!h->def_dynamic
&& h->root.type == bfd_link_hash_undefweak))))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s is"
" not allowed for global symbol: `%s'"),
input_bfd,
it's noticed if it happens elsewhere. */
if (sgot == NULL)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s with no GOT created"),
input_bfd,
input_section,
case R_CRIS_8:
case R_CRIS_16:
case R_CRIS_32:
- if (info->shared
+ if (bfd_link_pic (info)
&& r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0
&& ((r_type != R_CRIS_8_PCREL
&& r_type != R_CRIS_16_PCREL
&& r_type != R_CRIS_32_PCREL)
- || (!info->symbolic
+ || (!SYMBOLIC_BIND (info, h)
|| (h != NULL && !h->def_regular))))
{
Elf_Internal_Rela outrel;
/* h->dynindx may be -1 if the symbol was marked to
become local. */
else if (h != NULL
- && ((! info->symbolic && h->dynindx != -1)
+ && ((!SYMBOLIC_BIND (info, h) && h->dynindx != -1)
|| !h->def_regular))
{
BFD_ASSERT (h->dynindx != -1);
if (h != NULL
&& (input_section->flags & SEC_ALLOC) != 0
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- && (info->shared
+ && (bfd_link_pic (info)
|| (!h->def_regular
&& h->root.type != bfd_link_hash_undefined)))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
((h->root.type == bfd_link_hash_undefined)
/* We shouldn't get here for GCC-emitted code. */
+ /* xgettext:c-format */
? _("%B, section %A: relocation %s has an undefined"
" reference to `%s', perhaps a declaration mixup?")
- : ("%B, section %A: relocation %s is"
+ /* xgettext:c-format */
+ : _("%B, section %A: relocation %s is"
" not allowed for `%s', a global symbol with default"
" visibility, perhaps a declaration mixup?"),
input_bfd,
if (htab->dtpmod_refcount > 0
&& (input_section->flags & SEC_ALLOC) != 0)
{
- asection *sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ asection *sgotplt = htab->root.sgotplt;
BFD_ASSERT (sgotplt != NULL);
- 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");
+ srelgot = htab->root.srelgot;
BFD_ASSERT (srelgot != NULL);
loc = srelgot->contents;
loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
break;
case R_CRIS_32_GD:
- if (info->shared)
+ if (bfd_link_pic (info))
{
bfd_set_error (bfd_error_invalid_operation);
symbol *plus offset*. The GOT holds relocations for
symbols. Make this an error; the compiler isn't allowed
to pass us these kinds of things. */
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s with non-zero addend %d"
" against symbol `%s'"),
input_bfd,
return FALSE;
}
- if (!info->shared
+ if (!bfd_link_pic (info)
&& (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
{
/* Known contents of the GOT. */
bfd_put_32 (output_bfd, 0, sgot->contents + off);
bfd_put_32 (output_bfd, 0, sgot->contents + off + 4);
- if (srelgot == NULL)
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ srelgot = htab->root.srelgot;
BFD_ASSERT (srelgot != NULL);
if (h != NULL && h->dynindx != -1)
break;
case R_CRIS_32_IE:
- if (info->shared)
+ if (bfd_link_pic (info))
{
bfd_set_error (bfd_error_invalid_operation);
relocations for symbols. Make this an error; the
compiler isn't allowed to pass us these kinds of
things. */
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s with non-zero addend %d"
" against symbol `%s'"),
input_bfd,
return FALSE;
}
- if (!info->shared
+ if (!bfd_link_pic (info)
&& (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
{
/* Known contents of the GOT. */
else
local_got_offsets[r_symndx] |= 1;
- if (srelgot == NULL)
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ srelgot = htab->root.srelgot;
BFD_ASSERT (srelgot != NULL);
if (h != NULL && h->dynindx != -1)
case R_CRIS_32_TPREL:
/* This relocation must only be performed against symbols
defined in an ordinary (non-DSO) object. */
- if (info->shared)
+ if (bfd_link_pic (info))
{
bfd_set_error (bfd_error_invalid_operation);
been emitted. */
&& h->root.type != bfd_link_hash_undefined)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s is"
" not allowed for symbol: `%s'"
" which is defined outside the program,"
switch (r)
{
case bfd_reloc_overflow:
- r = info->callbacks->reloc_overflow
+ (*info->callbacks->reloc_overflow)
(info, (h ? &h->root : NULL), symname, howto->name,
(bfd_vma) 0, input_bfd, input_section, rel->r_offset);
if (additional_relocation_error_msg_count > 0)
only. */
case R_CRIS_16_GOT_TPREL:
case R_CRIS_16_GOT_GD:
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("(too many global variables for -fpic:"
" recompile with -fPIC)"));
break;
case R_CRIS_16_TPREL:
case R_CRIS_16_DTPREL:
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("(thread-local data too big for -fpic or"
" -msmall-tls: recompile with -fPIC or"
" -mno-small-tls)"));
break;
case bfd_reloc_undefined:
- r = info->callbacks->undefined_symbol
- (info, symname, input_bfd, input_section, rel->r_offset,
- TRUE);
+ (*info->callbacks->undefined_symbol)
+ (info, symname, input_bfd, input_section, rel->r_offset, TRUE);
break;
case bfd_reloc_outofrange:
}
if (msg)
- r = info->callbacks->warning
- (info, msg, symname, input_bfd, input_section, rel->r_offset);
-
- if (! r)
- return FALSE;
+ (*info->callbacks->warning) (info, msg, symname, input_bfd,
+ input_section, rel->r_offset);
}
}
Elf_Internal_Sym *sym)
{
struct elf_cris_link_hash_table * htab;
- bfd *dynobj;
/* Where in the plt entry to put values. */
int plt_off1 = 2, plt_off2 = 10, plt_off3 = 16;
plt_pic_entry = elf_cris_pic_plt_entry_v32;
}
- dynobj = elf_hash_table (info)->dynobj;
-
if (h->plt.offset != (bfd_vma) -1)
{
asection *splt;
BFD_ASSERT (h->dynindx != -1);
- splt = bfd_get_linker_section (dynobj, ".plt");
- sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
- srela = bfd_get_linker_section (dynobj, ".rela.plt");
+ splt = htab->root.splt;
+ sgotplt = htab->root.sgotplt;
+ srela = htab->root.srelplt;
BFD_ASSERT (splt != NULL && sgotplt != NULL
&& (! has_gotplt || srela != NULL));
got_base = sgotplt->output_section->vma + sgotplt->output_offset;
/* Fill in the entry in the procedure linkage table. */
- if (! info->shared)
+ if (! bfd_link_pic (info))
{
memcpy (splt->contents + h->plt.offset, plt_entry,
plt_entry_size);
references to the function symbol are redirected to the PLT. */
if (h->got.offset != (bfd_vma) -1
&& (elf_cris_hash_entry (h)->reg_got_refcount > 0)
- && (info->shared
+ && (bfd_link_pic (info)
|| (h->dynindx != -1
&& h->plt.offset == (bfd_vma) -1
&& !h->def_regular
/* This symbol has an entry in the global offset table. Set it up. */
- sgot = bfd_get_linker_section (dynobj, ".got");
- srela = bfd_get_linker_section (dynobj, ".rela.got");
+ sgot = htab->root.sgot;
+ srela = htab->root.srelgot;
BFD_ASSERT (sgot != NULL && srela != NULL);
rela.r_offset = (sgot->output_section->vma
initialized in the relocate_section function. */
where = sgot->contents + (h->got.offset &~ (bfd_vma) 1);
if (! elf_hash_table (info)->dynamic_sections_created
- || (info->shared
- && (info->symbolic || h->dynindx == -1)
+ || (bfd_link_pic (info)
+ && (SYMBOLIC_BIND (info, h) || h->dynindx == -1)
&& h->def_regular))
{
rela.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
- s = bfd_get_linker_section (dynobj, ".rela.bss");
- BFD_ASSERT (s != NULL);
+ if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+ s = htab->root.sreldynrelro;
+ else
+ s = htab->root.srelbss;
rela.r_offset = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
dynobj = elf_hash_table (info)->dynobj;
- sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ sgot = elf_hash_table (info)->sgotplt;
BFD_ASSERT (sgot != NULL);
sdyn = bfd_get_linker_section (dynobj, ".dynamic");
asection *splt;
Elf32_External_Dyn *dyncon, *dynconend;
- splt = bfd_get_linker_section (dynobj, ".plt");
+ splt = elf_hash_table (info)->splt;
BFD_ASSERT (splt != NULL && sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
break;
case DT_PLTGOT:
- s = bfd_get_section_by_name (output_bfd, ".got");
- BFD_ASSERT (s != NULL);
- dyn.d_un.d_ptr = s->vma;
+ dyn.d_un.d_ptr = sgot->output_section->vma + sgot->output_offset;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
case DT_JMPREL:
/* Yes, we *can* have a .plt and no .plt.rela, for instance
if all symbols are found in the .got (not .got.plt). */
- s = bfd_get_section_by_name (output_bfd, ".rela.plt");
- dyn.d_un.d_ptr = s != NULL ? s->vma : 0;
+ s = elf_hash_table (info)->srelplt;
+ dyn.d_un.d_ptr = s != NULL ? (s->output_section->vma
+ + s->output_offset) : 0;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
case DT_PLTRELSZ:
- s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+ s = elf_hash_table (info)->srelplt;
if (s == NULL)
dyn.d_un.d_val = 0;
else
dyn.d_un.d_val = s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
-
- case DT_RELASZ:
- /* The procedure linkage table relocs (DT_JMPREL) should
- not be included in the overall relocs (DT_RELA).
- 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. */
- s = bfd_get_section_by_name (output_bfd, ".rela.plt");
- if (s != NULL)
- dyn.d_un.d_val -= s->size;
- bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
- break;
}
}
{
if (bfd_get_mach (output_bfd) == bfd_mach_cris_v32)
{
- if (info->shared)
+ if (bfd_link_pic (info))
memcpy (splt->contents, elf_cris_pic_plt0_entry_v32,
PLT_ENTRY_SIZE_V32);
else
}
else
{
- if (info->shared)
+ if (bfd_link_pic (info))
memcpy (splt->contents, elf_cris_pic_plt0_entry,
PLT_ENTRY_SIZE);
else
asection *sgot;
asection *srelgot;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
dynobj = elf_hash_table (info)->dynobj;
sym_hashes = elf_sym_hashes (abfd);
local_got_refcounts = elf_local_got_refcounts (abfd);
- sgot = bfd_get_linker_section (dynobj, ".got");
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ sgot = htab->root.sgot;
+ srelgot = htab->root.srelgot;
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
{
/* We don't need the .got entry any more. */
sgot->size -= got_element_size;
- if (info->shared)
+ if (bfd_link_pic (info))
srelgot->size -= sizeof (Elf32_External_Rela);
}
}
else
{
/* No GOT entry for this symbol. We need to create one. */
- bfd *dynobj = elf_hash_table (info)->dynobj;
asection *sgot;
asection *srelgot;
- BFD_ASSERT (dynobj != NULL);
- sgot = bfd_get_linker_section (dynobj, ".got");
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ sgot = elf_hash_table (info)->sgot;
+ srelgot = elf_hash_table (info)->srelgot;
/* Put accurate refcounts there. */
h->root.got.refcount += h->gotplt_refcount;
struct elf_cris_link_hash_table * htab;
bfd *dynobj;
asection *s;
+ asection *srel;
bfd_size_type plt_entry_size;
htab = elf_cris_hash_table (info);
if (htab == NULL)
return FALSE;
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = htab->root.dynobj;
/* Make sure we know what is going on here. */
BFD_ASSERT (dynobj != NULL
result as one built without -fpic, specifically considering weak
symbols.
FIXME: m68k and i386 differ here, for unclear reasons. */
- if (! info->shared
+ if (! bfd_link_pic (info)
&& !h->def_dynamic)
{
/* This case can occur if we saw a PLT reloc in an input file,
like R_CRIS_JUMP_SLOT after symbol evaluation) we could get rid
of the PLT. We can't for the executable, because the GOT
entries will point to the PLT there (and be constant). */
- if (info->shared
+ if (bfd_link_pic (info)
&& !elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry*)
h, info))
return FALSE;
return FALSE;
}
- s = bfd_get_linker_section (dynobj, ".plt");
+ s = htab->root.splt;
BFD_ASSERT (s != NULL);
/* If this is the first .plt entry, make room for the special
/* If this symbol is not defined in a regular file, and we are
not generating a shared library, then set the symbol to this
location in the .plt. */
- if (!info->shared
+ if (!bfd_link_pic (info)
&& !h->def_regular)
{
h->root.u.def.section = s;
executable, because then the reloc associated with the PLT
would get a non-PLT reloc pointing to the PLT. FIXME: Move
this to elf_cris_try_fold_plt_to_got. */
- if (info->shared && h->got.refcount > 0)
+ if (bfd_link_pic (info) && h->got.refcount > 0)
{
h->got.refcount += h->plt.refcount;
= htab->next_gotplt_entry;
htab->next_gotplt_entry += 4;
- s = bfd_get_linker_section (dynobj, ".got.plt");
+ s = htab->root.sgotplt;
BFD_ASSERT (s != NULL);
s->size += 4;
/* We also need to make an entry in the .rela.plt section. */
- s = bfd_get_linker_section (dynobj, ".rela.plt");
+ s = htab->root.srelplt;
BFD_ASSERT (s != NULL);
s->size += sizeof (Elf32_External_Rela);
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
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
- s = bfd_get_linker_section (dynobj, ".dynbss");
- BFD_ASSERT (s != NULL);
-
/* We must generate a R_CRIS_COPY reloc to tell the dynamic linker to
copy the initial value out of the dynamic object and into the
runtime process image. We need to remember the offset into the
.rela.bss section we are going to use. */
+
+ if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+ {
+ s = htab->root.sdynrelro;
+ srel = htab->root.sreldynrelro;
+ }
+ else
+ {
+ s = htab->root.sdynbss;
+ srel = htab->root.srelbss;
+ }
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
{
- asection *srel;
-
- 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);
+ BFD_ASSERT (s != NULL);
+
+ return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
/* Adjust our "subclass" elements for an indirect symbol. */
asection *srelgot;
asection *sreloc;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
htab = elf_cris_hash_table (info);
that, we must insist on dynobj being a specific mach. */
if (bfd_get_mach (dynobj) == bfd_mach_cris_v10_v32)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A:\n v10/v32 compatible object %s"
" must not contain a PIC relocation"),
abfd, sec);
if (!_bfd_elf_create_got_section (dynobj, info))
return FALSE;
- sgot = bfd_get_linker_section (dynobj, ".got");
+ sgot = elf_hash_table (info)->sgot;
+ srelgot = elf_hash_table (info)->srelgot;
}
if (local_got_refcounts == NULL)
break;
}
- /* Some relocs require a global offset table (but perhaps not a
- specific GOT entry). */
- switch (r_type)
- {
- case R_CRIS_16_DTPREL:
- case R_CRIS_32_DTPREL:
- /* Not requesting .got.rela for an executable: the contents
- of the first entry is constant there. For a shared
- library, we need .got.rela for the R_CRIS_DTPMOD
- relocation at index 3. */
- if (!info->shared)
- break;
- /* Fall through. */
-
- case R_CRIS_32_IE:
- case R_CRIS_32_GD:
- case R_CRIS_16_GOT_GD:
- case R_CRIS_32_GOT_GD:
- case R_CRIS_32_GOT_TPREL:
- case R_CRIS_16_GOT_TPREL:
- /* Fall through. */
-
- /* For R_CRIS_16_GOTPLT and R_CRIS_32_GOTPLT, we need a GOT
- entry only for local symbols. Unfortunately, we don't know
- until later on if there's a version script that forces the
- symbol local. We must have the .rela.got section in place
- before we know if the symbol looks global now, so we need
- to treat the reloc just like for R_CRIS_16_GOT and
- R_CRIS_32_GOT. */
- case R_CRIS_16_GOTPLT:
- case R_CRIS_32_GOTPLT:
- case R_CRIS_16_GOT:
- case R_CRIS_32_GOT:
- if (srelgot == NULL
- && (h != NULL || info->shared))
- {
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
- if (srelgot == NULL)
- {
- 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;
- }
- }
- break;
-
- default:
- break;
- }
-
/* Warn and error for invalid input. */
switch (r_type)
{
case R_CRIS_32_TPREL:
case R_CRIS_16_TPREL:
case R_CRIS_32_GD:
- if (info->shared)
+ if (bfd_link_pic (info))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A:\n relocation %s not valid"
" in a shared object;"
" typically an option mixup, recompile with -fPIC"),
/* Those relocs also require that a DSO is of type
Initial Exec. Like other targets, we don't reset this
flag even if the relocs are GC:ed away. */
- if (info->shared)
+ if (bfd_link_pic (info))
info->flags |= DF_STATIC_TLS;
break;
if (local_got_refcounts[r_symndx_lgot] == 0)
{
sgot->size += got_element_size;
- if (info->shared)
+ if (bfd_link_pic (info))
{
/* If we are generating a shared object, we need
to output a R_CRIS_RELATIVE reloc so that the
can't help tables of (global) function pointers, for
example, though they must be emitted in a (writable) data
section to avoid having impure text sections. */
- if (info->shared
+ if (bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_READONLY) != 0)
{
/* FIXME: How do we make this optionally a warning only? */
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A:\n relocation %s should not"
" be used in a shared object; recompile with -fPIC"),
abfd,
render the symbol local. */
/* No need to do anything if we're not creating a shared object. */
- if (! info->shared)
+ if (! bfd_link_pic (info))
break;
/* We may need to create a reloc section in the dynobj and made room
render the symbol local. */
/* No need to do anything if we're not creating a shared object. */
- if (! info->shared)
+ if (! bfd_link_pic (info))
break;
/* We don't need to handle relocs into sections not going into
this shared library) then we can also eliminate the
reloc. See comment above for more eliminable cases which
we can't identify at this time. */
- if (info->symbolic
+ if (SYMBOLIC_BIND (info, h)
&& h->root.type != bfd_link_hash_defweak
&& h->def_regular)
break;
if (htab == NULL)
return FALSE;
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = htab->root.dynobj;
BFD_ASSERT (dynobj != NULL);
- if (elf_hash_table (info)->dynamic_sections_created)
+ 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);
not actually use these entries. Reset the size of .rela.got,
which will cause it to get stripped from the output file
below. */
- s = bfd_get_linker_section (dynobj, ".rela.got");
+ s = htab->root.srelgot;
if (s != NULL)
s->size = 0;
}
for relocs that have become for local symbols due to symbol
visibility changes. For programs, we discard space for relocs for
symbols not referenced by any dynamic object. */
- if (info->shared)
+ if (bfd_link_pic (info))
elf_cris_link_hash_traverse (htab,
elf_cris_discard_excess_dso_dynamics,
info);
{
if (strcmp (name, ".rela.got") == 0
&& htab->dtpmod_refcount != 0
- && info->shared)
+ && bfd_link_pic (info))
s->size += sizeof (Elf32_External_Rela);
if (s->size != 0)
}
}
else if (! CONST_STRNEQ (name, ".got")
- && strcmp (name, ".dynbss") != 0)
+ && strcmp (name, ".dynbss") != 0
+ && s != htab->root.sdynrelro)
{
/* It's not one of our sections, so don't allocate space. */
continue;
#define add_dynamic_entry(TAG, VAL) \
_bfd_elf_add_dynamic_entry (info, TAG, VAL)
- if (!info->shared)
+ if (!bfd_link_pic (info))
{
if (!add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
any relocs. */
if (h->root.def_regular
&& (h->root.forced_local
- || info->symbolic))
+ || SYMBOLIC_BIND (info, &h->root)))
{
for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
{
if ((s->section->flags & SEC_READONLY) != 0)
{
/* FIXME: How do we make this optionally a warning only? */
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section `%A', to symbol `%s':\n"
" relocation %s should not be used"
" in a shared object; recompile with -fPIC"),
&& elf_hash_table (info)->dynamic_sections_created)
{
bfd *dynobj = elf_hash_table (info)->dynobj;
- asection *srelgot;
+ asection *srelgot = elf_hash_table (info)->srelgot;
BFD_ASSERT (dynobj != NULL);
-
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
-
BFD_ASSERT (srelgot != NULL);
srelgot->size -= sizeof (Elf32_External_Rela);
have to export it as a dynamic symbol. This was already done for
functions; doing this for all symbols would presumably not
introduce new problems. Of course we don't do this if we're
- exporting all dynamic symbols. */
- if (! info->export_dynamic
+ exporting all dynamic symbols, or all data symbols, regardless of
+ them being referenced or not. */
+ if (! (info->export_dynamic
+ || (h->root.type != STT_FUNC && info->dynamic_data))
&& h->root.dynindx != -1
&& !h->root.def_dynamic
&& !h->root.ref_dynamic)
/* Don't mix files with and without a leading underscore. */
static bfd_boolean
-cris_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+cris_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
int imach, omach;
- if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ if (! _bfd_generic_verify_endian_match (ibfd, info))
return FALSE;
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
if (bfd_get_symbol_leading_char (ibfd)
!= bfd_get_symbol_leading_char (obfd))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(bfd_get_symbol_leading_char (ibfd) == '_'
? _("%B: uses _-prefixed symbols, but writing file with non-prefixed symbols")
: _("%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"),
|| (omach == bfd_mach_cris_v32
&& imach != bfd_mach_cris_v10_v32))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
((imach == bfd_mach_cris_v32)
? _("%B contains CRIS v32 code, incompatible"
" with previous objects")
static bfd_boolean
cris_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
- /* Call the base function. */
- if (!_bfd_elf_copy_private_bfd_data (ibfd, obfd))
- return FALSE;
-
- /* If output is big-endian for some obscure reason, stop here. */
- if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
- return FALSE;
-
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return TRUE;
+ /* Call the base function. */
+ if (!_bfd_elf_copy_private_bfd_data (ibfd, obfd))
+ return FALSE;
+
/* Do what we really came here for. */
return bfd_set_arch_mach (obfd, bfd_arch_cris, bfd_get_mach (ibfd));
}
#define elf_backend_want_plt_sym 0
#define elf_backend_got_header_size 12
#define elf_backend_got_elt_size elf_cris_got_elt_size
+#define elf_backend_dtrel_excludes_plt 1
+#define elf_backend_want_dynrelro 1
/* Later, we my want to optimize RELA entries into REL entries for dynamic
linking and libraries (if it's a win of any significance). Until then,