/* 32-bit ELF support for S+core.
- Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2006-2015 Free Software Foundation, Inc.
Contributed by
Brain.lin (brain.lin@sunplusct.com)
Mei Ligang (ligang@sunnorth.com.cn)
int score3 = 0;
int score7 = 1;
-/* Score ELF linker hash table. */
-struct score_elf_link_hash_table
-{
- /* The main hash table. */
- struct elf_link_hash_table root;
-};
-
/* The SCORE ELF linker needs additional information for each symbol in
the global hash table. */
struct score_elf_link_hash_entry
/* Traverse a score ELF linker hash table. */
#define score_elf_link_hash_traverse(table, func, info) \
(elf_link_hash_traverse \
- (&(table)->root, \
+ ((table), \
(bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
(info)))
-/* Get the SCORE elf linker hash table from a link_info structure. */
-#define score_elf_hash_table(info) \
- ((struct score_elf_link_hash_table *) ((info)->hash))
-
/* This structure is used to hold .got entries while estimating got sizes. */
struct score_got_entry
{
{
struct score_elf_hash_sort_data *hsd = data;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
-
/* Symbols without dynamic symbol table entries aren't interesting at all. */
if (h->root.dynindx == -1)
return TRUE;
static asection *
score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
{
- asection *sgot = bfd_get_section_by_name (abfd, ".got");
+ asection *sgot = bfd_get_linker_section (abfd, ".got");
if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
return NULL;
too large offsets. */
- (g->next ? g->assigned_gotno : 0);
hsd.max_non_got_dynindx = max_local;
- score_elf_link_hash_traverse (((struct score_elf_link_hash_table *)
- elf_hash_table (info)),
- score_elf_sort_hash_table_f,
- &hsd);
+ score_elf_link_hash_traverse (elf_hash_table (info),
+ score_elf_sort_hash_table_f,
+ &hsd);
/* There should have been enough room in the symbol table to
accommodate both the GOT and non-GOT symbols. */
}
/* Create an entry in an score ELF linker hash table. */
+
static struct bfd_hash_entry *
score_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
struct bfd_hash_table *table,
const char *string)
{
- struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *)entry;
+ struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *) entry;
/* Allocate the structure if it has not already been allocated by a subclass. */
if (ret == NULL)
ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry));
if (ret == NULL)
- return (struct bfd_hash_entry *)ret;
+ return (struct bfd_hash_entry *) ret;
/* Call the allocation method of the superclass. */
ret = ((struct score_elf_link_hash_entry *)
- _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *)ret, table, string));
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
if (ret != NULL)
{
ret->forced_local = FALSE;
}
- return (struct bfd_hash_entry *)ret;
+ return (struct bfd_hash_entry *) ret;
}
/* Returns the first relocation of type r_type found, beginning with
static const char dname[] = ".rel.dyn";
asection *sreloc;
- sreloc = bfd_get_section_by_name (dynobj, dname);
+ sreloc = bfd_get_linker_section (dynobj, dname);
if (sreloc == NULL && create_p)
{
- sreloc = bfd_make_section_with_flags (dynobj, dname,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
+ sreloc = bfd_make_section_anyway_with_flags (dynobj, dname,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
if (sreloc == NULL
|| ! bfd_set_section_alignment (dynobj, sreloc,
SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
/* We have to use an alignment of 2**4 here because this is hardcoded
in the function stub generation and in the linker script. */
- s = bfd_make_section_with_flags (abfd, ".got", flags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, 4))
return FALSE;
{
asection *sgot;
bfd_vma gp;
- struct score_got_info *g;
- g = score_elf_got_info (dynobj, &sgot);
+ score_elf_got_info (dynobj, &sgot);
gp = _bfd_get_gp_value (output_bfd);
return sgot->output_section->vma + sgot->output_offset + got_index - gp;
bfd_vma gp = MINUS_ONE;
/* The place (section offset or address) of the storage unit being relocated. */
bfd_vma rel_addr;
- /* The value of GP used to create the relocatable object. */
- bfd_vma gp0 = MINUS_ONE;
/* The offset into the global offset table at which the address of the relocation entry
symbol, adjusted by the addend, resides during execution. */
bfd_vma g = MINUS_ONE;
{
g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
(struct elf_link_hash_entry *) h);
- if ((! elf_hash_table(info)->dynamic_sections_created
+ if ((! elf_hash_table (info)->dynamic_sections_created
|| (info->shared
&& (info->symbolic || h->root.dynindx == -1)
&& h->root.def_regular)))
case R_SCORE_HI16:
case R_SCORE_LO16:
case R_SCORE_GPREL32:
- gp0 = _bfd_get_gp_value (input_bfd);
gp = _bfd_get_gp_value (output_bfd);
break;
&& h != NULL
&& h->root.def_dynamic
&& !h->root.def_regular))
- && r_symndx != 0
+ && r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0)
{
/* If we're creating a shared library, or this relocation is against a symbol
input_section))
return bfd_reloc_undefined;
}
- else if (r_symndx == 0)
- /* r_symndx will be zero only for relocs against symbols
+ else if (r_symndx == STN_UNDEF)
+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
from removed linkonce sections, or sections discarded by
a linker script. */
value = 0;
asection **local_sections)
{
Elf_Internal_Shdr *symtab_hdr;
- struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
const char *name;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
- sym_hashes = elf_sym_hashes (input_bfd);
rel = relocs;
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
/* For global symbols we look up the symbol in the hash-table. */
h = ((struct score_elf_link_hash_entry *)
elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ h = ((struct score_elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &h->root.root));
+
/* Find the real hash-table entry for this symbol. */
while (h->root.root.type == bfd_link_hash_indirect
|| h->root.root.type == bfd_link_hash_warning)
}
}
- 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)
{
{
while (h->root.type == bfd_link_hash_indirect)
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;
}
}
if (!h->def_regular)
{
/* We need .stub section. */
- s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
+ s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
BFD_ASSERT (s != NULL);
h->root.u.def.section = s;
/* Calculate the total loadable size of the output. That will give us the
maximum number of GOT_PAGE entries required. */
- for (sub = info->input_bfds; sub; sub = sub->link_next)
+ for (sub = info->input_bfds; sub; sub = sub->link.next)
{
asection *subsection;
/* Set the contents of the .interp section to the interpreter. */
if (!info->shared)
{
- s = bfd_get_section_by_name (dynobj, ".interp");
+ s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
| SEC_LINKER_CREATED | SEC_READONLY);
/* ABI requests the .dynamic section to be read only. */
- s = bfd_get_section_by_name (abfd, ".dynamic");
+ s = bfd_get_linker_section (abfd, ".dynamic");
if (s != NULL)
{
if (!bfd_set_section_flags (abfd, s, flags))
return FALSE;
/* Create .stub section. */
- if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
+ if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
{
- s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
- flags | SEC_CODE);
+ s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
+ flags | SEC_CODE);
if (s == NULL
|| !bfd_set_section_alignment (abfd, s, 2))
/* This symbol has a stub. Set it up. */
BFD_ASSERT (h->dynindx != -1);
- s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
+ s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
BFD_ASSERT (s != NULL);
/* FIXME: Can h->dynindex be more than 64K? */
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
name = h->root.root.string;
- if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
sym->st_shndx = SHN_ABS;
else if (strcmp (name, "_DYNAMIC_LINK") == 0)
{
dynobj = elf_hash_table (info)->dynobj;
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
sgot = score_elf_got_section (dynobj, FALSE);
if (sgot == NULL)
case 148: /* Linux/Score 32-bit. */
/* pr_cursig */
- elf_tdata (abfd)->core_signal = score_bfd_get_16 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->signal
+ = score_bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
- elf_tdata (abfd)->core_pid = score_bfd_get_32 (abfd, note->descdata + 24);
+ elf_tdata (abfd)->core->lwpid
+ = score_bfd_get_32 (abfd, note->descdata + 24);
/* pr_reg */
offset = 72;
}
/* Make a ".reg/999" section. */
- return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
+ note->descpos + offset);
}
static bfd_boolean
return FALSE;
case 124: /* Linux/Score elf_prpsinfo. */
- elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
- elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
}
/* Note that for some reason, a spurious space is tacked
implementations, so strip it off if it exists. */
{
- char *command = elf_tdata (abfd)->core_command;
+ char *command = elf_tdata (abfd)->core->command;
int n = strlen (command);
if (0 < n && command[n - 1] == ' ')
return NULL;
}
-/* Create a score elf linker hash table. */
-
-static struct bfd_link_hash_table *
-s3_elf32_score_link_hash_table_create (bfd *abfd)
-{
- struct score_elf_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct score_elf_link_hash_table);
-
- ret = bfd_malloc (amt);
- if (ret == NULL)
- return NULL;
-
- if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, score_elf_link_hash_newfunc,
- sizeof (struct score_elf_link_hash_entry)))
- {
- free (ret);
- return NULL;
- }
-
- return &ret->root.root;
-}
-
static bfd_boolean
s3_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
{
return s7_elf32_score_reloc_type_lookup (abfd, code);
}
+/* Create a score elf linker hash table.
+ This is a copy of _bfd_elf_link_hash_table_create() except with a
+ different hash table entry creation function. */
+
static struct bfd_link_hash_table *
elf32_score_link_hash_table_create (bfd *abfd)
{
- if (bfd_get_mach (abfd) == bfd_mach_score3)
- return s3_elf32_score_link_hash_table_create (abfd);
- else
- return s7_elf32_score_link_hash_table_create (abfd);
+ struct elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_link_hash_table);
+
+ ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (ret, abfd, score_elf_link_hash_newfunc,
+ sizeof (struct score_elf_link_hash_entry),
+ GENERIC_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root;
}
static bfd_boolean
#define USE_REL 1
-#define TARGET_LITTLE_SYM bfd_elf32_littlescore_vec
+#define TARGET_LITTLE_SYM score_elf32_le_vec
#define TARGET_LITTLE_NAME "elf32-littlescore"
-#define TARGET_BIG_SYM bfd_elf32_bigscore_vec
+#define TARGET_BIG_SYM score_elf32_be_vec
#define TARGET_BIG_NAME "elf32-bigscore"
#define ELF_ARCH bfd_arch_score
#define ELF_MACHINE_CODE EM_SCORE