/* CRIS-specific support for 32-bit ELF.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
Contributed by Axis Communications AB.
Written by Hans-Peter Nilsson, based on elf32-fr30.c
PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, bfd_vma));
-static bfd_boolean cris_elf_gc_sweep_hook
- PARAMS ((bfd *, struct bfd_link_info *, asection *,
- const Elf_Internal_Rela *));
-
-static asection * cris_elf_gc_mark_hook
- PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
- struct elf_link_hash_entry *, Elf_Internal_Sym *));
-
static bfd_boolean cris_elf_object_p PARAMS ((bfd *));
static void cris_elf_final_write_processing PARAMS ((bfd *, bfd_boolean));
if (ret == (struct elf_cris_link_hash_table *) NULL)
return NULL;
- if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
- elf_cris_link_hash_newfunc))
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf_cris_link_hash_newfunc,
+ sizeof (struct elf_cris_link_hash_entry)))
{
free (ret);
return NULL;
if (name == NULL)
return FALSE;
- BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ BFD_ASSERT (CONST_STRNEQ (name, ".rela")
&& strcmp (bfd_get_section_name (input_bfd,
input_section),
name + 5) == 0);
}
else
{
+ outrel.r_addend = relocation + rel->r_addend;
+
if (r_type == R_CRIS_32)
{
relocate = TRUE;
outrel.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
- outrel.r_addend = relocation + rel->r_addend;
}
else
{
{
asection *osec;
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
osec = sec->output_section;
indx = elf_section_data (osec)->dynindx;
- BFD_ASSERT (indx > 0);
+ if (indx == 0)
+ {
+ struct elf_cris_link_hash_table *htab;
+ htab = elf_cris_hash_table (info);
+ osec = htab->root.text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
}
outrel.r_info = ELF32_R_INFO (indx, r_type);
- outrel.r_addend = relocation + rel->r_addend;
}
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
if (strcmp (h->root.root.string, "_DYNAMIC") == 0
- || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ || h == elf_hash_table (info)->hgot)
sym->st_shndx = SHN_ABS;
return TRUE;
relocation. */
static asection *
-cris_elf_gc_mark_hook (sec, info, rel, h, sym)
- asection *sec;
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
- Elf_Internal_Rela *rel;
- struct elf_link_hash_entry *h;
- Elf_Internal_Sym *sym;
+cris_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
{
if (h != NULL)
- {
- switch (ELF32_R_TYPE (rel->r_info))
- {
- case R_CRIS_GNU_VTINHERIT:
- case R_CRIS_GNU_VTENTRY:
- break;
-
- default:
- switch (h->root.type)
- {
- case bfd_link_hash_defined:
- case bfd_link_hash_defweak:
- return h->root.u.def.section;
-
- case bfd_link_hash_common:
- return h->root.u.c.p->section;
-
- default:
- break;
- }
- }
- }
- else
- return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_CRIS_GNU_VTINHERIT:
+ case R_CRIS_GNU_VTENTRY:
+ return NULL;
+ }
- return NULL;
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}
/* Update the got entry reference counts for the section being removed. */
static bfd_boolean
-cris_elf_gc_sweep_hook (abfd, info, sec, relocs)
- bfd *abfd ATTRIBUTE_UNUSED;
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
- asection *sec ATTRIBUTE_UNUSED;
- const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
+cris_elf_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
{
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
if (name == NULL)
return FALSE;
- BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ BFD_ASSERT (CONST_STRNEQ (name, ".rela")
&& strcmp (bfd_get_section_name (abfd, sec),
name + 5) == 0);
/* Remember whether there is a PLT. */
plt = s->size != 0;
}
- else if (strncmp (name, ".rela", 5) == 0)
+ else if (CONST_STRNEQ (name, ".rela"))
{
if (s->size != 0)
{
s->reloc_count = 0;
}
}
- else if (strncmp (name, ".got", 4) != 0
+ else if (! CONST_STRNEQ (name, ".got")
&& strcmp (name, ".dynbss") != 0)
{
/* It's not one of our sections, so don't allocate space. */
elf_cris_adjust_dynamic_symbol
#define elf_backend_size_dynamic_sections \
elf_cris_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
#define elf_backend_finish_dynamic_symbol \
elf_cris_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \