/* 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-2015 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.
#include "elf/cris.h"
#include <limits.h>
-/* Forward declarations. */
-static reloc_howto_type * cris_reloc_type_lookup
- PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
-
-static void cris_info_to_howto_rela
- PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
-
-static bfd_reloc_status_type cris_elf_pcrel_reloc
- PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-
-static bfd_boolean cris_elf_grok_prstatus
- PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-
-static bfd_boolean cris_elf_grok_psinfo
- PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-
-static bfd_boolean cris_elf_relocate_section
- PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
- Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
-
-static bfd_reloc_status_type cris_final_link_relocate
- PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
- Elf_Internal_Rela *, bfd_vma));
-
-static bfd_boolean cris_elf_object_p PARAMS ((bfd *));
-
-static void cris_elf_final_write_processing PARAMS ((bfd *, bfd_boolean));
-
-static bfd_boolean cris_elf_set_mach_from_flags
- PARAMS ((bfd *, unsigned long int));
-
-static bfd_boolean cris_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
-
-static bfd_boolean cris_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
-static bfd_boolean cris_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
-
-struct elf_cris_link_hash_entry;
-static bfd_boolean elf_cris_discard_excess_dso_dynamics
- PARAMS ((struct elf_cris_link_hash_entry *, PTR));
-static bfd_boolean elf_cris_discard_excess_program_dynamics
- PARAMS ((struct elf_cris_link_hash_entry *, PTR));
-static bfd_boolean elf_cris_adjust_gotplt_to_got
- PARAMS ((struct elf_cris_link_hash_entry *, PTR));
-static bfd_boolean elf_cris_try_fold_plt_to_got
- PARAMS ((struct elf_cris_link_hash_entry *, PTR));
-static struct bfd_hash_entry *elf_cris_link_hash_newfunc
- PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-static struct bfd_link_hash_table *elf_cris_link_hash_table_create
- PARAMS ((bfd *));
-static bfd_boolean elf_cris_adjust_dynamic_symbol
- PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
-static bfd_boolean cris_elf_check_relocs
- PARAMS ((bfd *, struct bfd_link_info *, asection *,
- const Elf_Internal_Rela *));
-
-static bfd_boolean elf_cris_size_dynamic_sections
- PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean elf_cris_finish_dynamic_symbol
- PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
- Elf_Internal_Sym *));
-static bfd_boolean elf_cris_finish_dynamic_sections
- PARAMS ((bfd *, struct bfd_link_info *));
-static void elf_cris_hide_symbol
- PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
-static enum elf_reloc_type_class elf_cris_reloc_type_class
- PARAMS ((const Elf_Internal_Rela *));
+bfd_reloc_status_type
+cris_elf_pcrel_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+static bfd_boolean
+cris_elf_set_mach_from_flags (bfd *, unsigned long);
+/* Forward declarations. */
static reloc_howto_type cris_elf_howto_table [] =
{
/* 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 */
};
static reloc_howto_type *
-cris_reloc_type_lookup (abfd, code)
- bfd * abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
+cris_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
{
unsigned int i;
/* Set the howto pointer for an CRIS ELF reloc. */
static void
-cris_info_to_howto_rela (abfd, cache_ptr, dst)
- bfd * abfd ATTRIBUTE_UNUSED;
- arelent * cache_ptr;
- Elf_Internal_Rela * dst;
+cris_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
{
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];
}
bfd_reloc_status_type
-cris_elf_pcrel_reloc (abfd, reloc_entry, symbol, data, input_section,
- output_bfd, error_message)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data ATTRIBUTE_UNUSED;
- asection *input_section;
- bfd *output_bfd;
- char **error_message ATTRIBUTE_UNUSED;
+cris_elf_pcrel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
{
/* By default (using only bfd_elf_generic_reloc when linking to
non-ELF formats) PC-relative relocs are relative to the beginning
changes, while still keeping Linux/CRIS and Linux/CRISv32 code apart. */
static bfd_boolean
-cris_elf_grok_prstatus (abfd, note)
- bfd *abfd;
- Elf_Internal_Note *note;
+cris_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
int offset;
size_t size;
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;
}
static bfd_boolean
-cris_elf_grok_psinfo (abfd, note)
- bfd *abfd;
- Elf_Internal_Note *note;
+cris_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
switch (note->descsz)
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] == ' ')
bfd_signed_vma dtp_refcount;
};
+static bfd_boolean
+elf_cris_discard_excess_dso_dynamics (struct elf_cris_link_hash_entry *,
+ void * );
+static bfd_boolean
+elf_cris_discard_excess_program_dynamics (struct elf_cris_link_hash_entry *,
+ void *);
+
/* The local_got_refcounts and local_got_offsets are a multiple of
LSNUM in size, namely LGOT_ALLOC_NELTS_FOR(LSNUM) (plus one for the
refcount for GOT itself, see code), with the summary / group offset
struct elf_cris_link_hash_table *ret;
bfd_size_type amt = sizeof (struct elf_cris_link_hash_table);
- ret = ((struct elf_cris_link_hash_table *) bfd_malloc (amt));
+ ret = ((struct elf_cris_link_hash_table *) bfd_zmalloc (amt));
if (ret == (struct elf_cris_link_hash_table *) NULL)
return NULL;
are used for run-time symbol evaluation. */
ret->next_gotplt_entry = 12;
- /* We haven't seen any R_CRIS_nn_GOT_TPREL initially. */
- ret->dtpmod_refcount = 0;
-
return &ret->root.root;
}
\f
routines, with a few tweaks. */
static bfd_reloc_status_type
-cris_final_link_relocate (howto, input_bfd, input_section, contents, rel,
- relocation)
- reloc_howto_type * howto;
- bfd * input_bfd;
- asection * input_section;
- bfd_byte * contents;
- Elf_Internal_Rela * rel;
- bfd_vma relocation;
+cris_final_link_relocate (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation)
{
bfd_reloc_status_type r;
enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
}
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;
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
- if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ if (h == elf_hash_table (info)->hdynamic
|| h == elf_hash_table (info)->hgot)
sym->st_shndx = SHN_ABS;
computed. */
static bfd_boolean
-elf_cris_finish_dynamic_sections (output_bfd, info)
- bfd *output_bfd;
- struct bfd_link_info *info;
+elf_cris_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
{
bfd *dynobj;
asection *sgot;
{
bfd_size_type got_offset;
bfd_byte gotoffs_raw[4];
-
+
if (!bfd_get_section_contents (abfd, (asection *) plt, gotoffs_raw,
pltoffs + plt_entry_got_offset,
sizeof (gotoffs_raw)))
created (we're only linking static objects). */
static bfd_boolean
-elf_cris_adjust_gotplt_to_got (h, p)
- struct elf_cris_link_hash_entry *h;
- PTR p;
+elf_cris_adjust_gotplt_to_got (struct elf_cris_link_hash_entry *h, void * p)
{
struct bfd_link_info *info = (struct bfd_link_info *) p;
elf_cris_hide_symbol. */
static bfd_boolean
-elf_cris_try_fold_plt_to_got (h, p)
- struct elf_cris_link_hash_entry *h;
- PTR p;
+elf_cris_try_fold_plt_to_got (struct elf_cris_link_hash_entry *h, void * p)
{
struct bfd_link_info *info = (struct bfd_link_info *) p;
entry. */
static void
-elf_cris_hide_symbol (info, h, force_local)
- struct bfd_link_info *info;
- struct elf_link_hash_entry *h;
- bfd_boolean force_local;
+elf_cris_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ bfd_boolean force_local)
{
elf_cris_adjust_gotplt_to_got ((struct elf_cris_link_hash_entry *) h, info);
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. */
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)
{
relocate_section routine. */
static bfd_boolean
-elf_cris_discard_excess_dso_dynamics (h, inf)
- struct elf_cris_link_hash_entry *h;
- PTR inf;
+elf_cris_discard_excess_dso_dynamics (struct elf_cris_link_hash_entry *h,
+ void * inf)
{
struct elf_cris_pcrel_relocs_copied *s;
struct bfd_link_info *info = (struct bfd_link_info *) inf;
in the .got, but which we found we do not have to resolve at run-time. */
static bfd_boolean
-elf_cris_discard_excess_program_dynamics (h, inf)
- struct elf_cris_link_hash_entry *h;
- PTR inf;
+elf_cris_discard_excess_program_dynamics (struct elf_cris_link_hash_entry *h,
+ void * inf)
{
struct bfd_link_info *info = (struct bfd_link_info *) inf;
underscores on symbols. */
static bfd_boolean
-cris_elf_object_p (abfd)
- bfd *abfd;
+cris_elf_object_p (bfd *abfd)
{
if (! cris_elf_set_mach_from_flags (abfd, elf_elfheader (abfd)->e_flags))
return FALSE;
flags from mach type. */
static void
-cris_elf_final_write_processing (abfd, linker)
- bfd *abfd;
- bfd_boolean linker ATTRIBUTE_UNUSED;
+cris_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
{
unsigned long e_flags = elf_elfheader (abfd)->e_flags;
/* Set the mach type from e_flags value. */
static bfd_boolean
-cris_elf_set_mach_from_flags (abfd, flags)
- bfd *abfd;
- unsigned long flags;
+cris_elf_set_mach_from_flags (bfd *abfd,
+ unsigned long flags)
{
switch (flags & EF_CRIS_VARIANT_MASK)
{
/* Display the flags field. */
static bfd_boolean
-cris_elf_print_private_bfd_data (abfd, ptr)
- bfd *abfd;
- PTR ptr;
+cris_elf_print_private_bfd_data (bfd *abfd, void * ptr)
{
FILE *file = (FILE *) ptr;
/* Don't mix files with and without a leading underscore. */
static bfd_boolean
-cris_elf_merge_private_bfd_data (ibfd, obfd)
- bfd *ibfd;
- bfd *obfd;
+cris_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
{
int imach, omach;
/* Do side-effects of e_flags copying to obfd. */
static bfd_boolean
-cris_elf_copy_private_bfd_data (ibfd, obfd)
- bfd *ibfd;
- bfd *obfd;
+cris_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
/* Call the base function. */
if (!_bfd_elf_copy_private_bfd_data (ibfd, obfd))
}
static enum elf_reloc_type_class
-elf_cris_reloc_type_class (rela)
- 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