/* ADI Blackfin BFD support for 32-bit ELF.
- Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
bfd *abfd ATTRIBUTE_UNUSED,
arelent *reloc_entry ATTRIBUTE_UNUSED,
asymbol *symbol ATTRIBUTE_UNUSED,
- PTR data ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
asection *input_section ATTRIBUTE_UNUSED,
bfd *output_bfd ATTRIBUTE_UNUSED,
char **error_message ATTRIBUTE_UNUSED)
bfin_pcrel24_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol,
- PTR data,
+ void * data,
asection *input_section,
bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
/* if rightshift is 1 and the number odd, return error. */
if (howto->rightshift && (relocation & 0x01))
{
- (*_bfd_error_handler) (_("relocation should be even number"));
+ _bfd_error_handler (_("relocation should be even number"));
return bfd_reloc_overflow;
}
bfin_imm16_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol,
- PTR data,
+ void * data,
asection *input_section,
bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
bfin_byte4_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol,
- PTR data,
+ void * data,
asection *input_section,
bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
bfin_bfd_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol,
- PTR data,
+ void * data,
asection *input_section,
bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
/* If rightshift is 1 and the number odd, return error. */
if (howto->rightshift && (relocation & 0x01))
{
- (*_bfd_error_handler) (_("relocation should be even number"));
+ _bfd_error_handler (_("relocation should be even number"));
return bfd_reloc_overflow;
}
/* This reloc does nothing. . */
HOWTO (R_BFIN_UNUSED0, /* 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_BFIN_UNUSED0", /* name. */
FALSE, /* partial_inplace. */
HOWTO (R_BFIN_UNUSED1, /* 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_BFIN_UNUSED1", /* name. */
FALSE, /* partial_inplace. */
HOWTO (R_BFIN_UNUSEDB, /* 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_dont, /* complain_on_overflow. */
HOWTO (R_BFIN_UNUSEDC, /* 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_dont, /* complain_on_overflow. */
bfd_reloc_code_real_type code)
{
unsigned int i;
- unsigned int r_type = BFIN_RELOC_MIN;
+ unsigned int r_type = (unsigned int) -1;
- for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
+ for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); i--;)
if (bfin_reloc_map[i].bfd_reloc_val == code)
r_type = bfin_reloc_map[i].bfin_reloc_val;
- if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
+ if (r_type <= BFIN_RELOC_MAX)
return &bfin_howto_table [r_type];
else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
/* Given a bfin relocation type, return the howto. */
static reloc_howto_type *
bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
- unsigned int r_type)
+ unsigned int r_type)
{
if (r_type <= BFIN_RELOC_MAX)
return &bfin_howto_table [r_type];
/* Return TRUE if the name is a local label.
bfin local labels begin with L$. */
static bfd_boolean
-bfin_is_local_label_name (
- bfd *abfd,
- const char *label)
+bfin_is_local_label_name (bfd *abfd, const char *label)
{
if (label[0] == 'L' && label[1] == '$' )
return TRUE;
const Elf_Internal_Rela *rel_end;
asection *sgot;
asection *srelgot;
- if (info->relocatable)
+
+ if (bfd_link_relocatable (info))
return TRUE;
dynobj = elf_hash_table (info)->dynobj;
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
switch (ELF32_R_TYPE (rel->r_info))
{
return FALSE;
}
- if (sgot == NULL)
- {
- sgot = bfd_get_section_by_name (dynobj, ".got");
- BFD_ASSERT (sgot != NULL);
- }
-
- if (srelgot == NULL && (h != NULL || info->shared))
- {
- srelgot = bfd_get_section_by_name (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_with_flags (dynobj, ".rela.got",
- flags);
- if (srelgot == NULL
- || !bfd_set_section_alignment (dynobj, srelgot, 2))
- return FALSE;
- }
- }
+ sgot = elf_hash_table (info)->sgot;
+ srelgot = elf_hash_table (info)->srelgot;
+ BFD_ASSERT (sgot != NULL);
if (h != NULL)
{
if (local_got_refcounts[r_symndx] == 0)
{
sgot->size += 4;
- if (info->shared)
+ if (bfd_link_pic (info))
{
/* If we are generating a shared object, we need to
output a R_68K_RELATIVE reloc so that the dynamic
}
static enum elf_reloc_type_class
-elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
+elf32_bfin_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela * rela)
{
switch ((int) ELF32_R_TYPE (rela->r_info))
{
}
else
{
- bfd_boolean warned;
+ bfd_boolean warned, ignored;
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);
}
- if (sec != NULL && elf_discarded_section (sec))
+ if (sec != NULL && discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
continue;
address = rel->r_offset;
{
bfd_vma off;
- if (dynobj == NULL)
- {
- /* Create the .got section. */
- elf_hash_table (info)->dynobj = dynobj = output_bfd;
- if (!_bfd_elf_create_got_section (dynobj, info))
- return FALSE;
- }
-
- if (sgot == NULL)
+ if (dynobj == NULL)
{
- sgot = bfd_get_section_by_name (dynobj, ".got");
- BFD_ASSERT (sgot != NULL);
+ /* Create the .got section. */
+ elf_hash_table (info)->dynobj = dynobj = output_bfd;
+ if (!_bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
}
+ sgot = elf_hash_table (info)->sgot;
+ BFD_ASSERT (sgot != NULL);
+
if (h != NULL)
{
bfd_boolean dyn;
BFD_ASSERT (off != (bfd_vma) - 1);
dyn = elf_hash_table (info)->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)
&& (info->symbolic
|| h->dynindx == -1
|| h->forced_local)
{
bfd_put_32 (output_bfd, relocation, sgot->contents + off);
- if (info->shared)
+ if (bfd_link_pic (info))
{
asection *s;
Elf_Internal_Rela outrel;
bfd_byte *loc;
- s = bfd_get_section_by_name (dynobj, ".rela.got");
+ s = elf_hash_table (info)->srelgot;
BFD_ASSERT (s != NULL);
outrel.r_offset = (sgot->output_section->vma
because such sections are not SEC_ALLOC and thus ld.so will
not process them. */
if (unresolved_reloc
- && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
+ && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
input_bfd,
input_section, (long) rel->r_offset, h->root.root.string);
}
if (r == bfd_reloc_overflow)
- {
- 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);
else
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B(%A+0x%lx): reloc against `%s': error %d"),
input_bfd, input_section,
(long) rel->r_offset, name, (int) r);
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 = elf_hash_table (info)->sgot;
+ srelgot = elf_hash_table (info)->srelgot;
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
{
/* We don't need the .got entry any more. */
sgot->size -= 4;
- if (info->shared)
+ if (bfd_link_pic (info))
srelgot->size -= sizeof (Elf32_External_Rela);
}
}
return TRUE;
}
\f
-extern const bfd_target bfd_elf32_bfinfdpic_vec;
-#define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_bfinfdpic_vec)
+extern const bfd_target bfin_elf32_fdpic_vec;
+#define IS_FDPIC(bfd) ((bfd)->xvec == &bfin_elf32_fdpic_vec)
/* An extension of the elf hash table data structure,
containing some additional Blackfin-specific data. */
{
struct elf_link_hash_table elf;
- /* A pointer to the .got section. */
- asection *sgot;
- /* A pointer to the .rel.got section. */
- asection *sgotrel;
/* A pointer to the .rofixup section. */
asection *sgotfixup;
- /* A pointer to the .plt section. */
- asection *splt;
- /* A pointer to the .rel.plt section. */
- asection *spltrel;
/* GOT base offset. */
bfd_vma got0;
/* Location of the first non-lazy PLT entry, i.e., the number of
== BFIN_ELF_DATA ? ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash)) : NULL)
#define bfinfdpic_got_section(info) \
- (bfinfdpic_hash_table (info)->sgot)
+ (bfinfdpic_hash_table (info)->elf.sgot)
#define bfinfdpic_gotrel_section(info) \
- (bfinfdpic_hash_table (info)->sgotrel)
+ (bfinfdpic_hash_table (info)->elf.srelgot)
#define bfinfdpic_gotfixup_section(info) \
(bfinfdpic_hash_table (info)->sgotfixup)
#define bfinfdpic_plt_section(info) \
- (bfinfdpic_hash_table (info)->splt)
+ (bfinfdpic_hash_table (info)->elf.splt)
#define bfinfdpic_pltrel_section(info) \
- (bfinfdpic_hash_table (info)->spltrel)
+ (bfinfdpic_hash_table (info)->elf.srelplt)
#define bfinfdpic_relocs_info(info) \
(bfinfdpic_hash_table (info)->relocs_info)
#define bfinfdpic_got_initial_offset(info) \
struct bfinfdpic_elf_link_hash_table *ret;
bfd_size_type amt = sizeof (struct bfinfdpic_elf_link_hash_table);
- ret = bfd_zalloc (abfd, amt);
+ ret = bfd_zmalloc (amt);
if (ret == NULL)
return NULL;
for memory allocation purposes. */
inline static struct bfinfdpic_relocs_info *
bfinfdpic_relocs_info_for_global (struct htab *ht,
- bfd *abfd,
- struct elf_link_hash_entry *h,
- bfd_vma addend,
- enum insert_option insert)
+ bfd *abfd,
+ struct elf_link_hash_entry *h,
+ bfd_vma addend,
+ enum insert_option insert)
{
struct bfinfdpic_relocs_info entry;
inline static void
bfinfdpic_pic_merge_early_relocs_info (struct bfinfdpic_relocs_info *e2,
- struct bfinfdpic_relocs_info const *e1)
+ struct bfinfdpic_relocs_info const *e1)
{
e2->got17m4 |= e1->got17m4;
e2->gothilo |= e1->gothilo;
static bfd_vma
_bfinfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
- struct bfinfdpic_relocs_info *entry)
+ struct bfinfdpic_relocs_info *entry)
{
bfd_vma fixup_offset;
asection *sec,
Elf_Internal_Sym *sym,
bfd_vma addend)
-
{
- bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
+ bfd_vma fd_lazy_rel_offset = (bfd_vma) -1;
int dynindx = -1;
if (entry->done)
/* If we're linking an executable at a fixed address, we can
omit the dynamic relocation as long as the symbol is local to
this module. */
- if (info->executable && !info->pie
+ if (bfd_link_pde (info)
&& (entry->symndx != -1
|| BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
{
if (entry->symndx == -1
&& ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
&& BFINFDPIC_SYM_LOCAL (info, entry->d.h)
- && !(info->executable && !info->pie))
+ && !bfd_link_pde (info))
{
reloc = R_BFIN_FUNCDESC;
idx = elf_section_data (entry->d.h->root.u.def.section
dynamic symbol entry for the got section, so idx will be
zero, which means we can and should compute the address
of the private descriptor ourselves. */
- if (info->executable && !info->pie
+ if (bfd_link_pde (info)
&& (entry->symndx != -1
|| BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
{
/* If we're linking an executable at a fixed address, we can
omit the dynamic relocation as long as the symbol is local to
this module. */
- if (info->executable && !info->pie
+ if (bfd_link_pde (info)
&& (entry->symndx != -1 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
{
if (sec)
/* If we've omitted the dynamic relocation, just emit the fixed
addresses of the symbol and of the local GOT base offset. */
- if (info->executable && !info->pie && sec && sec->output_section)
+ if (bfd_link_pde (info)
+ && sec
+ && sec->output_section)
{
lowword = ad;
highword = bfinfdpic_got_section (info)->output_section->vma
Elf_Internal_Rela *relend;
unsigned isec_segment, got_segment, plt_segment,
check_segment[2];
- int silence_segment_error = !(info->shared || info->pie);
+ int silence_segment_error = !bfd_link_pic (info);
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
}
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);
osec = sec;
}
- if (sec != NULL && elf_discarded_section (sec))
+ if (sec != NULL && discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
continue;
if (h != NULL
case R_BFIN_BYTE4_DATA:
if (! IS_FDPIC (output_bfd))
goto non_fdpic;
+ /* Fall through. */
case R_BFIN_GOT17M4:
case R_BFIN_GOTHI:
osec, sym,
rel->r_addend))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"),
input_bfd, input_section, rel->r_offset, name);
return FALSE;
default:
non_fdpic:
picrel = NULL;
- if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
+ if (h && ! BFINFDPIC_SYM_LOCAL (info, h)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
{
info->callbacks->warning
(info, _("relocation references symbol not defined in the module"),
section+offset. */
if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h)
&& BFINFDPIC_SYM_LOCAL (info, h)
- && !(info->executable && !info->pie))
+ && !bfd_link_pde (info))
{
dynindx = elf_section_data (h->root.u.def.section
->output_section)->dynindx;
dynamic symbol entry for the got section, so idx will
be zero, which means we can and should compute the
address of the private descriptor ourselves. */
- if (info->executable && !info->pie
+ if (bfd_link_pde (info)
&& (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h)))
{
bfd_vma offset;
can omit the dynamic relocation as long as the symbol
is defined in the current link unit (which is implied
by its output section not being NULL). */
- if (info->executable && !info->pie
+ if (bfd_link_pde (info)
&& (!h || BFINFDPIC_SYM_LOCAL (info, h)))
{
if (osec)
/* If we've omitted the dynamic relocation, just emit
the fixed addresses of the symbol and of the local
GOT base offset. */
- if (info->executable && !info->pie
+ if (bfd_link_pde (info)
&& (!h || BFINFDPIC_SYM_LOCAL (info, h)))
bfd_put_32 (output_bfd,
bfinfdpic_got_section (info)->output_section->vma
&& picrel->d.h->root.type == bfd_link_hash_undefined))
info->callbacks->warning
(info,
- (info->shared || info->pie)
+ bfd_link_pic (info)
? _("relocations between different segments are not supported")
: _("warning: relocation references a different segment"),
name, input_bfd, input_section, rel->r_offset);
- if (!silence_segment_error && (info->shared || info->pie))
+ if (!silence_segment_error && bfd_link_pic (info))
return FALSE;
elf_elfheader (output_bfd)->e_flags |= EF_BFIN_PIC;
}
switch (r)
{
case bfd_reloc_overflow:
- r = info->callbacks->reloc_overflow
+ (*info->callbacks->reloc_overflow)
(info, (h ? &h->root : NULL), name, howto->name,
(bfd_vma) 0, input_bfd, input_section, rel->r_offset);
break;
case bfd_reloc_undefined:
- r = info->callbacks->undefined_symbol
+ (*info->callbacks->undefined_symbol)
(info, name, input_bfd, input_section, rel->r_offset, TRUE);
break;
}
if (msg)
- r = info->callbacks->warning
- (info, msg, name, input_bfd, input_section, rel->r_offset);
-
- if (! r)
- return FALSE;
+ (*info->callbacks->warning) (info, msg, name, input_bfd,
+ input_section, rel->r_offset);
}
}
int ptralign;
/* This function may be called more than once. */
- s = bfd_get_section_by_name (abfd, ".got");
- if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
+ s = elf_hash_table (info)->sgot;
+ if (s != NULL)
return TRUE;
/* Machine specific: although pointers are 32-bits wide, we want the
| SEC_LINKER_CREATED);
pltflags = flags;
- s = bfd_make_section_with_flags (abfd, ".got", flags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ elf_hash_table (info)->sgot = s;
if (s == NULL
|| !bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
- if (bed->want_got_plt)
- {
- s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
- if (s == NULL
- || !bfd_set_section_alignment (abfd, s, ptralign))
- return FALSE;
- }
-
if (bed->want_got_sym)
{
/* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
data for the got. */
if (IS_FDPIC (abfd))
{
- bfinfdpic_got_section (info) = s;
bfinfdpic_relocs_info (info) = htab_try_create (1,
bfinfdpic_relocs_info_hash,
bfinfdpic_relocs_info_eq,
if (! bfinfdpic_relocs_info (info))
return FALSE;
- s = bfd_make_section_with_flags (abfd, ".rel.got",
- (flags | SEC_READONLY));
+ s = bfd_make_section_anyway_with_flags (abfd, ".rel.got",
+ (flags | SEC_READONLY));
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, 2))
return FALSE;
bfinfdpic_gotrel_section (info) = s;
/* Machine-specific. */
- s = bfd_make_section_with_flags (abfd, ".rofixup",
- (flags | SEC_READONLY));
+ s = bfd_make_section_anyway_with_flags (abfd, ".rofixup",
+ (flags | SEC_READONLY));
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, 2))
return FALSE;
if (bed->plt_readonly)
pltflags |= SEC_READONLY;
- s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
return FALSE;
h->def_regular = 1;
h->type = STT_OBJECT;
- if (! info->executable
+ if (! bfd_link_executable (info)
&& ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
/* Blackfin-specific: we want rel relocations for the plt. */
- s = bfd_make_section_with_flags (abfd, ".rel.plt", flags | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd, ".rel.plt",
+ flags | SEC_READONLY);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
image and use a R_*_COPY reloc to tell the dynamic linker to
initialize them at run time. The linker script puts the .dynbss
section into the .bss section of the final image. */
- s = bfd_make_section_with_flags (abfd, ".dynbss",
- SEC_ALLOC | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
if (s == NULL)
return FALSE;
/* The .rel[a].bss section holds copy relocs. This section is not
- normally needed. We need to create it here, though, so that the
- linker will map it to an output section. We can't just create it
- only if we need it, because we will not know whether we need it
- until we have seen all the input files, and the first time the
- main linker code calls BFD after examining all the input files
- (size_dynamic_sections) the input sections have already been
- mapped to the output sections. If the section turns out not to
- 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)
+ normally needed. We need to create it here, though, so that the
+ linker will map it to an output section. We can't just create it
+ only if we need it, because we will not know whether we need it
+ until we have seen all the input files, and the first time the
+ main linker code calls BFD after examining all the input files
+ (size_dynamic_sections) the input sections have already been
+ mapped to the output sections. If the section turns out not to
+ 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 (! bfd_link_pic (info))
{
- s = bfd_make_section_with_flags (abfd,
- ".rela.bss",
- flags | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd,
+ ".rela.bss",
+ flags | SEC_READONLY);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
{
bfd_vma relocs = 0, fixups = 0;
- if (!dinfo->info->executable || dinfo->info->pie)
+ if (!bfd_link_pde (dinfo->info))
relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv;
else
{
if (htab->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_section_by_name (dynobj, ".interp");
+ s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
return FALSE;
}
- s = bfd_get_section_by_name (dynobj, ".dynbss");
+ s = bfd_get_linker_section (dynobj, ".dynbss");
if (s && s->size == 0)
s->flags |= SEC_EXCLUDE;
- s = bfd_get_section_by_name (dynobj, ".rela.bss");
+ s = bfd_get_linker_section (dynobj, ".rela.bss");
if (s && s->size == 0)
s->flags |= SEC_EXCLUDE;
elf32_bfinfdpic_always_size_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
- if (!info->relocatable)
- {
- struct elf_link_hash_entry *h;
-
- /* Force a PT_GNU_STACK segment to be created. */
- if (! elf_tdata (output_bfd)->stack_flags)
- elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
-
- /* Define __stacksize if it's not defined yet. */
- h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
- FALSE, FALSE, FALSE);
- if (! h || h->root.type != bfd_link_hash_defined
- || h->type != STT_OBJECT
- || !h->def_regular)
- {
- struct bfd_link_hash_entry *bh = NULL;
-
- if (!(_bfd_generic_link_add_one_symbol
- (info, output_bfd, "__stacksize",
- BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE,
- (const char *) NULL, FALSE,
- get_elf_backend_data (output_bfd)->collect, &bh)))
- return FALSE;
-
- h = (struct elf_link_hash_entry *) bh;
- h->def_regular = 1;
- h->type = STT_OBJECT;
- }
- }
+ if (!bfd_link_relocatable (info)
+ && !bfd_elf_stack_segment_size (output_bfd, info,
+ "__stacksize", DEFAULT_STACK_SIZE))
+ return FALSE;
return TRUE;
}
subtract it from the relocation or fixup count. */
static bfd_boolean
_bfinfdpic_check_discarded_relocs (bfd *abfd, asection *sec,
- struct bfd_link_info *info,
-
- bfd_boolean *changed)
+ struct bfd_link_info *info,
+ bfd_boolean *changed)
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
/* Account for relaxation of .eh_frame section. */
for (s = ibfd->sections; s; s = s->next)
- if (s->sec_info_type == ELF_INFO_TYPE_EH_FRAME)
+ if (s->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
{
if (!_bfinfdpic_check_discarded_relocs (ibfd, s, info, &changed))
return FALSE;
return TRUE;
}
-static bfd_boolean
-elf32_bfinfdpic_modify_program_headers (bfd *output_bfd,
- struct bfd_link_info *info)
-{
- struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
- struct elf_segment_map *m;
- Elf_Internal_Phdr *p;
-
- /* objcopy and strip preserve what's already there using
- elf32_bfinfdpic_copy_private_bfd_data (). */
- if (! info)
- return TRUE;
-
- for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
- if (m->p_type == PT_GNU_STACK)
- break;
-
- if (m)
- {
- struct elf_link_hash_entry *h;
-
- /* Obtain the pointer to the __stacksize symbol. */
- h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
- FALSE, FALSE, FALSE);
- if (h)
- {
- 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;
- BFD_ASSERT (h->root.type == bfd_link_hash_defined);
- }
-
- /* Set the header p_memsz from the symbol value. We
- intentionally ignore the symbol section. */
- if (h && h->root.type == bfd_link_hash_defined)
- p->p_memsz = h->root.u.def.value;
- else
- p->p_memsz = DEFAULT_STACK_SIZE;
-
- p->p_align = 8;
- }
-
- return TRUE;
-}
-
static bfd_boolean
elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd,
struct bfd_link_info *info)
if (bfinfdpic_got_section (info))
{
BFD_ASSERT (bfinfdpic_gotrel_section (info)->size
- == (bfinfdpic_gotrel_section (info)->reloc_count
+ /* PR 17334: It appears that the GOT section can end up
+ being bigger than the number of relocs. Presumably
+ because some relocs have been deleted. A test case has
+ yet to be generated for verify this, but in the meantime
+ the test below has been changed from == to >= so that
+ applications can continue to be built. */
+ >= (bfinfdpic_gotrel_section (info)->reloc_count
* sizeof (Elf32_External_Rel)));
if (bfinfdpic_gotfixup_section (info))
if (bfinfdpic_gotfixup_section (info)->size
!= (bfinfdpic_gotfixup_section (info)->reloc_count * 4))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
("LINKER BUG: .rofixup section size mismatch");
return FALSE;
}
* sizeof (Elf32_External_Rel)));
}
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)
{
regular object. */
static bfd_boolean
-elf32_bfinfdpic_adjust_dynamic_symbol
-(struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
+elf32_bfinfdpic_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
{
bfd * dynobj;
bfd *dynobj;
struct bfinfdpic_relocs_info *picrel;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
default:
bad_reloc:
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unsupported relocation type %i"),
abfd, ELF32_R_TYPE (rel->r_info));
return FALSE;
return TRUE;
}
-/* Copy backend specific data from one object module to another. */
-
-static bfd_boolean
-bfin_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
-{
- if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
- || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
- return TRUE;
-
- BFD_ASSERT (!elf_flags_init (obfd)
- || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
-
- elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
- elf_flags_init (obfd) = TRUE;
-
- /* Copy object attributes. */
- _bfd_elf_copy_obj_attributes (ibfd, obfd);
-
- return TRUE;
-}
-
-static bfd_boolean
-elf32_bfinfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
-{
- unsigned i;
-
- if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
- || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
- return TRUE;
-
- if (! bfin_elf_copy_private_bfd_data (ibfd, obfd))
- return FALSE;
-
- if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
- || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
- return TRUE;
-
- /* Copy the stack size. */
- for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
- if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
- {
- Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
-
- for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
- if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
- {
- memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
-
- /* Rewrite the phdrs, since we're only called after they
- were first written. */
- if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
- ->s->sizeof_ehdr, SEEK_SET) != 0
- || get_elf_backend_data (obfd)->s
- ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
- elf_elfheader (obfd)->e_phnum) != 0)
- return FALSE;
- break;
- }
-
- break;
- }
-
- return TRUE;
-}
-
-
/* Display the flags field. */
static bfd_boolean
-elf32_bfin_print_private_bfd_data (bfd * abfd, PTR ptr)
+elf32_bfin_print_private_bfd_data (bfd * abfd, void * ptr)
{
FILE *file = (FILE *) ptr;
flagword flags;
object file when linking. */
static bfd_boolean
-elf32_bfin_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+elf32_bfin_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
flagword old_flags, new_flags;
bfd_boolean error = FALSE;
#ifndef DEBUG
if (0)
#endif
- (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
- old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
- bfd_get_filename (ibfd));
+ _bfd_error_handler
+ ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
+ old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
+ bfd_get_filename (ibfd));
if (!elf_flags_init (obfd)) /* First call, no flags set. */
{
{
error = TRUE;
if (IS_FDPIC (obfd))
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%s: cannot link non-fdpic object file into fdpic executable"),
bfd_get_filename (ibfd));
else
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%s: cannot link fdpic object file into non-fdpic executable"),
bfd_get_filename (ibfd));
}
struct bfin_link_hash_table *ret;
bfd_size_type amt = sizeof (struct bfin_link_hash_table);
- ret = bfd_zalloc (abfd, amt);
+ ret = bfd_zmalloc (amt);
if (ret == NULL)
return NULL;
static bfd_boolean
bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info)
+ struct bfd_link_info *info)
{
bfd *dynobj;
asection *sdyn;
dynobj = elf_hash_table (info)->dynobj;
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)
{
static bfd_boolean
bfin_finish_dynamic_symbol (bfd * output_bfd,
- struct bfd_link_info *info,
- struct elf_link_hash_entry *h,
- Elf_Internal_Sym * sym)
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym * sym)
{
- bfd *dynobj;
-
- dynobj = elf_hash_table (info)->dynobj;
-
if (h->got.offset != (bfd_vma) - 1)
{
asection *sgot;
/* 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 = elf_hash_table (info)->sgot;
+ srela = elf_hash_table (info)->srelgot;
BFD_ASSERT (sgot != NULL && srela != NULL);
rela.r_offset = (sgot->output_section->vma
the symbol was forced to be local because of a version file.
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)
&& (info->symbolic
|| h->dynindx == -1 || h->forced_local) && h->def_regular)
{
- (*_bfd_error_handler) (_("*** check this relocation %s"),
- __FUNCTION__);
+ _bfd_error_handler (_("*** check this relocation %s"),
+ __FUNCTION__);
rela.r_info = ELF32_R_INFO (0, R_BFIN_PCREL24);
rela.r_addend = bfd_get_signed_32 (output_bfd,
(sgot->contents
static bfd_boolean
bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
+ struct elf_link_hash_entry *h)
{
bfd *dynobj;
asection *s;
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;
/* We must allocate the symbol in our .dynbss section, which will
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_68K_COPY reloc to tell the dynamic linker to
+#if 0 /* Bfin does not currently have a COPY reloc. */
+ /* We must generate a R_BFIN_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. */
{
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;
}
-
+#else
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ _bfd_error_handler (_("the bfin target does not currently support the generation of copy relocations"));
+ return FALSE;
+ }
+#endif
/* We need to figure out the alignment required for this symbol. I
have no idea how ELF linkers handle this. */
power_of_two = bfd_log2 (h->size);
case. */
static bfd_boolean
-bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
+bfin_discard_copies (struct elf_link_hash_entry *h, void * inf)
{
struct bfd_link_info *info = (struct bfd_link_info *) inf;
struct bfin_pcrel_relocs_copied *s;
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
if (!h->def_regular || (!info->symbolic && !h->forced_local))
{
if ((info->flags & DF_TEXTREL) == 0)
static bfd_boolean
bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info)
+ struct bfd_link_info *info)
{
bfd *dynobj;
asection *s;
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))
{
- 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 = elf_hash_table (info)->srelgot;
if (s != NULL)
s->size = 0;
}
against symbols that have become local due to visibility changes.
We allocated space for them in the check_relocs routine, but we
will not fill them in in the relocate_section routine. */
- if (info->shared)
+ if (bfd_link_pic (info))
elf_link_hash_traverse (elf_hash_table (info),
- bfin_discard_copies, (PTR) info);
+ bfin_discard_copies, info);
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
#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;
after the add_symbols entry point has been called for all the
objects, and before the final_link entry point is called. */
-bfd_boolean bfd_bfin_elf32_create_embedded_relocs
- PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **));
-
bfd_boolean
-bfd_bfin_elf32_create_embedded_relocs (
- bfd *abfd,
- struct bfd_link_info *info,
- asection *datasec,
- asection *relsec,
- char **errmsg)
+bfd_bfin_elf32_create_embedded_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *datasec,
+ asection *relsec,
+ char **errmsg)
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Sym *isymbuf = NULL;
bfd_byte *p;
bfd_size_type amt;
- BFD_ASSERT (! info->relocatable);
+ BFD_ASSERT (! bfd_link_relocatable (info));
*errmsg = NULL;
/* Get a copy of the native relocations. */
internal_relocs = (_bfd_elf_link_read_relocs
- (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ (abfd, datasec, NULL, (Elf_Internal_Rela *) NULL,
info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
};
\f
-#define TARGET_LITTLE_SYM bfd_elf32_bfin_vec
+#define TARGET_LITTLE_SYM bfin_elf32_vec
#define TARGET_LITTLE_NAME "elf32-bfin"
#define ELF_ARCH bfd_arch_bfin
#define ELF_TARGET_ID BFIN_ELF_DATA
#define elf_backend_final_write_processing \
elf32_bfin_final_write_processing
#define elf_backend_reloc_type_class elf32_bfin_reloc_type_class
+#define elf_backend_stack_align 8
#define elf_backend_can_gc_sections 1
#define elf_backend_special_sections elf32_bfin_special_sections
#define elf_backend_can_refcount 1
#include "elf32-target.h"
#undef TARGET_LITTLE_SYM
-#define TARGET_LITTLE_SYM bfd_elf32_bfinfdpic_vec
+#define TARGET_LITTLE_SYM bfin_elf32_fdpic_vec
#undef TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME "elf32-bfinfdpic"
#undef elf32_bed
#undef elf_backend_always_size_sections
#define elf_backend_always_size_sections \
elf32_bfinfdpic_always_size_sections
-#undef elf_backend_modify_program_headers
-#define elf_backend_modify_program_headers \
- elf32_bfinfdpic_modify_program_headers
-#undef bfd_elf32_bfd_copy_private_bfd_data
-#define bfd_elf32_bfd_copy_private_bfd_data \
- elf32_bfinfdpic_copy_private_bfd_data
#undef elf_backend_create_dynamic_sections
#define elf_backend_create_dynamic_sections \