diff options
Diffstat (limited to 'bfd/elf32-m32c.c')
-rw-r--r-- | bfd/elf32-m32c.c | 161 |
1 files changed, 56 insertions, 105 deletions
diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c index 5e9f3ab28a21..43499cec01c2 100644 --- a/bfd/elf32-m32c.c +++ b/bfd/elf32-m32c.c @@ -1,5 +1,5 @@ /* M16C/M32C specific support for 32-bit ELF. - Copyright (C) 2005, 2006 + Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -18,8 +18,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "elf-bfd.h" #include "elf/m32c.h" @@ -32,15 +32,12 @@ static void m32c_info_to_howto_rela (bfd *, arelent *, Elf_Internal_Rela *); static bfd_boolean m32c_elf_relocate_section (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); -static bfd_boolean m32c_elf_gc_sweep_hook - (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); -static asection * m32c_elf_gc_mark_hook - (asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *); static bfd_boolean m32c_elf_check_relocs (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int); #ifdef DEBUG -static char * m32c_get_reloc (long reloc); +char * m32c_get_reloc (long reloc); +void dump_symtab (bfd *, void *, void *); #endif static bfd_boolean m32c_elf_relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again); @@ -63,13 +60,16 @@ static reloc_howto_type m32c_elf_howto_table [] = 0, /* dst_mask */ FALSE), /* pcrel_offset */ + /* GCC intentionally overflows these next two in order to work + around limitations in the addressing modes, so don't complain + about overflow. */ HOWTO (R_M32C_16, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ + complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_M32C_16", /* name */ FALSE, /* partial_inplace */ @@ -83,7 +83,7 @@ static reloc_howto_type m32c_elf_howto_table [] = 24, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ + complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_M32C_24", /* name */ FALSE, /* partial_inplace */ @@ -272,6 +272,21 @@ m32c_reloc_type_lookup return NULL; } +static reloc_howto_type * +m32c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < sizeof (m32c_elf_howto_table) / sizeof (m32c_elf_howto_table[0]); + i++) + if (m32c_elf_howto_table[i].name != NULL + && strcasecmp (m32c_elf_howto_table[i].name, r_name) == 0) + return &m32c_elf_howto_table[i]; + + return NULL; +} + /* Set the howto pointer for an M32C ELF reloc. */ static void @@ -372,31 +387,11 @@ m32c_elf_relocate_section r_symndx = ELF32_R_SYM (rel->r_info); - if (info->relocatable) - { - /* This is a relocatable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections [r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - - /* This is a final link. */ howto = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info); h = NULL; sym = NULL; sec = NULL; + relocation = 0; if (r_symndx < symtab_hdr->sh_info) { @@ -429,19 +424,38 @@ m32c_elf_relocate_section + sec->output_offset); } else if (h->root.type == bfd_link_hash_undefweak) - { - relocation = 0; - } - else + ; + else if (!info->relocatable) { if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, input_section, rel->r_offset, TRUE))) return FALSE; - relocation = 0; } } + 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 (info->relocatable) + { + /* This is a relocatable link. We don't have to change + anything, unless the reloc is against a section symbol, + in which case we have to adjust according to where the + section symbol winds up in the output section. */ + if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + rel->r_addend += sec->output_offset; + continue; + } + switch (ELF32_R_TYPE (rel->r_info)) { case R_M32C_16: @@ -571,62 +585,6 @@ m32c_elf_relocate_section return TRUE; } -/* Return the section that should be marked against GC for a given - relocation. */ - -static asection * -m32c_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; -} - -/* Update the got entry reference counts for the section being removed. */ - -static bfd_boolean -m32c_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) -{ - return TRUE; -} - /* We support 16-bit pointers to code above 64k by generating a thunk below 64k containing a JMP instruction to the final address. */ @@ -690,16 +648,11 @@ m32c_elf_check_relocs splt = bfd_get_section_by_name (dynobj, ".plt"); if (splt == NULL) { - splt = bfd_make_section (dynobj, ".plt"); + flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS + | SEC_IN_MEMORY | SEC_LINKER_CREATED + | SEC_READONLY | SEC_CODE); + splt = bfd_make_section_with_flags (dynobj, ".plt", flags); if (splt == NULL - || ! bfd_set_section_flags (dynobj, splt, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY - | SEC_CODE)) || ! bfd_set_section_alignment (dynobj, splt, 1)) return FALSE; } @@ -936,7 +889,7 @@ m32c_elf_object_p (bfd *abfd) #ifdef DEBUG -static void +void dump_symtab (bfd * abfd, void *internal_syms, void *external_syms) { size_t locsymcount; @@ -977,7 +930,6 @@ dump_symtab (bfd * abfd, void *internal_syms, void *external_syms) { case STT_FUNC: st_info_str = "STT_FUNC"; case STT_SECTION: st_info_str = "STT_SECTION"; - case STT_SRELC: st_info_str = "STT_SRELC"; case STT_FILE: st_info_str = "STT_FILE"; case STT_OBJECT: st_info_str = "STT_OBJECT"; case STT_TLS: st_info_str = "STT_TLS"; @@ -1022,7 +974,7 @@ dump_symtab (bfd * abfd, void *internal_syms, void *external_syms) free (external_syms); } -static char * +char * m32c_get_reloc (long reloc) { if (0 <= reloc && reloc < R_M32C_max) @@ -2055,8 +2007,6 @@ m32c_elf_relax_delete_bytes #define elf_info_to_howto m32c_info_to_howto_rela #define elf_backend_object_p m32c_elf_object_p #define elf_backend_relocate_section m32c_elf_relocate_section -#define elf_backend_gc_mark_hook m32c_elf_gc_mark_hook -#define elf_backend_gc_sweep_hook m32c_elf_gc_sweep_hook #define elf_backend_check_relocs m32c_elf_check_relocs #define elf_backend_object_p m32c_elf_object_p #define elf_symbol_leading_char ('_') @@ -2068,6 +2018,7 @@ m32c_elf_relax_delete_bytes #define elf_backend_can_gc_sections 1 #define bfd_elf32_bfd_reloc_type_lookup m32c_reloc_type_lookup +#define bfd_elf32_bfd_reloc_name_lookup m32c_reloc_name_lookup #define bfd_elf32_bfd_relax_section m32c_elf_relax_section #define bfd_elf32_bfd_set_private_flags m32c_elf_set_private_flags #define bfd_elf32_bfd_merge_private_bfd_data m32c_elf_merge_private_bfd_data |