/* Matsushita 10300 specific support for 32-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "bfd.h"
#include "sysdep.h"
linking with -Bsymbolic. We store the information in a field
extending the regular ELF linker hash table. */
-/* This structure keeps track of the number of PC relative relocs we
- have copied for a given symbol. */
-
-struct elf_mn10300_pcrel_relocs_copied
-{
- /* Next section. */
- struct elf_mn10300_pcrel_relocs_copied * next;
- /* A section in dynobj. */
- asection * section;
- /* Number of relocs copied in this section. */
- bfd_size_type count;
-};
-
struct elf32_mn10300_link_hash_entry {
/* The basic elf link hash table entry. */
struct elf_link_hash_entry root;
to the target when it's valid and profitable to do so. */
unsigned char movm_args;
- /* For funtion symbols, the amount of stack space that would be allocated
+ /* For function symbols, the amount of stack space that would be allocated
by the movm instruction. This is redundant with movm_args, but we
add it to the hash table to avoid computing it over and over. */
unsigned char movm_stack_size;
- /* Number of PC relative relocs copied for this symbol. */
- struct elf_mn10300_pcrel_relocs_copied * pcrel_relocs_copied;
-
/* When set, convert all "call" instructions to this target into "calls"
instructions. */
#define MN10300_CONVERT_CALL_TO_CALLS 0x1
PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean _bfd_mn10300_elf_adjust_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
-static bfd_boolean _bfd_mn10300_elf_discard_copies
- PARAMS ((struct elf32_mn10300_link_hash_entry *,
- struct bfd_link_info *));
static bfd_boolean _bfd_mn10300_elf_size_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean _bfd_mn10300_elf_finish_dynamic_symbol
if (bed->plt_readonly)
pltflags |= SEC_READONLY;
- s = bfd_make_section (abfd, ".plt");
+ s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, pltflags)
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
return FALSE;
get_elf_backend_data (abfd)->collect, &bh)))
return FALSE;
h = (struct elf_link_hash_entry *) bh;
- h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->def_regular = 1;
h->type = STT_OBJECT;
if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
- s = bfd_make_section (abfd, ".got");
+ s = bfd_make_section_with_flags (abfd, ".got", flags);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags)
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
if (bed->want_got_plt)
{
- s = bfd_make_section (abfd, ".got.plt");
+ s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags)
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
}
bh = NULL;
if (!(_bfd_generic_link_add_one_symbol
(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
- bed->got_symbol_offset, (const char *) NULL, FALSE,
- bed->collect, &bh)))
+ 0, (const char *) NULL, FALSE, bed->collect, &bh)))
return FALSE;
h = (struct elf_link_hash_entry *) bh;
- h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->def_regular = 1;
h->type = STT_OBJECT;
if (info->shared
- && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
elf_hash_table (info)->hgot = h;
/* The first bit of the global offset table is the header. */
- s->_raw_size += bed->got_header_size + bed->got_symbol_offset;
+ s->size += bed->got_header_size;
return TRUE;
}
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
case R_MN10300_GNU_VTINHERIT:
- if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return FALSE;
break;
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_MN10300_GNU_VTENTRY:
- if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
case R_MN10300_GOT32:
srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
if (srelgot == NULL)
{
- srelgot = bfd_make_section (dynobj, ".rela.got");
+ 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_flags (dynobj, srelgot,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY))
|| ! bfd_set_section_alignment (dynobj, srelgot, 2))
return FALSE;
}
/* We have already allocated space in the .got. */
break;
- h->got.offset = sgot->_raw_size;
+ h->got.offset = sgot->size;
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
- if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
- srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ srelgot->size += sizeof (Elf32_External_Rela);
}
else
{
/* This is a global offset table entry for a local
- symbol. */
+ symbol. */
if (local_got_offsets == NULL)
{
size_t size;
/* We have already allocated space in the .got. */
break;
- local_got_offsets[r_symndx] = sgot->_raw_size;
+ local_got_offsets[r_symndx] = sgot->size;
if (info->shared)
/* If we are generating a shared object, we need to
output a R_MN10300_RELATIVE reloc so that the dynamic
linker can adjust this GOT entry. */
- srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ srelgot->size += sizeof (Elf32_External_Rela);
}
- sgot->_raw_size += 4;
+ sgot->size += 4;
break;
|| ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
break;
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->needs_plt = 1;
break;
- case R_MN10300_32:
case R_MN10300_24:
case R_MN10300_16:
case R_MN10300_8:
case R_MN10300_PCREL16:
case R_MN10300_PCREL8:
if (h != NULL)
- h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
- /* If we are creating a shared library, and this is a reloc
- against a global symbol, or a non PC relative reloc
- against a local symbol, then we need to copy the reloc
- into the shared library. However, if we are linking with
- -Bsymbolic, we do not need to copy a reloc against a
- global symbol which is defined in an object we are
- including in the link (i.e., DEF_REGULAR is set). At
- this point we have not seen all the input files, so it is
- possible that DEF_REGULAR is not set now but will be set
- later (it is never cleared). We account for that
- possibility below by storing information in the
- pcrel_relocs_copied field of the hash table entry. */
+ h->non_got_ref = 1;
+ break;
+
+ case R_MN10300_32:
+ if (h != NULL)
+ h->non_got_ref = 1;
+
+ /* If we are creating a shared library, then we need to copy
+ the reloc into the shared library. */
if (info->shared
- && (sec->flags & SEC_ALLOC) != 0
- && (! (elf_mn10300_howto_table[ELF32_R_TYPE (rel->r_info)]
- .pc_relative)
- || (h != NULL
- && (! info->symbolic
- || h->root.type == bfd_link_hash_defweak
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+ && (sec->flags & SEC_ALLOC) != 0)
{
/* When creating a shared object, we must copy these
reloc types into the output file. We create a reloc
{
flagword flags;
- sreloc = bfd_make_section (dynobj, name);
flags = (SEC_HAS_CONTENTS | SEC_READONLY
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
if ((sec->flags & SEC_ALLOC) != 0)
flags |= SEC_ALLOC | SEC_LOAD;
+ sreloc = bfd_make_section_with_flags (dynobj,
+ name,
+ flags);
if (sreloc == NULL
- || ! bfd_set_section_flags (dynobj, sreloc, flags)
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
return FALSE;
}
}
- sreloc->_raw_size += sizeof (Elf32_External_Rela);
-
- /* If we are linking with -Bsymbolic, and this is a
- global symbol, we count the number of PC relative
- relocations we have entered for this symbol, so that
- we can discard them again if the symbol is later
- defined by a regular object. Note that this function
- is only called if we are using an elf_sh linker
- hash table, which means that h is really a pointer to
- an elf32_mn10300_link_hash_entry. */
- if (h != NULL
- && (elf_mn10300_howto_table[ELF32_R_TYPE (rel->r_info)]
- .pc_relative))
- {
- struct elf32_mn10300_link_hash_entry *eh;
- struct elf_mn10300_pcrel_relocs_copied *p;
-
- eh = (struct elf32_mn10300_link_hash_entry *) h;
-
- for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
- if (p->section == sreloc)
- break;
-
- if (p == NULL)
- {
- p = ((struct elf_mn10300_pcrel_relocs_copied *)
- bfd_alloc (dynobj, sizeof *p));
- if (p == NULL)
- return FALSE;
-
- p->next = eh->pcrel_relocs_copied;
- eh->pcrel_relocs_copied = p;
- p->section = sreloc;
- p->count = 0;
- }
-
- ++p->count;
- }
+ sreloc->size += sizeof (Elf32_External_Rela);
}
break;
bfd_vma addend;
struct elf_link_hash_entry * h;
unsigned long symndx;
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
+ struct bfd_link_info *info;
asection *sym_sec ATTRIBUTE_UNUSED;
int is_local ATTRIBUTE_UNUSED;
{
splt = NULL;
sreloc = NULL;
+ switch (r_type)
+ {
+ case R_MN10300_24:
+ case R_MN10300_16:
+ case R_MN10300_8:
+ case R_MN10300_PCREL8:
+ case R_MN10300_PCREL16:
+ case R_MN10300_PCREL32:
+ case R_MN10300_GOTOFF32:
+ case R_MN10300_GOTOFF24:
+ case R_MN10300_GOTOFF16:
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && ! SYMBOL_REFERENCES_LOCAL (info, h))
+ return bfd_reloc_dangerous;
+ }
+
switch (r_type)
{
case R_MN10300_NONE:
skip = FALSE;
- if (elf_section_data (input_section)->sec_info == NULL
- || (input_section->sec_info_type != ELF_INFO_TYPE_STABS))
- outrel.r_offset = offset;
- else
- {
- bfd_vma off;
-
- off = (_bfd_stab_section_offset
- (output_bfd, & elf_hash_table (info)->stab_info,
- input_section,
- & elf_section_data (input_section)->sec_info,
- offset));
- if (off == (bfd_vma) -1)
- skip = TRUE;
- outrel.r_offset = off;
- }
+ outrel.r_offset = _bfd_elf_section_offset (input_bfd, info,
+ input_section, offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
/* h->dynindx may be -1 if this symbol was marked to
become local. */
if (h == NULL
- || ((info->symbolic || h->dynindx == -1)
- && (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) != 0))
+ || SYMBOL_REFERENCES_LOCAL (info, h))
{
relocate = TRUE;
outrel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE);
return bfd_reloc_ok;
case R_MN10300_PCREL32:
- if (info->shared
- && (input_section->flags & SEC_ALLOC) != 0
- && h != NULL
- && h->dynindx != -1
- && (! info->symbolic
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))
- {
- Elf_Internal_Rela outrel;
- bfd_boolean skip;
-
- /* When generating a shared object, these relocations
- are copied into the output file to be resolved at run
- time. */
-
- if (sreloc == NULL)
- {
- const char * name;
-
- name = (bfd_elf_string_from_elf_section
- (input_bfd,
- elf_elfheader (input_bfd)->e_shstrndx,
- elf_section_data (input_section)->rel_hdr.sh_name));
- if (name == NULL)
- return FALSE;
-
- BFD_ASSERT (strncmp (name, ".rela", 5) == 0
- && strcmp (bfd_get_section_name (input_bfd,
- input_section),
- name + 5) == 0);
-
- sreloc = bfd_get_section_by_name (dynobj, name);
- BFD_ASSERT (sreloc != NULL);
- }
-
- skip = FALSE;
-
- if (elf_section_data (input_section)->sec_info == NULL
- || (input_section->sec_info_type != ELF_INFO_TYPE_STABS))
- outrel.r_offset = offset;
- else
- {
- bfd_vma off;
-
- off = (_bfd_stab_section_offset
- (output_bfd, & elf_hash_table (info)->stab_info,
- input_section,
- & elf_section_data (input_section)->sec_info,
- offset));
- if (off == (bfd_vma) -1)
- skip = TRUE;
- outrel.r_offset = off;
- }
-
- outrel.r_offset += (input_section->output_section->vma
- + input_section->output_offset);
-
- if (skip)
- memset (&outrel, 0, sizeof outrel);
- else
- {
- BFD_ASSERT (h != NULL && h->dynindx != -1);
- outrel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_PCREL32);
- outrel.r_addend = addend;
- }
-
- bfd_elf32_swap_reloca_out (output_bfd, &outrel,
- (bfd_byte *) (((Elf32_External_Rela *)
- sreloc->contents)
- + sreloc->reloc_count));
- ++sreloc->reloc_count;
-
- return bfd_reloc_ok;
- }
-
value -= (input_section->output_section->vma
+ input_section->output_offset);
value -= offset;
bfd_put_32 (input_bfd, value, hit_data);
return bfd_reloc_ok;
-
+
case R_MN10300_GOTPC16:
/* Use global offset table as symbol value. */
value -= bfd_get_section_by_name (dynobj,
".got")->output_section->vma;
value += addend;
-
+
bfd_put_32 (input_bfd, value, hit_data);
return bfd_reloc_ok;
value -= bfd_get_section_by_name (dynobj,
".got")->output_section->vma;
value += addend;
-
+
if ((long) value > 0x7fffff || (long) value < -0x800000)
return bfd_reloc_overflow;
value -= bfd_get_section_by_name (dynobj,
".got")->output_section->vma;
value += addend;
-
+
if ((long) value > 0xffff || (long) value < -0x10000)
return bfd_reloc_overflow;
asection * splt;
splt = bfd_get_section_by_name (dynobj, ".plt");
-
+
value = (splt->output_section->vma
+ splt->output_offset
+ h->plt.offset) - value;
asection * splt;
splt = bfd_get_section_by_name (dynobj, ".plt");
-
+
value = (splt->output_section->vma
+ splt->output_offset
+ h->plt.offset) - value;
asection * sgot;
sgot = bfd_get_section_by_name (dynobj, ".got");
-
+
if (h != NULL)
{
bfd_vma off;
BFD_ASSERT (off != (bfd_vma) -1);
if (! elf_hash_table (info)->dynamic_sections_created
- || (info->shared
- && (info->symbolic || h->dynindx == -1)
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ || SYMBOL_REFERENCES_LOCAL (info, h))
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
return bfd_reloc_ok;
}
/* Fall through. */
-
+
default:
return bfd_reloc_notsupported;
}
asection **local_sections;
{
Elf_Internal_Shdr *symtab_hdr;
- struct elf32_mn10300_link_hash_entry **sym_hashes;
+ 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 = (struct elf32_mn10300_link_hash_entry **)
- (elf_sym_hashes (input_bfd));
+ sym_hashes = elf_sym_hashes (input_bfd);
rel = relocs;
relend = relocs + input_section->reloc_count;
{
sym = local_syms + r_symndx;
sec = local_sections[r_symndx];
- relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
}
else
{
bfd_boolean warned;
struct elf_link_hash_entry *hh;
- RELOC_FOR_GLOBAL_SYMBOL (hh, (struct elf_link_hash_entry *) sym_hashes,
- r_symndx, symtab_hdr, relocation,
- sec, unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ hh, sec, relocation,
+ unresolved_reloc, warned);
h = (struct elf32_mn10300_link_hash_entry *) hh;
|| r_type == R_MN10300_GOT24
|| r_type == R_MN10300_GOT16)
&& elf_hash_table (info)->dynamic_sections_created
- && (! info->shared
- || (! info->symbolic && h->root.dynindx != -1)
- || (h->root.elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))
- || (info->shared
- && ((! info->symbolic && h->root.dynindx != -1)
- || (h->root.elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0)
- && ( r_type == R_MN10300_32
- || r_type == R_MN10300_PCREL32)
+ && !SYMBOL_REFERENCES_LOCAL (info, hh))
+ || (r_type == R_MN10300_32
+ && !SYMBOL_REFERENCES_LOCAL (info, hh)
&& ((input_section->flags & SEC_ALLOC) != 0
/* DWARF will emit R_MN10300_32 relocations
in its sections against symbols defined
externally in shared libraries. We can't
do anything with them here. */
|| ((input_section->flags & SEC_DEBUGGING) != 0
- && (h->root.elf_link_hash_flags
- & ELF_LINK_HASH_DEF_DYNAMIC) != 0)))))
+ && h->root.def_dynamic)))))
/* In these cases, we don't need the relocation
value. We check specially because in some
obscure cases sec->output_section will be NULL. */
{
case bfd_reloc_overflow:
if (! ((*info->callbacks->reloc_overflow)
- (info, name, howto->name, (bfd_vma) 0,
- input_bfd, input_section, rel->r_offset)))
+ (info, (h ? &h->root.root : NULL), name,
+ howto->name, (bfd_vma) 0, input_bfd,
+ input_section, rel->r_offset)))
return FALSE;
break;
static bfd_boolean
elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
struct bfd_hash_entry *gen_entry;
- PTR in_args ATTRIBUTE_UNUSED;
+ PTR in_args;
{
struct elf32_mn10300_link_hash_entry *entry;
+ struct bfd_link_info *link_info = (struct bfd_link_info *)in_args;
unsigned int byte_count = 0;
entry = (struct elf32_mn10300_link_hash_entry *) gen_entry;
return TRUE;
/* If there are no named calls to this symbol, or there's nothing we
- can move from the function itself into the "call" instruction, then
- note that all "call" instructions should be converted into "calls"
- instructions and return. */
+ can move from the function itself into the "call" instruction,
+ then note that all "call" instructions should be converted into
+ "calls" instructions and return. If a symbol is available for
+ dynamic symbol resolution (overridable or overriding), avoid
+ custom calling conventions. */
if (entry->direct_calls == 0
- || (entry->stack_size == 0 && entry->movm_args == 0))
+ || (entry->stack_size == 0 && entry->movm_args == 0)
+ || (elf_hash_table (link_info)->dynamic_sections_created
+ && ELF_ST_VISIBILITY (entry->root.other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (entry->root.other) != STV_HIDDEN))
{
/* Make a note that we should convert "call" instructions to "calls"
instructions for calls to this symbol. */
byte_count += 2;
/* Count the insn to allocate stack space too. */
- if (entry->stack_size > 0 && entry->stack_size <= 128)
- byte_count += 3;
- else if (entry->stack_size > 0 && entry->stack_size < 256)
- byte_count += 4;
+ if (entry->stack_size > 0)
+ {
+ if (entry->stack_size <= 128)
+ byte_count += 3;
+ else
+ byte_count += 4;
+ }
/* If using "call" will result in larger code, then turn all
- the associated "call" instructions into "calls" instrutions. */
+ the associated "call" instructions into "calls" instructions. */
if (byte_count < entry->direct_calls)
entry->flags |= MN10300_CONVERT_CALL_TO_CALLS;
/* This function handles relaxing for the mn10300.
- There's quite a few relaxing opportunites available on the mn10300:
+ There are quite a few relaxing opportunities available on the mn10300:
* calls:32 -> calls:16 2 bytes
* call:32 -> call:16 2 bytes
/* Get cached copy of section contents if it exists. */
if (elf_section_data (section)->this_hdr.contents != NULL)
contents = elf_section_data (section)->this_hdr.contents;
- else if (section->_raw_size != 0)
+ else if (section->size != 0)
{
/* Go get them off disk. */
- contents = (bfd_byte *) bfd_malloc (section->_raw_size);
- if (contents == NULL)
- goto error_return;
-
- if (!bfd_get_section_contents (input_bfd, section,
- contents, (file_ptr) 0,
- section->_raw_size))
+ if (!bfd_malloc_and_get_section (input_bfd, section,
+ &contents))
goto error_return;
}
else
if (new_name == 0)
goto error_return;
- sprintf (new_name, "%s_%08x",
- sym_name, (int) sym_sec);
+ sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
sym_name = new_name;
elftab = &hash_table->static_hash_table->root;
sec_shndx = _bfd_elf_section_from_bfd_section (input_bfd,
section);
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ hashes = elf_sym_hashes (input_bfd);
+ end_hashes = hashes + symcount;
+
/* Look at each function defined in this section and
update info for that function. */
isymend = isymbuf + symtab_hdr->sh_info;
{
struct elf_link_hash_table *elftab;
bfd_size_type amt;
+ struct elf_link_hash_entry **lhashes = hashes;
+
+ /* Skip a local symbol if it aliases a
+ global one. */
+ for (; lhashes < end_hashes; lhashes++)
+ {
+ hash = (struct elf32_mn10300_link_hash_entry *) *lhashes;
+ if ((hash->root.root.type == bfd_link_hash_defined
+ || hash->root.root.type == bfd_link_hash_defweak)
+ && hash->root.root.u.def.section == section
+ && hash->root.type == STT_FUNC
+ && hash->root.root.u.def.value == isym->st_value)
+ break;
+ }
+ if (lhashes != end_hashes)
+ continue;
if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
if (new_name == 0)
goto error_return;
- sprintf (new_name, "%s_%08x",
- sym_name, (int) sym_sec);
+ sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
sym_name = new_name;
elftab = &hash_table->static_hash_table->root;
}
}
- symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
- - symtab_hdr->sh_info);
- hashes = elf_sym_hashes (input_bfd);
- end_hashes = hashes + symcount;
for (; hashes < end_hashes; hashes++)
{
hash = (struct elf32_mn10300_link_hash_entry *) *hashes;
if ((hash->root.root.type == bfd_link_hash_defined
|| hash->root.root.type == bfd_link_hash_defweak)
&& hash->root.root.u.def.section == section
- && ELF_ST_TYPE (isym->st_info) == STT_FUNC)
+ && hash->root.type == STT_FUNC)
compute_function_info (input_bfd, hash,
(hash)->root.root.u.def.value,
contents);
the final initialization steps on each. */
elf32_mn10300_link_hash_traverse (hash_table,
elf32_mn10300_finish_hash_table_entry,
- NULL);
+ link_info);
elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
elf32_mn10300_finish_hash_table_entry,
- NULL);
+ link_info);
/* All entries in the hash table are fully initialized. */
hash_table->flags |= MN10300_HASH_ENTRIES_INITIALIZED;
unsigned int symcount;
/* Skip non-code sections and empty sections. */
- if ((section->flags & SEC_CODE) == 0 || section->_raw_size == 0)
+ if ((section->flags & SEC_CODE) == 0 || section->size == 0)
continue;
if (section->reloc_count != 0)
else
{
/* Go get them off disk. */
- contents = (bfd_byte *) bfd_malloc (section->_raw_size);
- if (contents == NULL)
- goto error_return;
-
- if (!bfd_get_section_contents (input_bfd, section,
- contents, (file_ptr) 0,
- section->_raw_size))
+ if (!bfd_malloc_and_get_section (input_bfd, section,
+ &contents))
goto error_return;
}
new_name = bfd_malloc (amt);
if (new_name == 0)
goto error_return;
- sprintf (new_name, "%s_%08x", sym_name, (int) sym_sec);
+ sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
sym_name = new_name;
elftab = &hash_table->static_hash_table->root;
if (sym_hash->movm_args)
bytes += 2;
- if (sym_hash->stack_size && sym_hash->stack_size <= 128)
- bytes += 3;
- else if (sym_hash->stack_size
- && sym_hash->stack_size < 256)
- bytes += 4;
+ if (sym_hash->stack_size > 0)
+ {
+ if (sym_hash->stack_size <= 128)
+ bytes += 3;
+ else
+ bytes += 4;
+ }
/* Note that we've deleted prologue bytes for this
function. */
if (sym_hash->movm_args)
bytes += 2;
- if (sym_hash->stack_size && sym_hash->stack_size <= 128)
- bytes += 3;
- else if (sym_hash->stack_size
- && sym_hash->stack_size < 256)
- bytes += 4;
+ if (sym_hash->stack_size > 0)
+ {
+ if (sym_hash->stack_size <= 128)
+ bytes += 3;
+ else
+ bytes += 4;
+ }
/* Note that we've deleted prologue bytes for this
function. */
|| (sec->flags & SEC_CODE) == 0)
return TRUE;
- /* If this is the first time we have been called for this section,
- initialize the cooked size. */
- if (sec->_cooked_size == 0)
- sec->_cooked_size = sec->_raw_size;
-
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* Get a copy of the native relocations. */
else
{
/* Go get them off disk. */
- contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
- if (contents == NULL)
- goto error_return;
-
- if (! bfd_get_section_contents (abfd, sec, contents,
- (file_ptr) 0, sec->_raw_size))
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
goto error_return;
}
}
asection *sym_sec = NULL;
const char *sym_name;
char *new_name;
+ bfd_vma saved_addend;
/* A local symbol. */
isym = isymbuf + ELF32_R_SYM (irel->r_info);
else
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
- symval = (isym->st_value
- + sym_sec->output_section->vma
- + sym_sec->output_offset);
sym_name = bfd_elf_string_from_elf_section (abfd,
symtab_hdr->sh_link,
isym->st_name);
+ if ((sym_sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (isym->st_info) == STT_SECTION
+ && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
+ {
+ saved_addend = irel->r_addend;
+ symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
+ symval += irel->r_addend;
+ irel->r_addend = saved_addend;
+ }
+ else
+ {
+ symval = (isym->st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ }
/* Tack on an ID so we can uniquely identify this
local symbol in the global hash table. */
new_name = bfd_malloc ((bfd_size_type) strlen (sym_name) + 10);
if (new_name == 0)
goto error_return;
- sprintf (new_name, "%s_%08x", sym_name, (int) sym_sec);
+ sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
sym_name = new_name;
h = (struct elf32_mn10300_link_hash_entry *)
splt = bfd_get_section_by_name (elf_hash_table (link_info)
->dynobj, ".plt");
-
+
value = ((splt->output_section->vma
+ splt->output_offset
+ h->root.plt.offset)
value += irel->r_addend;
/* Do nothing if this reloc is the last byte in the section. */
- if (irel->r_offset == sec->_cooked_size)
+ if (irel->r_offset == sec->size)
continue;
/* See if the next instruction is an unconditional pc-relative
/* We can not relax 0x6b, 0x7b, 0x8b, 0x9b as no 24bit
equivalent instructions exists. */
- if (code != 0x6b && code != 0x7b
+ if (code != 0x6b && code != 0x7b
&& code != 0x8b && code != 0x9b
&& ((code & 0x0f) == 0x09 || (code & 0x0f) == 0x08
|| (code & 0x0f) == 0x0a || (code & 0x0f) == 0x0b
|| (code & 0x0f) == 0x0e))
{
/* Not safe if the high bit is on as relaxing may
- move the value out of high mem and thus not fit
- in a signed 8bit value. This is currently over
- conservative. */
+ move the value out of high mem and thus not fit
+ in a signed 8bit value. This is currently over
+ conservative. */
if ((value & 0x80) == 0)
{
/* Note that we've changed the relocation contents,
if (code == 0xfe)
{
- /* Get the second opcode. */
- code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+ /* Get the second opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
/* All the am33 32 -> 24 relaxing possibilities. */
/* We can not relax 0x6b, 0x7b, 0x8b, 0x9b as no 24bit
|| (code & 0x0f) == 0x0e))
{
/* Not safe if the high bit is on as relaxing may
- move the value out of high mem and thus not fit
- in a signed 16bit value. This is currently over
- conservative. */
+ move the value out of high mem and thus not fit
+ in a signed 16bit value. This is currently over
+ conservative. */
if ((value & 0x8000) == 0)
{
/* Note that we've changed the relocation contents,
}
/* Now figure out how much stack space will be allocated by the movm
- instruction. We need this kept separate from the funtion's normal
+ instruction. We need this kept separate from the function's normal
stack space. */
if (hash->movm_args)
{
power larger than the number of bytes we are deleting. */
irelalign = NULL;
- toaddr = sec->_cooked_size;
+ toaddr = sec->size;
irel = elf_section_data (sec)->relocs;
irelend = irel + sec->reloc_count;
/* Actually delete the bytes. */
memmove (contents + addr, contents + addr + count,
(size_t) (toaddr - addr - count));
- sec->_cooked_size -= count;
+ sec->size -= count;
/* Adjust all the relocs. */
for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
- (size_t) input_section->_raw_size);
+ (size_t) input_section->size);
if ((input_section->flags & SEC_RELOC) != 0
&& input_section->reloc_count > 0)
ret->stack_size = 0;
ret->movm_args = 0;
ret->movm_stack_size = 0;
- ret->pcrel_relocs_copied = NULL;
ret->flags = 0;
}
&& bfd_get_mach (obfd) < bfd_get_mach (ibfd))
{
if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
- bfd_get_mach (ibfd)))
- return FALSE;
+ bfd_get_mach (ibfd)))
+ return FALSE;
}
return TRUE;
/* Return offset of the GOT id in PLT0 entry. */
#define elf_mn10300_plt0_gotid_offset(info) 9
-/* Return offset of the tempoline in PLT entry */
+/* Return offset of the temporary in PLT entry */
#define elf_mn10300_plt_temp_offset(info) 8
/* Return offset of the symbol in PLT entry. */
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
- s = bfd_make_section (abfd,
- bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
+ s = bfd_make_section_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt"),
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
strcpy (relname, ".rela");
strcat (relname, secname);
- s = bfd_make_section (abfd, relname);
+ s = bfd_make_section_with_flags (abfd, relname,
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
}
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 (abfd, ".dynbss");
- if (s == NULL
- || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
+ s = bfd_make_section_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ if (s == NULL)
return FALSE;
/* The .rel[a].bss section holds copy relocs. This section is not
copy relocs. */
if (! info->shared)
{
- s = bfd_make_section (abfd,
- (bed->default_use_rela_p
- ? ".rela.bss" : ".rel.bss"));
+ s = bfd_make_section_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, ptralign))
return FALSE;
}
/* Make sure we know what is going on here. */
BFD_ASSERT (dynobj != NULL
- && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
- || h->weakdef != NULL
- || ((h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_DYNAMIC) != 0
- && (h->elf_link_hash_flags
- & ELF_LINK_HASH_REF_REGULAR) != 0
- && (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later,
when we know the address of the .got section. */
if (h->type == STT_FUNC
- || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ || h->needs_plt)
{
if (! info->shared
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
- && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+ && !h->def_dynamic
+ && !h->ref_dynamic)
{
/* This case can occur if we saw a PLT reloc in an input
file, but the symbol was never referred to by a dynamic
object. In such a case, we don't actually need to build
a procedure linkage table, and we can just do a REL32
reloc instead. */
- BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+ BFD_ASSERT (h->needs_plt);
return TRUE;
}
/* Make sure this symbol is output as a dynamic symbol. */
if (h->dynindx == -1)
{
- if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
/* If this is the first .plt entry, make room for the special
first entry. */
- if (s->_raw_size == 0)
- s->_raw_size += elf_mn10300_sizeof_plt0 (info);
+ if (s->size == 0)
+ s->size += elf_mn10300_sizeof_plt0 (info);
/* If this symbol is not defined in a regular file, and we are
not generating a shared library, then set the symbol to this
pointers compare as equal between the normal executable and
the shared library. */
if (! info->shared
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ && !h->def_regular)
{
h->root.u.def.section = s;
- h->root.u.def.value = s->_raw_size;
+ h->root.u.def.value = s->size;
}
- h->plt.offset = s->_raw_size;
+ h->plt.offset = s->size;
/* Make room for this entry. */
- s->_raw_size += elf_mn10300_sizeof_plt (info);
+ s->size += elf_mn10300_sizeof_plt (info);
/* 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");
BFD_ASSERT (s != NULL);
- s->_raw_size += 4;
+ s->size += 4;
/* We also need to make an entry in the .rela.plt section. */
s = bfd_get_section_by_name (dynobj, ".rela.plt");
BFD_ASSERT (s != NULL);
- s->_raw_size += sizeof (Elf32_External_Rela);
+ s->size += sizeof (Elf32_External_Rela);
return TRUE;
}
/* If this is a weak symbol, and there is a real definition, the
processor independent code will have arranged for us to see the
real definition first, and we can just use the same value. */
- if (h->weakdef != NULL)
+ if (h->u.weakdef != NULL)
{
- BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
- || h->weakdef->root.type == bfd_link_hash_defweak);
- h->root.u.def.section = h->weakdef->root.u.def.section;
- h->root.u.def.value = h->weakdef->root.u.def.value;
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
return TRUE;
}
/* If there are no references to this symbol that do not use the
GOT, we don't need to generate a copy reloc. */
- if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
+ if (!h->non_got_ref)
return TRUE;
/* We must allocate the symbol in our .dynbss section, which will
srel = bfd_get_section_by_name (dynobj, ".rela.bss");
BFD_ASSERT (srel != NULL);
- srel->_raw_size += sizeof (Elf32_External_Rela);
- h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
}
/* We need to figure out the alignment required for this symbol. I
power_of_two = 3;
/* Apply the required alignment. */
- s->_raw_size = BFD_ALIGN (s->_raw_size,
- (bfd_size_type) (1 << power_of_two));
+ s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
if (power_of_two > bfd_get_section_alignment (dynobj, s))
{
if (! bfd_set_section_alignment (dynobj, s, power_of_two))
/* Define the symbol as being at this point in the section. */
h->root.u.def.section = s;
- h->root.u.def.value = s->_raw_size;
+ h->root.u.def.value = s->size;
/* Increment the section size to make room for the symbol. */
- s->_raw_size += h->size;
-
- return TRUE;
-}
-
-/* This function is called via elf32_mn10300_link_hash_traverse if we are
- creating a shared object with -Bsymbolic. It discards the space
- allocated to copy PC relative relocs against symbols which are
- defined in regular objects. We allocated space for them in the
- check_relocs routine, but we won't fill them in in the
- relocate_section routine. */
-
-static bfd_boolean
-_bfd_mn10300_elf_discard_copies (h, info)
- struct elf32_mn10300_link_hash_entry *h;
- struct bfd_link_info *info;
-{
- struct elf_mn10300_pcrel_relocs_copied *s;
-
- /* If a symbol has been forced local or we have found a regular
- definition for the symbolic link case, then we won't be needing
- any relocs. */
- if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
- && ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
- || info->symbolic))
- {
- for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
- s->section->_raw_size -= s->count * sizeof (Elf32_External_Rel);
- }
+ s->size += h->size;
return TRUE;
}
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (! info->shared)
+ if (info->executable)
{
s = bfd_get_section_by_name (dynobj, ".interp");
BFD_ASSERT (s != NULL);
- s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
}
}
below. */
s = bfd_get_section_by_name (dynobj, ".rela.got");
if (s != NULL)
- s->_raw_size = 0;
+ s->size = 0;
}
- /* If this is a -Bsymbolic shared link, then we need to discard all
- PC relative relocs against symbols defined in a regular object.
- We allocated space for them in the check_relocs routine, but we
- will not fill them in in the relocate_section routine. */
- if (info->shared && info->symbolic)
- elf32_mn10300_link_hash_traverse (elf32_mn10300_hash_table (info),
- _bfd_mn10300_elf_discard_copies,
- info);
-
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */
if (strcmp (name, ".plt") == 0)
{
- if (s->_raw_size == 0)
+ if (s->size == 0)
/* Strip this section if we don't need it; see the
comment below. */
strip = TRUE;
}
else if (strncmp (name, ".rela", 5) == 0)
{
- if (s->_raw_size == 0)
+ if (s->size == 0)
{
/* If we don't need this section, strip it from the
output file. This is mostly to handle .rela.bss and
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
section's contents are written out. This should not happen,
but this way if it does, we get a R_MN10300_NONE reloc
instead of garbage. */
- s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
- if (s->contents == NULL && s->_raw_size != 0)
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL && s->size != 0)
return FALSE;
}
in by the dynamic linker and used by the debugger. */
if (! info->shared)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
return FALSE;
}
if (plt)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
- || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
return FALSE;
}
if (relocs)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
- sizeof (Elf32_External_Rela)))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
return FALSE;
}
if (reltext)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
return FALSE;
}
}
(bfd_byte *) ((Elf32_External_Rela *) srel->contents
+ plt_index));
- if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ if (!h->def_regular)
/* Mark the symbol as undefined, rather than as defined in
the .plt section. Leave the value alone. */
sym->st_shndx = SHN_UNDEF;
initialized in the relocate_section function. */
if (info->shared
&& (info->symbolic || h->dynindx == -1)
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ && h->def_regular)
{
rel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE);
rel.r_addend = (h->root.u.def.value
++ srel->reloc_count;
}
- if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+ if (h->needs_copy)
{
asection * s;
Elf_Internal_Rela rel;
BFD_ASSERT (sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
- dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
for (; dyncon < dynconend; dyncon++)
{
case DT_PLTRELSZ:
s = bfd_get_section_by_name (output_bfd, ".rela.plt");
BFD_ASSERT (s != NULL);
- if (s->_cooked_size != 0)
- dyn.d_un.d_val = s->_cooked_size;
- else
- dyn.d_un.d_val = s->_raw_size;
+ dyn.d_un.d_val = s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
about changing the DT_RELA entry. */
s = bfd_get_section_by_name (output_bfd, ".rela.plt");
if (s != NULL)
- {
- if (s->_cooked_size != 0)
- dyn.d_un.d_val -= s->_cooked_size;
- else
- dyn.d_un.d_val -= s->_raw_size;
- }
+ dyn.d_un.d_val -= s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
}
/* Fill in the first entry in the procedure linkage table. */
splt = bfd_get_section_by_name (dynobj, ".plt");
- if (splt && splt->_raw_size > 0)
+ if (splt && splt->size > 0)
{
if (info->shared)
{
}
/* Fill in the first three entries in the global offset table. */
- if (sgot->_raw_size > 0)
+ if (sgot->size > 0)
{
if (sdyn == NULL)
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
return TRUE;
}
+/* Classify relocation types, such that combreloc can sort them
+ properly. */
+
+static enum elf_reloc_type_class
+_bfd_mn10300_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_MN10300_RELATIVE:
+ return reloc_class_relative;
+ case R_MN10300_JMP_SLOT:
+ return reloc_class_plt;
+ case R_MN10300_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
#ifndef ELF_ARCH
#define TARGET_LITTLE_SYM bfd_elf32_mn10300_vec
#define TARGET_LITTLE_NAME "elf32-mn10300"
/* So we can set bits in e_flags. */
#define elf_backend_final_write_processing \
- _bfd_mn10300_elf_final_write_processing
-#define elf_backend_object_p _bfd_mn10300_elf_object_p
+ _bfd_mn10300_elf_final_write_processing
+#define elf_backend_object_p _bfd_mn10300_elf_object_p
#define bfd_elf32_bfd_merge_private_bfd_data \
- _bfd_mn10300_elf_merge_private_bfd_data
+ _bfd_mn10300_elf_merge_private_bfd_data
#define elf_backend_can_gc_sections 1
#define elf_backend_create_dynamic_sections \
#define elf_backend_finish_dynamic_sections \
_bfd_mn10300_elf_finish_dynamic_sections
+#define elf_backend_reloc_type_class \
+ _bfd_mn10300_elf_reloc_type_class
+
#define elf_backend_want_got_plt 1
#define elf_backend_plt_readonly 1
#define elf_backend_want_plt_sym 0