/* CRIS-specific support for 32-bit ELF.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2000-2016 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)
+ {
+ _bfd_error_handler (_("%B: invalid CRIS reloc number: %d"), abfd, r_type);
+ r_type = 0;
+ }
cache_ptr->howto = & cris_elf_howto_table [r_type];
}
case 202: /* Linux/CRISv32 */
/* pr_cursig */
- elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
- elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 22);
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 22);
/* pr_reg */
offset = 70;
case 214: /* Linux/CRIS */
/* pr_cursig */
- elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
- elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 22);
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 22);
/* pr_reg */
offset = 70;
return FALSE;
case 124: /* Linux/CRISv32 elf_prpsinfo */
- elf_tdata (abfd)->core_program
+ elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
- elf_tdata (abfd)->core_command
+ elf_tdata (abfd)->core->command
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
}
else
return FALSE;
case 124: /* Linux/CRIS elf_prpsinfo */
- elf_tdata (abfd)->core_program
+ elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
- elf_tdata (abfd)->core_command
+ elf_tdata (abfd)->core->command
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
}
implementations, so strip it off if it exists. */
{
- char *command = elf_tdata (abfd)->core_command;
+ char *command = elf_tdata (abfd)->core->command;
int n = strlen (command);
if (0 < n && command[n - 1] == ' ')
}
else
{
- bfd_boolean warned;
+ bfd_boolean warned, ignored;
bfd_boolean unresolved_reloc;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
h, sec, relocation,
- unresolved_reloc, warned);
+ unresolved_reloc, warned, ignored);
symname = h->root.root.string;
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)
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)
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_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;
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))))
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)))
{
asection *sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
BFD_ASSERT (sgotplt != NULL);
- if (info->shared)
+ if (bfd_link_pic (info))
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
break;
case R_CRIS_32_GD:
- if (info->shared)
+ if (bfd_link_pic (info))
{
bfd_set_error (bfd_error_invalid_operation);
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. */
break;
case R_CRIS_32_IE:
- if (info->shared)
+ if (bfd_link_pic (info))
{
bfd_set_error (bfd_error_invalid_operation);
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. */
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);
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)
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);
}
}
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
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);
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 = bfd_get_linker_section (dynobj, ".rela.plt");
+ 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 = bfd_get_linker_section (dynobj, ".rela.plt");
if (s == NULL)
dyn.d_un.d_val = 0;
else
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");
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
if (s != NULL)
dyn.d_un.d_val -= s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
{
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;
{
/* 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);
}
}
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;
/* 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;
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
h->needs_copy = 1;
}
- return _bfd_elf_adjust_dynamic_copy (h, s);
+ 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);
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
}
r_type = ELF32_R_TYPE (rel->r_info);
abfd, sec);
return FALSE;
}
+ }
- /* Create the .got section, so we can assume it's always
- present whenever there's a dynobj. */
+ if (sgot == NULL)
+ {
+ /* We may have a dynobj but no .got section, if machine-
+ independent parts of the linker found a reason to create
+ a dynobj. We want to create the .got section now, so we
+ can assume it's always present whenever there's a dynobj.
+ It's ok to call this function more than once. */
if (!_bfd_elf_create_got_section (dynobj, info))
return FALSE;
- }
- if (sgot == NULL)
- sgot = bfd_get_linker_section (dynobj, ".got");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ }
if (local_got_refcounts == NULL)
{
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)
+ if (!bfd_link_pic (info))
break;
/* Fall through. */
case R_CRIS_16_GOT:
case R_CRIS_32_GOT:
if (srelgot == NULL
- && (h != NULL || info->shared))
+ && (h != NULL || bfd_link_pic (info)))
{
srelgot = bfd_get_linker_section (dynobj, ".rela.got");
if (srelgot == NULL)
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)
(_("%B, section %A:\n relocation %s not valid"
/* 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)
{
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 (elf_hash_table (info)->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);
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)
#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)
{
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)
}
static enum elf_reloc_type_class
-elf_cris_reloc_type_class (const Elf_Internal_Rela *rela)
+elf_cris_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rela->r_info);
switch (r_type)
#define ELF_MACHINE_CODE EM_CRIS
#define ELF_MAXPAGESIZE 0x2000
-#define TARGET_LITTLE_SYM bfd_elf32_cris_vec
+#define TARGET_LITTLE_SYM cris_elf32_vec
#define TARGET_LITTLE_NAME "elf32-cris"
#define elf_symbol_leading_char 0
#undef TARGET_LITTLE_NAME
#undef elf_symbol_leading_char
-#define TARGET_LITTLE_SYM bfd_elf32_us_cris_vec
+#define TARGET_LITTLE_SYM cris_elf32_us_vec
#define TARGET_LITTLE_NAME "elf32-us-cris"
#define elf_symbol_leading_char '_'
#undef elf32_bed