/* BFD back-end for National Semiconductor's CR16 ELF
- Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2007-2017 Free Software Foundation, Inc.
Written by M R Swami Reddy.
This file is part of BFD, the Binary File Descriptor library.
linking with -Bsymbolic. We store the information in a field
extending the regular ELF linker hash table. */
-struct elf32_cr16_link_hash_entry {
+struct elf32_cr16_link_hash_entry
+{
/* The basic elf link hash table entry. */
struct elf_link_hash_entry root;
bfd_vma value;
};
-/* We derive a hash table from the main elf linker hash table so
- we can store state variables and a secondary hash table without
- resorting to global variables. */
-struct elf32_cr16_link_hash_table {
- /* The main hash table. */
- struct elf_link_hash_table root;
-
- /* A hash table for static functions. We could derive a new hash table
- instead of using the full elf32_cr16_link_hash_table if we wanted
- to save some memory. */
- struct elf32_cr16_link_hash_table *static_hash_table;
-
- /* Random linker state flags. */
-#define CR16_HASH_ENTRIES_INITIALIZED 0x1
- char flags;
-};
-
-/* For CR16 linker hash table. */
-
-/* Get the CR16 ELF linker hash table from a link_info structure. */
-
-#define elf32_cr16_hash_table(p) \
- ((struct elf32_cr16_link_hash_table *) ((p)->hash))
-
-#define elf32_cr16_link_hash_traverse(table, func, info) \
- (elf_link_hash_traverse \
- (&(table)->root, \
- (bfd_boolean (*) ((struct elf_link_hash_entry *, void *))) (func), (info)))
-
/* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
struct cr16_reloc_map
{
HOWTO (R_CR16_NONE, /* type */
0, /* rightshift */
- 2, /* size */
- 32, /* bitsize */
+ 3, /* size */
+ 0, /* bitsize */
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
asection * s;
struct elf_link_hash_entry * h;
const struct elf_backend_data * bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
int ptralign;
/* This function may be called more than once. */
- if (bfd_get_section_by_name (abfd, ".got") != NULL)
+ if (htab->sgot != NULL)
return TRUE;
switch (bed->s->arch_size)
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
- s = bfd_make_section_with_flags (abfd, ".got", flags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ htab->sgot= s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
if (bed->want_got_plt)
{
- s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ htab->sgotplt = s;
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
because we don't want to define the symbol if we are not creating
a global offset table. */
h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
- elf_hash_table (info)->hgot = h;
+ htab->hgot = h;
if (h == NULL)
return FALSE;
if (code == cr16_reloc_map[i].bfd_reloc_enum)
return &cr16_elf_howto_table[cr16_reloc_map[i].cr16_reloc_type];
- _bfd_error_handler ("Unsupported CR16 relocation type: 0x%x\n", code);
+ _bfd_error_handler (_("Unsupported CR16 relocation type: 0x%x\n"), code);
return NULL;
}
{
unsigned int r_type = ELF32_R_TYPE (dst->r_info);
- BFD_ASSERT (r_type < (unsigned int) R_CR16_MAX);
+ if (r_type >= R_CR16_MAX)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: unrecognised CR16 reloc number: %d"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ r_type = R_CR16_NONE;
+ }
cache_ptr->howto = cr16_elf_howto_table + r_type;
}
srelgot = NULL;
bfd_boolean result = FALSE;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
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_CR16_GOTC_REGREL20:
/* This symbol requires a global offset table entry. */
- if (sgot == NULL)
- {
- sgot = bfd_get_section_by_name (dynobj, ".got");
- BFD_ASSERT (sgot != NULL);
- }
-
- if (srelgot == NULL
- && (h != NULL || info->executable))
- {
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
- if (srelgot == NULL)
- {
- srelgot = bfd_make_section_with_flags (dynobj,
- ".rela.got",
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
- if (srelgot == NULL
- || ! bfd_set_section_alignment (dynobj, srelgot, 2))
- goto fail;
- }
- }
+ sgot = elf_hash_table (info)->sgot;
+ srelgot = elf_hash_table (info)->srelgot;
+ BFD_ASSERT (sgot != NULL && srelgot != NULL);
if (h != NULL)
{
local_got_offsets[r_symndx] = sgot->size;
- if (info->executable)
+ if (bfd_link_executable (info))
/* If we are generating a shared object, we need to
output a R_CR16_RELATIVE reloc so that the dynamic
linker can adjust this GOT entry. */
bfd_byte *hit_data = contents + offset;
bfd_vma reloc_bits, check, Rvalue1;
- bfd * dynobj;
- bfd_vma * local_got_offsets;
- asection * sgot;
-
- dynobj = elf_hash_table (info)->dynobj;
- local_got_offsets = elf_local_got_offsets (input_bfd);
-
- sgot = NULL;
-
-
switch (r_type)
{
case R_CR16_IMM4:
/* We only care about the addend, where the difference between
expressions is kept. */
Rvalue = 0;
-
+
default:
break;
}
| ((Rvalue >> 16) & 0xf)), hit_data);
bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
}
- else if (r_type == R_CR16_GOT_REGREL20)
+ else if (r_type == R_CR16_GOT_REGREL20)
{
- asection * sgot = bfd_get_section_by_name (dynobj, ".got");
+ asection *sgot = elf_hash_table (info)->sgot;
if (h != NULL)
{
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
because of a version file. We must initialize
- this entry in the global offset table.
+ this entry in the global offset table.
When doing a dynamic link, we create a .rela.got
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
Rvalue += addend;
- /* REVISIT: if ((long) Rvalue > 0xffffff ||
+ /* REVISIT: if ((long) Rvalue > 0xffffff ||
(long) Rvalue < -0x800000). */
if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
return bfd_reloc_overflow;
}
else if (r_type == R_CR16_GOTC_REGREL20)
{
- asection * sgot;
- sgot = bfd_get_section_by_name (dynobj, ".got");
+ asection *sgot = elf_hash_table (info)->sgot;
if (h != NULL)
{
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
because of a version file. We must initialize
- this entry in the global offset table.
+ this entry in the global offset table.
When doing a dynamic link, we create a .rela.got
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
Rvalue += Rvalue1;
/* Check for range. */
- /* REVISIT: if ((long) Rvalue > 0xffffff
+ /* REVISIT: if ((long) Rvalue > 0xffffff
|| (long) Rvalue < -0x800000). */
if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
return bfd_reloc_overflow;
}
else if (r_type == R_CR16_NUM32)
{
- Rvalue1 = (bfd_get_32 (input_bfd, hit_data));
+ Rvalue1 = (bfd_get_32 (input_bfd, hit_data));
/* Add or subtract the offset value */
if (Rvalue1 & 0x80000000)
unsigned int sec_shndx;
bfd_byte *contents;
Elf_Internal_Rela *irel, *irelend;
- Elf_Internal_Rela *irelalign;
bfd_vma toaddr;
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
contents = elf_section_data (sec)->this_hdr.contents;
- /* The deletion must stop at the next ALIGN reloc for an aligment
- power larger than the number of bytes we are deleting. */
- irelalign = NULL;
toaddr = sec->size;
irel = elf_section_data (sec)->relocs;
&& ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH16
&& ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH32)
continue;
-
+
r_symndx = ELF32_R_SYM (irel->r_info);
rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Rela *rel, *relend;
- if (info->relocatable)
- return TRUE;
-
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
}
else
{
- bfd_boolean unresolved_reloc, warned;
+ bfd_boolean unresolved_reloc, warned, ignored;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
h, sec, relocation,
- unresolved_reloc, warned);
+ unresolved_reloc, warned, ignored);
}
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (bfd_link_relocatable (info))
+ continue;
+
r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd,
input_section,
contents, rel->r_offset,
switch (r)
{
case bfd_reloc_overflow:
- if (!((*info->callbacks->reloc_overflow)
- (info, (h ? &h->root : NULL), name, howto->name,
- (bfd_vma) 0, input_bfd, input_section,
- rel->r_offset)))
- return FALSE;
+ (*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
break;
case bfd_reloc_undefined:
- if (!((*info->callbacks->undefined_symbol)
- (info, name, input_bfd, input_section,
- rel->r_offset, TRUE)))
- return FALSE;
+ (*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section, rel->r_offset, TRUE);
break;
case bfd_reloc_outofrange:
/* Fall through. */
common_error:
- if (!((*info->callbacks->warning)
- (info, msg, name, input_bfd, input_section,
- rel->r_offset)))
- return FALSE;
+ (*info->callbacks->warning) (info, msg, name, input_bfd,
+ input_section, rel->r_offset);
break;
}
}
static struct bfd_link_hash_table *
elf32_cr16_link_hash_table_create (bfd *abfd)
{
- struct elf32_cr16_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct elf32_cr16_link_hash_table);
+ struct elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_link_hash_table);
- ret = (struct elf32_cr16_link_hash_table *) bfd_malloc (amt);
- if (ret == (struct elf32_cr16_link_hash_table *) NULL)
+ ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == (struct elf_link_hash_table *) NULL)
return NULL;
- if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
- elf32_cr16_link_hash_newfunc,
- sizeof (struct elf32_cr16_link_hash_entry)))
- {
- free (ret);
- return NULL;
- }
-
- ret->flags = 0;
- amt = sizeof (struct elf_link_hash_table);
- ret->static_hash_table
- = (struct elf32_cr16_link_hash_table *) bfd_malloc (amt);
- if (ret->static_hash_table == NULL)
- {
- free (ret);
- return NULL;
- }
-
- if (!_bfd_elf_link_hash_table_init (&ret->static_hash_table->root, abfd,
+ if (!_bfd_elf_link_hash_table_init (ret, abfd,
elf32_cr16_link_hash_newfunc,
- sizeof (struct elf32_cr16_link_hash_entry)))
+ sizeof (struct elf32_cr16_link_hash_entry),
+ GENERIC_ELF_DATA))
{
- free (ret->static_hash_table);
free (ret);
return NULL;
}
- return &ret->root.root;
-}
-
-/* Free an cr16 ELF linker hash table. */
-
-static void
-elf32_cr16_link_hash_table_free (struct bfd_link_hash_table *hash)
-{
- struct elf32_cr16_link_hash_table *ret
- = (struct elf32_cr16_link_hash_table *) hash;
- _bfd_generic_link_hash_table_free
- ((struct bfd_link_hash_table *) ret->static_hash_table);
- _bfd_generic_link_hash_table_free
- ((struct bfd_link_hash_table *) ret);
+ return &ret->root;
}
static unsigned long
object file when linking. */
static bfd_boolean
-_bfd_cr16_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+_bfd_cr16_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
+
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return TRUE;
/* We don't have to do anything for a relocatable link, if
this section does not have relocs, or if this is not a
code section. */
- if (link_info->relocatable
+ if (bfd_link_relocatable (link_info)
|| (sec->flags & SEC_RELOC) == 0
|| sec->reloc_count == 0
|| (sec->flags & SEC_CODE) == 0)
bfd_vma value = symval;
unsigned short is_add_mov = 0;
bfd_vma value1 = 0;
-
+
/* Get the existing value from the mcode */
value1 = ((bfd_get_32 (abfd, contents + irel->r_offset + 2) >> 16)
|(((bfd_get_32 (abfd, contents + irel->r_offset + 2) & 0xffff) << 16)));
/* Verify it's a 'arithmetic ADDD or MOVD instruction'.
For ADDD and MOVD only, convert to IMM32 -> IMM20. */
-
+
if (((code & 0xfff0) == 0x0070) || ((code & 0xfff0) == 0x0020))
is_add_mov = 1;
bfd_put_8 (abfd, (code & 0xf) << 4, contents + irel->r_offset);
- /* If existing value is nagavive adjust approriately
+ /* If existing value is nagavive adjust approriately
place the 16-20bits (ie 4 bit) in new opcode,
as the 0xffffxxxx, the higher 2 byte values removed. */
if (value1 & 0x80000000)
}
/* See if the value will fit in 16 bits. */
- if ((!is_add_mov)
+ if ((!is_add_mov)
&& ((long)(value + value1) < 0x7fff && (long)(value + value1) > 0))
{
unsigned short code;
bfd_put_8 (abfd, 0xb0 | (code & 0xf), contents + irel->r_offset);
- /* If existing value is nagavive adjust approriately
+ /* If existing value is nagavive adjust approriately
place the 12-16bits (ie 4 bit) in new opcode,
as the 0xfffffxxx, the higher 2 byte values removed. */
if (value1 & 0x80000000)
#if 0
/* Try to turn a 16bit immediate address into a 4bit
immediate address. */
- if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
+ if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
|| (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16))
{
bfd_vma value = symval;
else
/* Cache the section contents for elf_link_input_bfd. */
elf_section_data (sec)->this_hdr.contents = contents;
-
+
}
if (internal_relocs != NULL
static asection *
elf32_cr16_gc_mark_hook (asection *sec,
- struct bfd_link_info *info ATTRIBUTE_UNUSED,
- Elf_Internal_Rela *rel ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
struct elf_link_hash_entry *h,
Elf_Internal_Sym *sym)
{
- if (h == NULL)
- return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-
- 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:
- return NULL;
- }
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}
/* Update the got entry reference counts for the section being removed. */
flagword flags;
asection * s;
const struct elf_backend_data * bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
int ptralign = 0;
switch (bed->s->arch_size)
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
- 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))
return FALSE;
if (! _bfd_cr16_elf_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 = (char *) bfd_malloc (strlen (secname) + 6);
- strcpy (relname, ".rela");
- strcat (relname, secname);
-
- 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);
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->executable)
+ if (! bfd_link_executable (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);
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
if (h->type == STT_FUNC
|| h->needs_plt)
{
- if (! info->executable
+ if (! bfd_link_executable (info)
&& !h->def_dynamic
&& !h->ref_dynamic)
{
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
- s = bfd_get_section_by_name (dynobj, ".got.plt");
+ s = elf_hash_table (info)->sgotplt;
BFD_ASSERT (s != NULL);
s->size += 4;
/* We also need to make an entry in the .rela.plt section. */
- s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ s = elf_hash_table (info)->srelplt;
BFD_ASSERT (s != NULL);
s->size += sizeof (Elf32_External_Rela);
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->executable)
+ if (bfd_link_executable (info))
return TRUE;
/* If there are no references to this symbol that do not use the
if (!h->non_got_ref)
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
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
- s = bfd_get_section_by_name (dynobj, ".dynbss");
+ s = bfd_get_linker_section (dynobj, ".dynbss");
BFD_ASSERT (s != NULL);
/* We must generate a R_CR16_COPY reloc to tell the dynamic linker 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;
- srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
BFD_ASSERT (srel != NULL);
srel->size += sizeof (Elf32_External_Rela);
h->needs_copy = 1;
}
- return _bfd_elf_adjust_dynamic_copy (h, s);
+ return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
/* Set the sizes of the dynamic sections. */
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (info->executable)
+ if (bfd_link_executable (info) && !info->nointerp)
{
#if 0
- 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;
not actually use these entries. Reset the size of .rela.got,
which will cause it to get stripped from the output file
below. */
- s = bfd_get_section_by_name (dynobj, ".rela.got");
+ s = elf_hash_table (info)->srelgot;
if (s != NULL)
s->size = 0;
}
but we must add the entries now so that we get the correct
size for the .dynamic section. The DT_DEBUG entry is filled
in by the dynamic linker and used by the debugger. */
- if (! info->executable)
+ if (! bfd_link_executable (info))
{
if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
return FALSE;
/* This symbol has an entry in the global offset table. Set it up. */
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srel = bfd_get_section_by_name (dynobj, ".rela.got");
+ sgot = elf_hash_table (info)->sgot;
+ srel = elf_hash_table (info)->srelgot;
BFD_ASSERT (sgot != NULL && srel != NULL);
rel.r_offset = (sgot->output_section->vma
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->executable
+ if (bfd_link_executable (info)
&& (info->symbolic || h->dynindx == -1)
&& h->def_regular)
{
&& (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 (dynobj, ".rela.bss");
BFD_ASSERT (s != NULL);
rel.r_offset = (h->root.u.def.value
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
- if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ if (h == elf_hash_table (info)->hdynamic
|| h == elf_hash_table (info)->hgot)
sym->st_shndx = SHN_ABS;
dynobj = elf_hash_table (info)->dynobj;
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ sgot = elf_hash_table (info)->sgotplt;
BFD_ASSERT (sgot != NULL);
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->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 = elf_hash_table (info)->sgotplt;
goto get_vma;
case DT_JMPREL:
- name = ".rela.plt";
+ s = elf_hash_table (info)->srelplt;
get_vma:
- s = bfd_get_section_by_name (output_bfd, name);
- BFD_ASSERT (s != NULL);
- dyn.d_un.d_ptr = s->vma;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
case DT_PLTRELSZ:
- s = bfd_get_section_by_name (output_bfd, ".rela.plt");
- BFD_ASSERT (s != NULL);
+ s = elf_hash_table (info)->srelplt;
dyn.d_un.d_val = s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
-
- case DT_RELASZ:
- /* My reading of the SVR4 ABI indicates that the
- procedure linkage table relocs (DT_JMPREL) should be
- included in the overall relocs (DT_RELA). This is
- what Solaris does. However, UnixWare can not handle
- that case. Therefore, we override the DT_RELASZ entry
- here to make it not include the JMPREL relocs. Since
- the linker script arranges for .rela.plt to follow all
- other relocation sections, we don't have to worry
- about changing the DT_RELA entry. */
- s = bfd_get_section_by_name (output_bfd, ".rela.plt");
- if (s != NULL)
- dyn.d_un.d_val -= s->size;
- bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
- break;
}
}
bfd_byte *p;
bfd_size_type amt;
- BFD_ASSERT (! info->relocatable);
+ BFD_ASSERT (! bfd_link_relocatable (info));
*errmsg = NULL;
properly. */
static enum elf_reloc_type_class
-_bfd_cr16_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+_bfd_cr16_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))
{
}
/* Definitions for setting CR16 target vector. */
-#define TARGET_LITTLE_SYM bfd_elf32_cr16_vec
+#define TARGET_LITTLE_SYM cr16_elf32_vec
#define TARGET_LITTLE_NAME "elf32-cr16"
#define ELF_ARCH bfd_arch_cr16
#define ELF_MACHINE_CODE EM_CR16
#define bfd_elf32_bfd_link_hash_table_create \
elf32_cr16_link_hash_table_create
-#define bfd_elf32_bfd_link_hash_table_free \
- elf32_cr16_link_hash_table_free
#define elf_backend_create_dynamic_sections \
_bfd_cr16_elf_create_dynamic_sections
#define elf_backend_plt_readonly 1
#define elf_backend_want_plt_sym 0
#define elf_backend_got_header_size 12
+#define elf_backend_dtrel_excludes_plt 1
#include "elf32-target.h"