/* Renesas / SuperH SH 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.
+ 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Free Software Foundation, Inc.
Contributed by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
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 = sh_elf_hash_table (info);
if (htab == NULL)
struct elf_sh_link_hash_entry *eh;
struct elf_sh_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_sh_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
static unsigned
sh_elf_osec_to_segment (bfd *output_bfd, asection *osec)
{
- Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section (output_bfd,
- osec);
+ Elf_Internal_Phdr *p = NULL;
+
+ if (output_bfd->xvec->flavour == bfd_target_elf_flavour)
+ p = _bfd_elf_find_segment_containing_section (output_bfd, osec);
/* FIXME: Nothing ever says what this index is relative to. The kernel
supplies data in terms of the number of load segments but this is
{
unsigned seg = sh_elf_osec_to_segment (output_bfd, osec);
- return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
+ return (seg != (unsigned) -1
+ && ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W));
}
/* Generate the initial contents of a local function descriptor, along
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Rela *rel, *relend;
- bfd *dynobj;
+ bfd *dynobj = NULL;
bfd_vma *local_got_offsets;
- asection *sgot;
- asection *sgotplt;
- asection *splt;
- asection *sreloc;
- asection *srelgot;
+ asection *sgot = NULL;
+ asection *sgotplt = NULL;
+ asection *splt = NULL;
+ asection *sreloc = NULL;
+ asection *srelgot = NULL;
bfd_boolean is_vxworks_tls;
unsigned isec_segment, got_segment, plt_segment, check_segment[2];
+ bfd_boolean fdpic_p = FALSE;
BFD_ASSERT (is_sh_elf (input_bfd));
htab = sh_elf_hash_table (info);
- if (htab == NULL)
- return FALSE;
+ if (htab != NULL)
+ {
+ dynobj = htab->root.dynobj;
+ sgot = htab->sgot;
+ sgotplt = htab->sgotplt;
+ splt = htab->splt;
+ fdpic_p = htab->fdpic_p;
+ }
symtab_hdr = &elf_symtab_hdr (input_bfd);
sym_hashes = elf_sym_hashes (input_bfd);
- dynobj = htab->root.dynobj;
local_got_offsets = elf_local_got_offsets (input_bfd);
isec_segment = sh_elf_osec_to_segment (output_bfd,
input_section->output_section);
- if (htab->fdpic_p && htab->sgot)
+ if (fdpic_p && sgot)
got_segment = sh_elf_osec_to_segment (output_bfd,
- htab->sgot->output_section);
+ sgot->output_section);
else
got_segment = -1;
- if (htab->fdpic_p && htab->splt)
+ if (fdpic_p && splt)
plt_segment = sh_elf_osec_to_segment (output_bfd,
- htab->splt->output_section);
+ splt->output_section);
else
plt_segment = -1;
- sgot = htab->sgot;
- sgotplt = htab->sgotplt;
- splt = htab->splt;
- sreloc = NULL;
- srelgot = NULL;
/* We have to handle relocations in vxworks .tls_vars sections
specially, because the dynamic loader is 'weird'. */
- is_vxworks_tls = (htab->vxworks_p && info->shared
+ is_vxworks_tls = (htab && htab->vxworks_p && info->shared
&& !strcmp (input_section->output_section->name,
".tls_vars"));
{
bfd_boolean dyn;
- dyn = htab->root.dynamic_sections_created;
+ dyn = htab ? htab->root.dynamic_sections_created : FALSE;
sec = h->root.u.def.section;
/* In these cases, we don't need the relocation value.
We check specially because in some obscure cases
STT_DATALABEL on the way to it. */
| ((h->other & STO_SH5_ISA32) != 0
&& ! seen_stt_datalabel));
- else if (!info->relocatable)
+ else if (!info->relocatable
+ && (_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'"),
}
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;
- }
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, relend, howto, contents);
if (info->relocatable)
continue;
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
- && r_symndx != 0
+ && r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0
&& !is_vxworks_tls
&& (r_type == R_SH_DIR32
outrel.r_addend = addend;
}
#endif
- else if (htab->fdpic_p
+ else if (fdpic_p
&& (h == NULL
|| ((info->symbolic || h->dynindx == -1)
&& h->def_regular)))
if (! relocate)
continue;
}
- else if (htab->fdpic_p && !info->shared
+ else if (fdpic_p && !info->shared
&& r_type == R_SH_DIR32
&& (input_section->flags & SEC_ALLOC) != 0)
{
bfd_vma offset;
+ BFD_ASSERT (htab);
+
if (sh_elf_osec_readonly_p (output_bfd,
input_section->output_section))
{
/* Relocation is to the entry for this symbol in the global
offset table extension for the procedure linkage table. */
+ BFD_ASSERT (htab);
BFD_ASSERT (sgotplt != NULL);
relocation = (sgotplt->output_offset
+ (get_plt_index (htab->plt_info, h->plt.offset)
/* Relocation is to the entry for this symbol in the global
offset table. */
+ BFD_ASSERT (htab);
BFD_ASSERT (sgot != NULL);
check_segment[0] = check_segment[1] = -1;
/* If we initialize the GOT entry here with a valid
symbol address, also add a fixup. */
- if (htab->fdpic_p && !info->shared
+ if (fdpic_p && !info->shared
&& sh_elf_hash_entry (h)->got_type == GOT_NORMAL
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
+ off);
- if (htab->fdpic_p)
+ if (fdpic_p)
{
int dynindx
= elf_section_data (sec->output_section)->dynindx;
loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
- else if (htab->fdpic_p
+ else if (fdpic_p
&& (sh_elf_local_got_type (input_bfd) [r_symndx]
== GOT_NORMAL))
sh_elf_add_rofixup (output_bfd, htab->srofixup,
we place at the start of the .got.plt section. This is the same
as the start of the output .got section, unless there are function
descriptors in front of it. */
+ BFD_ASSERT (htab);
BFD_ASSERT (sgotplt != NULL);
check_segment[0] = got_segment;
relocation -= sgotplt->output_section->vma + sgotplt->output_offset
bfd_vma reloc_offset;
int reloc_type = R_SH_FUNCDESC;
+ BFD_ASSERT (htab);
+
check_segment[0] = check_segment[1] = -1;
/* FIXME: See what FRV does for global symbols in the
}
else
{
- reloc_section = htab->sgot;
+ reloc_section = sgot;
if (h != NULL)
reloc_offset = h->got.offset;
executable and --export-dynamic. If such symbols get
ld.so-allocated descriptors we can not use R_SH_GOTOFFFUNCDESC
for them. */
+ BFD_ASSERT (htab);
check_segment[0] = check_segment[1] = -1;
relocation = 0;
relocation = htab->sfuncdesc->output_offset + (offset & ~1);
}
- relocation -= htab->root.hgot->root.u.def.value
- + htab->sgotplt->output_offset;
+ relocation -= (htab->root.hgot->root.u.def.value
+ + sgotplt->output_offset);
#ifdef GOT_BIAS
relocation -= GOT_BIAS;
#endif
case R_SH_TLS_GD_32:
case R_SH_TLS_IE_32:
+ BFD_ASSERT (htab);
check_segment[0] = check_segment[1] = -1;
r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
got_type = GOT_UNKNOWN;
goto final_link_relocate;
case R_SH_TLS_LD_32:
+ BFD_ASSERT (htab);
check_segment[0] = check_segment[1] = -1;
if (! info->shared)
{
check_segment[0] = check_segment[1] = -1;
- if (! info->shared)
+ if (! info->shared || info->pie)
{
relocation = tpoff (info, relocation);
addend = rel->r_addend;
}
relocation_done:
- if (htab->fdpic_p && check_segment[0] != (unsigned) -1
+ if (fdpic_p && check_segment[0] != (unsigned) -1
&& check_segment[0] != check_segment[1])
{
/* We don't want duplicate errors for undefined symbols. */
struct elf_sh_link_hash_table *htab;
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
- bfd_vma *local_got_offsets;
- asection *sgot;
- asection *srelgot;
asection *sreloc;
unsigned int r_type;
int got_type, old_got_type;
- sgot = NULL;
- srelgot = NULL;
sreloc = NULL;
if (info->relocatable)
if (htab == NULL)
return FALSE;
- local_got_offsets = elf_local_got_offsets (abfd);
-
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
break;
case R_SH_TLS_LE_32:
- if (info->shared)
+ if (info->shared && !info->pie)
{
(*_bfd_error_handler)
(_("%B: TLS local exec code cannot be linked into shared objects"),
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
- elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
+ elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24);
/* pr_reg */
offset = 72;
#endif
#define ELF_ARCH bfd_arch_sh
+#define ELF_TARGET_ID SH_ELF_DATA
#define ELF_MACHINE_CODE EM_SH
#ifdef __QNXTARGET__
#define ELF_MAXPAGESIZE 0x1000