/* Ubicom IP2xxx specific support for 32-bit ELF
- Copyright 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2012
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/ip2k.h"
return NULL;
}
+static reloc_howto_type *
+ip2k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (ip2k_elf_howto_table) / sizeof (ip2k_elf_howto_table[0]);
+ i++)
+ if (ip2k_elf_howto_table[i].name != NULL
+ && strcasecmp (ip2k_elf_howto_table[i].name, r_name) == 0)
+ return &ip2k_elf_howto_table[i];
+
+ return NULL;
+}
+
static void
ip2k_get_mem (bfd *abfd ATTRIBUTE_UNUSED,
bfd_byte *addr,
bfd_byte *contents)
{
bfd_byte code[4];
- int index = 0;
+ int table_index = 0;
/* Check current page-jmp. */
if (addr + 4 > sec->size)
ip2k_get_mem (abfd, contents + addr - 4, 4, code);
if ((IS_ADD_W_WREG_OPCODE (code + 0))
&& (IS_ADD_PCL_W_OPCODE (code + 2)))
- return index;
+ return table_index;
if ((! IS_PAGE_OPCODE (code + 0))
|| (! IS_JMP_OPCODE (code + 2)))
return -1;
- index++;
+ table_index++;
addr -= 4;
}
}
bfd_byte *contents)
{
bfd_byte code[16];
- int index = 0;
+ int table_index = 0;
/* Check current page-jmp. */
if (addr + 4 > sec->size)
&& (IS_INC_1SP_OPCODE (code + 10))
&& (IS_PAGE_OPCODE (code + 12))
&& (IS_JMP_OPCODE (code + 14)))
- return index;
+ return table_index;
if ((IS_ADD_W_WREG_OPCODE (code + 2))
&& (IS_SNC_OPCODE (code + 4))
&& (IS_SNC_OPCODE (code + 10))
&& (IS_INC_1SP_OPCODE (code + 12))
&& (IS_JMP_OPCODE (code + 14)))
- return index;
+ return table_index;
if ((! IS_PAGE_OPCODE (code + 0))
|| (! IS_JMP_OPCODE (code + 2)))
return -1;
- index++;
+ table_index++;
addr -= 4;
}
}
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Sym *isymbuf, *isym, *isymend;
unsigned int shndx;
- bfd_byte *contents;
Elf_Internal_Rela *irel, *irelend, *irelbase;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
- contents = elf_section_data (sec)->this_hdr.contents;
-
irelbase = elf_section_data (sec)->relocs;
irelend = irelbase + sec->reloc_count;
if (sym_sec == sec)
{
const char *name;
- unsigned long strx;
- unsigned char type, other;
- unsigned short desc;
+ unsigned char type;
bfd_vma value;
bfd_vma baseaddr = BASEADDR (sec);
bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
stabp = stabcontents + irel->r_offset - 8;
/* Go pullout the stab entry. */
- strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
- other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
- desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
value = bfd_h_get_32 (abfd, stabp + VALOFF);
name = bfd_get_stab_name (type);
for (;stabp < stabend; stabp += STABSIZE)
{
/* Go pullout the stab entry. */
- strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
- other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
- desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
value = bfd_h_get_32 (abfd, stabp + VALOFF);
name = bfd_get_stab_name (type);
static bfd_boolean new_pass = FALSE;
static bfd_boolean changed = FALSE;
struct misc misc;
- asection *stab;
/* Assume nothing changes. */
*again = FALSE;
if (internal_relocs == NULL)
goto error_return;
- /* Make sure the stac.rela stuff gets read in. */
- stab = bfd_get_section_by_name (abfd, ".stab");
-
- if (stab)
- {
- /* So stab does exits. */
- Elf_Internal_Rela * irelbase;
-
- irelbase = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL,
- link_info->keep_memory);
- }
-
/* Get section contents cached copy if it exists. */
if (contents == NULL)
{
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
- if (info->relocatable)
- return TRUE;
-
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
relend = relocs + input_section->reloc_count;
const char * name = NULL;
int r_type;
- /* This is a final link. */
r_type = ELF32_R_TYPE (rel->r_info);
r_symndx = ELF32_R_SYM (rel->r_info);
- howto = ip2k_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ howto = ip2k_elf_howto_table + r_type;
h = NULL;
sym = NULL;
sec = NULL;
name = h->root.root.string;
}
+ 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;
+
/* Finally, the sole IP2K-specific part. */
r = ip2k_final_link_relocate (howto, input_bfd, input_section,
contents, rel, relocation);
return TRUE;
}
-static asection *
-ip2k_elf_gc_mark_hook (asection *sec,
- struct bfd_link_info *info ATTRIBUTE_UNUSED,
- Elf_Internal_Rela *rel,
- struct elf_link_hash_entry *h,
- Elf_Internal_Sym *sym)
-{
- if (h != NULL)
- {
- switch (ELF32_R_TYPE (rel->r_info))
- {
- 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
- {
- if (!(elf_bad_symtab (sec->owner)
- && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
- && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
- && sym->st_shndx != SHN_COMMON))
- return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
- }
- return NULL;
-}
-
-static bfd_boolean
-ip2k_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info ATTRIBUTE_UNUSED,
- asection *sec ATTRIBUTE_UNUSED,
- const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
-{
- /* We don't use got and plt entries for ip2k. */
- return TRUE;
-}
-
#define TARGET_BIG_SYM bfd_elf32_ip2k_vec
#define TARGET_BIG_NAME "elf32-ip2k"
#define elf_backend_can_gc_sections 1
#define elf_backend_rela_normal 1
-#define elf_backend_gc_mark_hook ip2k_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook ip2k_elf_gc_sweep_hook
#define elf_backend_relocate_section ip2k_elf_relocate_section
#define elf_symbol_leading_char '_'
#define bfd_elf32_bfd_reloc_type_lookup ip2k_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup ip2k_reloc_name_lookup
#define bfd_elf32_bfd_relax_section ip2k_elf_relax_section
#include "elf32-target.h"