/* M32R-specific support for 32-bit ELF.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1996-2016 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
/* This reloc does nothing. */
HOWTO (R_M32R_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_M32R_NONE", /* name */
FALSE, /* partial_inplace */
unsigned int r_type;
r_type = ELF32_R_TYPE (dst->r_info);
- BFD_ASSERT (ELF32_R_TYPE(dst->r_info) <= (unsigned int) R_M32R_GNU_VTENTRY);
+ if (r_type > (unsigned int) R_M32R_GNU_VTENTRY)
+ {
+ _bfd_error_handler (_("%B: invalid M32R reloc number: %d"), abfd, r_type);
+ r_type = 0;
+ }
cache_ptr->howto = &m32r_elf_howto_table[r_type];
}
asection **secp,
bfd_vma *valp)
{
- if (! info->relocatable
+ if (! bfd_link_relocatable (info)
&& (*namep)[0] == '_' && (*namep)[1] == 'S'
&& strcmp (*namep, "_SDA_BASE_") == 0
&& is_elf_hash_table (info->hash))
flags);
if (s == NULL)
return FALSE;
- bfd_set_section_alignment (abfd, s, 2);
+ if (! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
}
bh = bfd_link_hash_lookup (info->hash, "_SDA_BASE_",
struct elf_m32r_link_hash_table *ret;
bfd_size_type amt = sizeof (struct elf_m32r_link_hash_table);
- ret = bfd_malloc (amt);
+ ret = bfd_zmalloc (amt);
if (ret == NULL)
return NULL;
return NULL;
}
- ret->sgot = NULL;
- ret->sgotplt = NULL;
- ret->srelgot = NULL;
- ret->splt = NULL;
- ret->srelplt = NULL;
- ret->sdynbss = NULL;
- ret->srelbss = NULL;
- ret->sym_cache.abfd = NULL;
-
return &ret->root.root;
}
if (htab == NULL)
return FALSE;
- htab->sgot = bfd_get_section_by_name (dynobj, ".got");
- htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
- htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ htab->sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got");
if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
abort ();
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);
htab->splt = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
h->type = STT_OBJECT;
htab->root.hplt = h;
- if (info->shared
+ if (bfd_link_pic (info)
&& ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
- s = bfd_make_section_with_flags (abfd,
- bed->default_use_rela_p ? ".rela.plt" : ".rel.plt",
- flags | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd,
+ bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt",
+ flags | SEC_READONLY);
htab->srelplt = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
&& ! create_got_section (abfd, info))
return FALSE;
- {
- const char *secname;
- char *relname;
- flagword secflags;
- asection *sec;
-
- for (sec = abfd->sections; sec; sec = sec->next)
- {
- secflags = bfd_get_section_flags (abfd, sec);
- if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
- || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
- continue;
- secname = bfd_get_section_name (abfd, sec);
- relname = bfd_malloc ((bfd_size_type) strlen (secname) + 6);
- strcpy (relname, ".rela");
- strcat (relname, secname);
- if (bfd_get_section_by_name (abfd, secname))
- continue;
- s = bfd_make_section_with_flags (abfd, relname,
- flags | SEC_READONLY);
- if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, ptralign))
- return FALSE;
- }
- }
-
if (bed->want_dynbss)
{
/* The .dynbss section is a place to put symbols which are defined
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);
htab->sdynbss = s;
if (s == NULL)
return FALSE;
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)
+ if (! bfd_link_pic (info))
{
- s = bfd_make_section_with_flags (abfd,
- (bed->default_use_rela_p
- ? ".rela.bss" : ".rel.bss"),
- flags | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
htab->srelbss = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
if (h->type == STT_FUNC
|| h->needs_plt)
{
- if (! info->shared
+ if (! bfd_link_pic (info)
&& !h->def_dynamic
&& !h->ref_dynamic
&& h->root.type != bfd_link_hash_undefweak
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
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
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;
h->needs_copy = 1;
}
- return _bfd_elf_adjust_dynamic_copy (h, s);
+ return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
- if (h->root.type == bfd_link_hash_warning)
- /* When warning symbols are created, they **replace** the "real"
- entry in the hash table, thus we never get to see the real
- symbol in a hash traversal. So look at it now. */
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
info = (struct bfd_link_info *) inf;
htab = m32r_elf_hash_table (info);
if (htab == NULL)
return FALSE;
}
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
{
asection *s = htab->splt;
location in the .plt. This is required to make function
pointers compare as equal between the normal executable and
the shared library. */
- if (! info->shared
+ if (! bfd_link_pic (info)
&& !h->def_regular)
{
h->root.u.def.section = s;
h->got.offset = s->size;
s->size += 4;
dyn = htab->root.dynamic_sections_created;
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h))
htab->srelgot->size += sizeof (Elf32_External_Rela);
}
else
space for pc-relative relocs that have become local due to symbol
visibility changes. */
- if (info->shared)
+ if (bfd_link_pic (info))
{
if (h->def_regular
&& (h->forced_local
struct elf_m32r_link_hash_entry *eh;
struct elf_m32r_dyn_relocs *p;
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
eh = (struct elf_m32r_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
if (htab->root.dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (info->executable)
+ if (bfd_link_executable (info) && !info->nointerp)
{
- s = bfd_get_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;
/* Set up .got offsets for local syms, and space for local dynamic
relocs. */
- for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
{
bfd_signed_vma *local_got;
bfd_signed_vma *end_local_got;
{
*local_got = s->size;
s->size += 4;
- if (info->shared)
+ if (bfd_link_pic (info))
srel->size += sizeof (Elf32_External_Rela);
}
else
#define add_dynamic_entry(TAG, VAL) \
_bfd_elf_add_dynamic_entry (info, TAG, VAL)
- if (info->executable)
+ if (bfd_link_executable (info))
{
if (! add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
relocation = 0;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ h = ((struct elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &h->root));
+
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;
|| r_type == R_M32R_GOT16_HI_SLO
|| r_type == R_M32R_GOT16_LO)
&& WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
- info->shared, h)
- && (! info->shared
+ bfd_link_pic (info),
+ h)
+ && (! bfd_link_pic (info)
|| (! info->symbolic && h->dynindx != -1)
|| !h->def_regular))
- || (info->shared
+ || (bfd_link_pic (info)
&& ((! info->symbolic && h->dynindx != -1)
|| !h->def_regular)
&& (((r_type == R_M32R_16_RELA
relocation = (h->root.u.def.value
+ sec->output_section->vma
+ sec->output_offset);
- else if (!info->relocatable)
+ else if (!bfd_link_relocatable (info)
+ && (_bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ != (bfd_vma) -1))
{
(*_bfd_error_handler)
(_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
;
- else if (!info->relocatable)
+ else if (!bfd_link_relocatable (info))
{
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
}
}
- 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 && !use_rel)
+ if (bfd_link_relocatable (info) && !use_rel)
{
/* This is a relocatable link. We don't have to change
anything, unless the reloc is against a section symbol,
continue;
}
- if (info->relocatable && use_rel)
+ if (bfd_link_relocatable (info) && use_rel)
{
/* This is a relocatable link. We don't have to change
anything, unless the reloc is against a section symbol,
BFD_ASSERT (off != (bfd_vma) -1);
dyn = htab->root.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 *srelgot;
Elf_Internal_Rela outrel;
/* We need to generate a R_M32R_RELATIVE reloc
for the dynamic linker. */
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = bfd_get_linker_section (dynobj,
+ ".rela.got");
BFD_ASSERT (srelgot != NULL);
outrel.r_offset = (sgot->output_section->vma
case R_M32R_26_PCREL_RELA:
case R_M32R_HI16_ULO_RELA:
case R_M32R_LO16_RELA:
- if (info->shared
- && r_symndx != 0
+ if (bfd_link_pic (info)
+ && r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0
&& (( r_type != R_M32R_10_PCREL_RELA
&& r_type != R_M32R_18_PCREL_RELA
const char *name;
BFD_ASSERT (sec != NULL);
- name = bfd_get_section_name (abfd, sec);
+ name = bfd_get_section_name (sec->owner, sec);
if ( strcmp (name, ".sdata") == 0
|| strcmp (name, ".sbss") == 0
Elf_Internal_Sym *sym)
{
struct elf_m32r_link_hash_table *htab;
- bfd *dynobj;
bfd_byte *loc;
#ifdef DEBUG_PIC
if (htab == NULL)
return FALSE;
- dynobj = htab->root.dynobj;
-
if (h->plt.offset != (bfd_vma) -1)
{
asection *splt;
got_offset = (plt_index + 3) * 4;
/* Fill in the entry in the procedure linkage table. */
- if (! info->shared)
+ if (! bfd_link_pic (info))
{
bfd_put_32 (output_bfd,
(PLT_ENTRY_WORD0b
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->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 (htab->root.dynobj, ".rela.bss");
BFD_ASSERT (s != NULL);
rela.r_offset = (h->root.u.def.value
}
/* Mark some specially defined symbols as absolute. */
- if (strcmp (h->root.root.string, "_DYNAMIC") == 0
- || h == htab->root.hgot)
+ if (h == htab->root.hdynamic || h == htab->root.hgot)
sym->st_shndx = SHN_ABS;
return TRUE;
dynobj = htab->root.dynobj;
sgot = htab->sgotplt;
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (htab->root.dynamic_sections_created)
{
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
- const char *name;
asection *s;
bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
break;
case DT_PLTGOT:
- name = ".got";
s = htab->sgot->output_section;
goto get_vma;
case DT_JMPREL:
- name = ".rela.plt";
s = htab->srelplt->output_section;
get_vma:
BFD_ASSERT (s != NULL);
splt = htab->splt;
if (splt && splt->size > 0)
{
- if (info->shared)
+ if (bfd_link_pic (info))
{
bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD0, splt->contents);
bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD1, splt->contents + 4);
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
elf_section_data (sec)->local_dynrel = NULL;
struct elf_m32r_dyn_relocs **pp;
struct elf_m32r_dyn_relocs *p;
- if (!info->shared && h->plt.refcount > 0)
+ if (!bfd_link_pic (info) && h->plt.refcount > 0)
h->plt.refcount -= 1;
eh = (struct elf_m32r_link_hash_entry *) h;
const Elf_Internal_Rela *rel_end;
struct elf_m32r_link_hash_table *htab;
bfd *dynobj;
- bfd_vma *local_got_offsets;
- asection *sgot, *srelgot, *sreloc;
+ asection *sreloc;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
- sgot = srelgot = sreloc = NULL;
-
+ sreloc = NULL;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
return FALSE;
dynobj = htab->root.dynobj;
- local_got_offsets = elf_local_got_offsets (abfd);
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
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;
}
/* Some relocs require a global offset table. */
case R_M32R_18_PCREL_RELA:
case R_M32R_26_PCREL_RELA:
- if (h != NULL && !info->shared)
+ if (h != NULL && !bfd_link_pic (info))
{
h->non_got_ref = 1;
h->plt.refcount += 1;
may need to keep relocations for symbols satisfied by a
dynamic library if we manage to avoid copy relocs for the
symbol. */
- if ((info->shared
+ if ((bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& (( r_type != R_M32R_26_PCREL_RELA
&& r_type != R_M32R_18_PCREL_RELA
&& (! info->symbolic
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
- || (!info->shared
+ || (!bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& h != NULL
&& (h->root.type == bfd_link_hash_defweak
{ NULL, 0, 0, 0, 0 }
};
-static bfd_boolean
-m32r_elf_fake_sections (bfd *abfd,
- Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
- asection *sec)
-{
- const char *name;
-
- name = bfd_get_section_name (abfd, sec);
-
- /* The generic elf_fake_sections will set up REL_HDR using the
- default kind of relocations. But, we may actually need both
- kinds of relocations, so we set up the second header here.
-
- This is not necessary for the O32 ABI since that only uses Elf32_Rel
- relocations (cf. System V ABI, MIPS RISC Processor Supplement,
- 3rd Edition, p. 4-17). It breaks the IRIX 5/6 32-bit ld, since one
- of the resulting empty .rela.<section> sections starts with
- sh_offset == object size, and ld doesn't allow that. While the check
- is arguably bogus for empty or SHT_NOBITS sections, it can easily be
- avoided by not emitting those useless sections in the first place. */
- if ((sec->flags & SEC_RELOC) != 0)
- {
- struct bfd_elf_section_data *esd;
- bfd_size_type amt = sizeof (Elf_Internal_Shdr);
-
- esd = elf_section_data (sec);
- BFD_ASSERT (esd->rel_hdr2 == NULL);
- esd->rel_hdr2 = bfd_zalloc (abfd, amt);
- if (!esd->rel_hdr2)
- return FALSE;
- _bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
- !sec->use_rela_p);
- }
-
- return TRUE;
-}
-
static enum elf_reloc_type_class
-m32r_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+m32r_elf_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))
{
}
\f
#define ELF_ARCH bfd_arch_m32r
+#define ELF_TARGET_ID M32R_ELF_DATA
#define ELF_MACHINE_CODE EM_M32R
#define ELF_MACHINE_ALT1 EM_CYGNUS_M32R
#define ELF_MAXPAGESIZE 0x1 /* Explicitly requested by Mitsubishi. */
-#define TARGET_BIG_SYM bfd_elf32_m32r_vec
+#define TARGET_BIG_SYM m32r_elf32_vec
#define TARGET_BIG_NAME "elf32-m32r"
-#define TARGET_LITTLE_SYM bfd_elf32_m32rle_vec
+#define TARGET_LITTLE_SYM m32r_elf32_le_vec
#define TARGET_LITTLE_NAME "elf32-m32rle"
#define elf_info_to_howto m32r_info_to_howto
#else
#define elf_backend_default_use_rela_p 1
#define elf_backend_may_use_rela_p 1
-#define elf_backend_fake_sections m32r_elf_fake_sections
#endif
#define elf_backend_object_p m32r_elf_object_p
#define ELF_MAXPAGESIZE 0x1000
#undef TARGET_BIG_SYM
-#define TARGET_BIG_SYM bfd_elf32_m32rlin_vec
+#define TARGET_BIG_SYM m32r_elf32_linux_vec
#undef TARGET_BIG_NAME
#define TARGET_BIG_NAME "elf32-m32r-linux"
#undef TARGET_LITTLE_SYM
-#define TARGET_LITTLE_SYM bfd_elf32_m32rlelin_vec
+#define TARGET_LITTLE_SYM m32r_elf32_linux_le_vec
#undef TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME "elf32-m32rle-linux"
#undef elf32_bed