/* CRIS-specific support for 32-bit ELF.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010 Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 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. */
};
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;
}
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);
if (dynobj != NULL)
{
- splt = bfd_get_section_by_name (dynobj, ".plt");
- sgot = bfd_get_section_by_name (dynobj, ".got");
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got");
}
for (rel = relocs; rel < relend; rel ++)
}
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;
|| r_type == R_CRIS_16_PCREL
|| r_type == R_CRIS_32_PCREL))
relocation = 0;
- else if (!info->relocatable && unresolved_reloc)
+ else if (!info->relocatable && unresolved_reloc
+ && (_bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ != (bfd_vma) -1))
{
_bfd_error_handler
(_("%B, section %A: unresolvable relocation %s against symbol `%s'"),
}
}
- if (sec != NULL && elf_discarded_section (sec))
- {
- /* For relocs against symbols from removed linkonce sections,
- or sections discarded by a linker script, we just want the
- section contents zeroed. Avoid any special processing. */
- _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
- rel->r_info = 0;
- rel->r_addend = 0;
- continue;
- }
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
&& ((struct elf_cris_link_hash_entry *) h)->gotplt_offset != 0)
{
asection *sgotplt
- = bfd_get_section_by_name (dynobj, ".got.plt");
+ = bfd_get_linker_section (dynobj, ".got.plt");
bfd_vma got_offset;
BFD_ASSERT (h->dynindx != -1);
if (srelgot == NULL)
srelgot
- = bfd_get_section_by_name (dynobj, ".rela.got");
+ = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
outrel.r_offset = (sgot->output_section->vma
if (htab->dtpmod_refcount > 0
&& (input_section->flags & SEC_ALLOC) != 0)
{
- asection *sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+ asection *sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
BFD_ASSERT (sgotplt != NULL);
if (info->shared)
bfd_byte *loc;
if (srelgot == NULL)
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
loc = srelgot->contents;
loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_put_32 (output_bfd, 0, sgot->contents + off + 4);
if (srelgot == NULL)
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
if (h != NULL && h->dynindx != -1)
return FALSE;
}
- if (!info->shared && (h == NULL || h->def_regular))
+ if (!info->shared
+ && (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
{
/* Known contents of the GOT. */
bfd_vma off;
local_got_offsets[r_symndx] |= 1;
if (srelgot == NULL)
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
if (h != NULL && h->dynindx != -1)
BFD_ASSERT (h->dynindx != -1);
- splt = bfd_get_section_by_name (dynobj, ".plt");
- sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
- srela = bfd_get_section_by_name (dynobj, ".rela.plt");
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ srela = bfd_get_linker_section (dynobj, ".rela.plt");
BFD_ASSERT (splt != NULL && sgotplt != NULL
&& (! has_gotplt || srela != NULL));
/* This symbol has an entry in the global offset table. Set it up. */
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srela = bfd_get_section_by_name (dynobj, ".rela.got");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srela = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (sgot != NULL && srela != NULL);
rela.r_offset = (sgot->output_section->vma
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
- s = bfd_get_section_by_name (h->root.u.def.section->owner,
- ".rela.bss");
+ s = bfd_get_linker_section (dynobj, ".rela.bss");
BFD_ASSERT (s != NULL);
rela.r_offset = (h->root.u.def.value
}
/* 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;
dynobj = elf_hash_table (info)->dynobj;
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
BFD_ASSERT (sgot != NULL);
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)
{
asection *splt;
Elf32_External_Dyn *dyncon, *dynconend;
- splt = bfd_get_section_by_name (dynobj, ".plt");
+ splt = bfd_get_linker_section (dynobj, ".plt");
BFD_ASSERT (splt != NULL && sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
sym_hashes = elf_sym_hashes (abfd);
local_got_refcounts = elf_local_got_refcounts (abfd);
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
/* For local symbols, treat these like GOT relocs. */
if (h == NULL)
goto local_got_reloc;
+ else
+ /* For global symbols, adjust the reloc-specific refcount. */
+ elf_cris_hash_entry (h)->gotplt_refcount--;
/* Fall through. */
case R_CRIS_32_PLT_GOTREL:
local_got_refcounts[-1]--;
/* Fall through. */
+ case R_CRIS_8:
+ case R_CRIS_16:
+ case R_CRIS_32:
case R_CRIS_8_PCREL:
case R_CRIS_16_PCREL:
case R_CRIS_32_PCREL:
case R_CRIS_32_PLT_PCREL:
+ /* Negate the increment we did in cris_elf_check_relocs. */
if (h != NULL)
{
if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
/* The elf_backend_plt_sym_val hook function. */
static bfd_vma
-cris_elf_plt_sym_val (bfd_vma i, const asection *plt,
- const arelent *rel ATTRIBUTE_UNUSED)
+cris_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED, const asection *plt,
+ const arelent *rel)
{
bfd_size_type plt_entry_size;
+ bfd_size_type pltoffs;
+ bfd *abfd = plt->owner;
+
+ /* Same for CRIS and CRIS v32; see elf_cris_(|pic_)plt_entry(|_v32)[]. */
+ bfd_size_type plt_entry_got_offset = 2;
+ bfd_size_type plt_sec_size;
+ bfd_size_type got_vma_for_dyn;
+ asection *got;
+ /* FIXME: the .got section should be readily available also when
+ we're not linking. */
+ if ((got = bfd_get_section_by_name (abfd, ".got")) == NULL)
+ return (bfd_vma) -1;
+
+ plt_sec_size = bfd_section_size (plt->owner, plt);
plt_entry_size
- = (bfd_get_mach (plt->owner) == bfd_mach_cris_v32
+ = (bfd_get_mach (abfd) == bfd_mach_cris_v32
? PLT_ENTRY_SIZE_V32 : PLT_ENTRY_SIZE);
- return plt->vma + (i + 1) * plt_entry_size;
+ /* Data in PLT is GOT-relative for DYN, but absolute for EXE. */
+ got_vma_for_dyn = (abfd->flags & EXEC_P) ? 0 : got->vma;
+
+ /* Because we can have merged GOT entries; a single .got entry for
+ both GOT and the PLT part of the GOT (.got.plt), the index of the
+ reloc in .rela.plt is not the same as the index in the PLT.
+ Instead, we have to hunt down the GOT offset in the PLT that
+ corresponds to that of this reloc. Unfortunately, we will only
+ be called for the .rela.plt relocs, so we'll miss synthetic
+ symbols for .plt entries with merged GOT entries. (FIXME:
+ fixable by providing our own bfd_elf32_get_synthetic_symtab.
+ Doesn't seem worthwile at time of this writing.) FIXME: we've
+ gone from O(1) to O(N) (N number of PLT entries) for finding each
+ PLT address. Shouldn't matter in practice though. */
+
+ for (pltoffs = plt_entry_size;
+ pltoffs < plt_sec_size;
+ pltoffs += plt_entry_size)
+ {
+ 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)))
+ return (bfd_vma) -1;
+
+ got_offset = bfd_get_32 (abfd, gotoffs_raw);
+ if (got_offset + got_vma_for_dyn == rel->address)
+ return plt->vma + pltoffs;
+ }
+
+ /* While it's tempting to BFD_ASSERT that we shouldn't get here,
+ that'd not be graceful behavior for invalid input. */
+ return (bfd_vma) -1;
}
/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
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;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct elf_cris_link_hash_entry *) h->root.root.u.i.link;
+ /* A GOTPLT reloc, when activated, is supposed to be included into
+ the PLT refcount. */
+ BFD_ASSERT (h->gotplt_refcount == 0
+ || h->gotplt_refcount <= h->root.plt.refcount);
/* If nobody wanted a GOTPLT with this symbol, we're done. */
if (h->gotplt_refcount <= 0)
asection *srelgot;
BFD_ASSERT (dynobj != NULL);
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
/* Put accurate refcounts there. */
h->root.got.refcount += h->gotplt_refcount;
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);
return FALSE;
}
- s = bfd_get_section_by_name (dynobj, ".plt");
+ s = bfd_get_linker_section (dynobj, ".plt");
BFD_ASSERT (s != NULL);
/* If this is the first .plt entry, make room for the special
= htab->next_gotplt_entry;
htab->next_gotplt_entry += 4;
- s = bfd_get_section_by_name (dynobj, ".got.plt");
+ s = bfd_get_linker_section (dynobj, ".got.plt");
BFD_ASSERT (s != NULL);
s->size += 4;
/* We also need to make an entry in the .rela.plt section. */
- s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
BFD_ASSERT (s != NULL);
s->size += sizeof (Elf32_External_Rela);
if (!h->non_got_ref)
return TRUE;
- if (h->size == 0)
- {
- (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
- h->root.root.string);
- return TRUE;
- }
-
/* We must allocate the symbol in our .dynbss section, which will
become part of the .bss section of the executable. There will be
an entry for this symbol in the .dynsym section. The dynamic
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
- s = bfd_get_section_by_name (dynobj, ".dynbss");
+ 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_ALLOC) != 0)
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
{
asection *srel;
- srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
BFD_ASSERT (srel != NULL);
srel->size += sizeof (Elf32_External_Rela);
h->needs_copy = 1;
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_section_by_name (dynobj, ".got");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ }
if (local_got_refcounts == NULL)
{
if (srelgot == NULL
&& (h != NULL || info->shared))
{
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
if (srelgot == NULL)
{
- srelgot = bfd_make_section_with_flags (dynobj,
- ".rela.got",
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
+ 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;
sec,
cris_elf_howto_table[r_type].name);
}
+
+ /* We don't need to handle relocs into sections not going into
+ the "real" output. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ break;
+
if (h != NULL)
{
h->non_got_ref = 1;
if (! info->shared)
break;
- /* We don't need to handle relocs into sections not going into
- the "real" output. */
- if ((sec->flags & SEC_ALLOC) == 0)
- break;
-
/* We may need to create a reloc section in the dynobj and made room
for this reloc. */
if (sreloc == NULL)
/* Set the contents of the .interp section to the interpreter. */
if (info->executable)
{
- s = bfd_get_section_by_name (dynobj, ".interp");
+ s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
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_section_by_name (dynobj, ".rela.got");
+ s = bfd_get_linker_section (dynobj, ".rela.got");
if (s != NULL)
s->size = 0;
}
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;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct elf_cris_link_hash_entry *) h->root.root.u.i.link;
-
/* If a symbol has been forced local or we have found a regular
definition for the symbolic link case, then we won't be needing
any relocs. */
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;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct elf_cris_link_hash_entry *) h->root.root.u.i.link;
-
/* If we're not creating a shared library and have a symbol which is
referred to by .got references, but the symbol is defined locally,
(or rather, not defined by a DSO) then lose the reloc for the .got
BFD_ASSERT (dynobj != NULL);
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
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