X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=bfd%2Felf-m10300.c;h=794d329fe80be3f7f24120dddece95d80cc9c3ae;hp=2b309e5af98aba66f13d79946238bc3fb53f0c66;hb=88750007d7869f178f0ba528f41efd3b74c424cf;hpb=6df9443a374e2b81278c61b8afc0a1eef7db280b diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 2b309e5..794d329 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -1,6 +1,6 @@ /* Matsushita 10300 specific support for 32-bit ELF Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007 Free Software Foundation, Inc. + 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -24,28 +24,7 @@ #include "libbfd.h" #include "elf-bfd.h" #include "elf/mn10300.h" - -static bfd_reloc_status_type mn10300_elf_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, - bfd_vma, bfd_vma, bfd_vma, - struct elf_link_hash_entry *, unsigned long, struct bfd_link_info *, - asection *, int)); -static bfd_boolean mn10300_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static bfd_boolean mn10300_elf_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *)); -static bfd_byte * mn10300_elf_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, bfd_boolean, asymbol **)); -static unsigned long elf_mn10300_mach - PARAMS ((flagword)); -void _bfd_mn10300_elf_final_write_processing - PARAMS ((bfd *, bfd_boolean)); -bfd_boolean _bfd_mn10300_elf_object_p - PARAMS ((bfd *)); -bfd_boolean _bfd_mn10300_elf_merge_private_bfd_data - PARAMS ((bfd *,bfd *)); +#include "libiberty.h" /* The mn10300 linker needs to keep track of the number of relocs that it decides to copy in check_relocs for each symbol. This is so @@ -53,7 +32,8 @@ bfd_boolean _bfd_mn10300_elf_merge_private_bfd_data linking with -Bsymbolic. We store the information in a field extending the regular ELF linker hash table. */ -struct elf32_mn10300_link_hash_entry { +struct elf32_mn10300_link_hash_entry +{ /* The basic elf link hash table entry. */ struct elf_link_hash_entry root; @@ -94,7 +74,8 @@ struct elf32_mn10300_link_hash_entry { /* 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_mn10300_link_hash_table { +struct elf32_mn10300_link_hash_table +{ /* The main hash table. */ struct elf_link_hash_table root; @@ -108,6 +89,10 @@ struct elf32_mn10300_link_hash_table { char flags; }; +#ifndef streq +#define streq(a, b) (strcmp ((a),(b)) == 0) +#endif + /* For MN10300 linker hash table. */ /* Get the MN10300 ELF linker hash table from a link_info structure. */ @@ -118,48 +103,11 @@ struct elf32_mn10300_link_hash_table { #define elf32_mn10300_link_hash_traverse(table, func, info) \ (elf_link_hash_traverse \ (&(table)->root, \ - (bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ + (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ (info))) -static struct bfd_hash_entry *elf32_mn10300_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *elf32_mn10300_link_hash_table_create - PARAMS ((bfd *)); -static void elf32_mn10300_link_hash_table_free - PARAMS ((struct bfd_link_hash_table *)); - -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void mn10300_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_boolean mn10300_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean mn10300_elf_relax_delete_bytes - PARAMS ((bfd *, asection *, bfd_vma, int)); -static bfd_boolean mn10300_elf_symbol_address_p - PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma)); -static bfd_boolean elf32_mn10300_finish_hash_table_entry - PARAMS ((struct bfd_hash_entry *, PTR)); -static void compute_function_info - PARAMS ((bfd *, struct elf32_mn10300_link_hash_entry *, - bfd_vma, unsigned char *)); - -static bfd_boolean _bfd_mn10300_elf_create_got_section - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean _bfd_mn10300_elf_create_dynamic_sections - 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_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean _bfd_mn10300_elf_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static bfd_boolean _bfd_mn10300_elf_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -static reloc_howto_type elf_mn10300_howto_table[] = { +static reloc_howto_type elf_mn10300_howto_table[] = +{ /* Dummy relocation. Does nothing. */ HOWTO (R_MN10300_NONE, 0, @@ -259,7 +207,7 @@ static reloc_howto_type elf_mn10300_howto_table[] = { 0xff, TRUE), - /* GNU extension to record C++ vtable hierarchy */ + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_MN10300_GNU_VTINHERIT, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ @@ -499,14 +447,53 @@ static reloc_howto_type elf_mn10300_howto_table[] = { 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ + EMPTY_HOWTO (24), + EMPTY_HOWTO (25), + EMPTY_HOWTO (26), + EMPTY_HOWTO (27), + EMPTY_HOWTO (28), + EMPTY_HOWTO (29), + EMPTY_HOWTO (30), + EMPTY_HOWTO (31), + EMPTY_HOWTO (32), + + HOWTO (R_MN10300_SYM_DIFF, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + NULL, /* special handler. */ + "R_MN10300_SYM_DIFF", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_MN10300_ALIGN, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + NULL, /* special handler. */ + "R_MN10300_ALIGN", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE) /* pcrel_offset */ }; -struct mn10300_reloc_map { +struct mn10300_reloc_map +{ bfd_reloc_code_real_type bfd_reloc_val; unsigned char elf_reloc_val; }; -static const struct mn10300_reloc_map mn10300_reloc_map[] = { +static const struct mn10300_reloc_map mn10300_reloc_map[] = +{ { BFD_RELOC_NONE, R_MN10300_NONE, }, { BFD_RELOC_32, R_MN10300_32, }, { BFD_RELOC_16, R_MN10300_16, }, @@ -531,14 +518,15 @@ static const struct mn10300_reloc_map mn10300_reloc_map[] = { { BFD_RELOC_MN10300_GLOB_DAT, R_MN10300_GLOB_DAT }, { BFD_RELOC_MN10300_JMP_SLOT, R_MN10300_JMP_SLOT }, { BFD_RELOC_MN10300_RELATIVE, R_MN10300_RELATIVE }, + { BFD_RELOC_MN10300_SYM_DIFF, R_MN10300_SYM_DIFF }, + { BFD_RELOC_MN10300_ALIGN, R_MN10300_ALIGN } }; /* Create the GOT section. */ static bfd_boolean -_bfd_mn10300_elf_create_got_section (abfd, info) - bfd * abfd; - struct bfd_link_info * info; +_bfd_mn10300_elf_create_got_section (bfd * abfd, + struct bfd_link_info * info) { flagword flags; flagword pltflags; @@ -621,19 +609,14 @@ _bfd_mn10300_elf_create_got_section (abfd, info) } static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; - for (i = 0; - i < sizeof (mn10300_reloc_map) / sizeof (struct mn10300_reloc_map); - i++) - { - if (mn10300_reloc_map[i].bfd_reloc_val == code) - return &elf_mn10300_howto_table[mn10300_reloc_map[i].elf_reloc_val]; - } + for (i = ARRAY_SIZE (mn10300_reloc_map); i--;) + if (mn10300_reloc_map[i].bfd_reloc_val == code) + return &elf_mn10300_howto_table[mn10300_reloc_map[i].elf_reloc_val]; return NULL; } @@ -644,13 +627,10 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, { unsigned int i; - for (i = 0; - i < (sizeof (elf_mn10300_howto_table) - / sizeof (elf_mn10300_howto_table[0])); - i++) + for (i = ARRAY_SIZE (elf_mn10300_howto_table); i--;) if (elf_mn10300_howto_table[i].name != NULL && strcasecmp (elf_mn10300_howto_table[i].name, r_name) == 0) - return &elf_mn10300_howto_table[i]; + return elf_mn10300_howto_table + i; return NULL; } @@ -658,16 +638,15 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, /* Set the howto pointer for an MN10300 ELF reloc. */ static void -mn10300_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +mn10300_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type; r_type = ELF32_R_TYPE (dst->r_info); BFD_ASSERT (r_type < (unsigned int) R_MN10300_MAX); - cache_ptr->howto = &elf_mn10300_howto_table[r_type]; + cache_ptr->howto = elf_mn10300_howto_table + r_type; } /* Look through the relocs for a section during the first phase. @@ -675,14 +654,15 @@ mn10300_info_to_howto (abfd, cache_ptr, dst) virtual table relocs for gc. */ static bfd_boolean -mn10300_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +mn10300_elf_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { + bfd_boolean sym_diff_reloc_seen; Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; + Elf_Internal_Sym * isymbuf = NULL; + struct elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; bfd * dynobj; @@ -690,6 +670,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) asection * sgot; asection * srelgot; asection * sreloc; + bfd_boolean result = FALSE; sgot = NULL; srelgot = NULL; @@ -699,18 +680,19 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) return TRUE; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; sym_hashes = elf_sym_hashes (abfd); - sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym); - if (!elf_bad_symtab (abfd)) - sym_hashes_end -= symtab_hdr->sh_info; dynobj = elf_hash_table (info)->dynobj; local_got_offsets = elf_local_got_offsets (abfd); rel_end = relocs + sec->reloc_count; + sym_diff_reloc_seen = FALSE; + for (rel = relocs; rel < rel_end; rel++) { struct elf_link_hash_entry *h; unsigned long r_symndx; + unsigned int r_type; r_symndx = ELF32_R_SYM (rel->r_info); if (r_symndx < symtab_hdr->sh_info) @@ -723,10 +705,12 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) h = (struct elf_link_hash_entry *) h->root.u.i.link; } + r_type = ELF32_R_TYPE (rel->r_info); + /* Some relocs require a global offset table. */ if (dynobj == NULL) { - switch (ELF32_R_TYPE (rel->r_info)) + switch (r_type) { case R_MN10300_GOT32: case R_MN10300_GOT24: @@ -738,7 +722,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) case R_MN10300_GOTPC16: elf_hash_table (info)->dynobj = dynobj = abfd; if (! _bfd_mn10300_elf_create_got_section (dynobj, info)) - return FALSE; + goto fail; break; default: @@ -746,21 +730,24 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) } } - switch (ELF32_R_TYPE (rel->r_info)) + switch (r_type) { /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_MN10300_GNU_VTINHERIT: if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) - return FALSE; + goto fail; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_MN10300_GNU_VTENTRY: - if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) - return FALSE; + BFD_ASSERT (h != NULL); + if (h != NULL + && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + goto fail; break; + case R_MN10300_GOT32: case R_MN10300_GOT24: case R_MN10300_GOT16: @@ -788,7 +775,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) | SEC_READONLY)); if (srelgot == NULL || ! bfd_set_section_alignment (dynobj, srelgot, 2)) - return FALSE; + goto fail; } } @@ -804,7 +791,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) if (h->dynindx == -1) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; + goto fail; } srelgot->size += sizeof (Elf32_External_Rela); @@ -819,10 +806,11 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) unsigned int i; size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); + local_got_offsets = bfd_alloc (abfd, size); if (local_got_offsets == NULL) - return FALSE; + goto fail; + elf_local_got_offsets (abfd) = local_got_offsets; for (i = 0; i < symtab_hdr->sh_info; i++) @@ -843,7 +831,6 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) } sgot->size += 4; - break; case R_MN10300_PLT32: @@ -865,7 +852,6 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) break; h->needs_plt = 1; - break; case R_MN10300_24: @@ -878,59 +864,82 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) h->non_got_ref = 1; break; + case R_MN10300_SYM_DIFF: + sym_diff_reloc_seen = TRUE; + 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 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) + && (sec->flags & SEC_ALLOC) != 0 + /* Do not generate a dynamic reloc for a + reloc associated with a SYM_DIFF operation. */ + && ! sym_diff_reloc_seen) { - /* When creating a shared object, we must copy these - reloc types into the output file. We create a reloc - section in dynobj and make room for this reloc. */ - if (sreloc == NULL) - { - const char * name; + asection * sym_section = NULL; - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; + /* Find the section containing the + symbol involved in the relocation. */ + if (h == NULL) + { + Elf_Internal_Sym * isym; - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, + NULL, NULL, NULL); + if (isymbuf) + { + isym = isymbuf + r_symndx; + /* All we care about is whether this local symbol is absolute. */ + if (isym->st_shndx == SHN_ABS) + sym_section = bfd_abs_section_ptr; + } + } + else + { + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + sym_section = h->root.u.def.section; + } - sreloc = bfd_get_section_by_name (dynobj, name); + /* If the symbol is absolute then the relocation can + be resolved during linking and there is no need for + a dynamic reloc. */ + if (sym_section != bfd_abs_section_ptr) + { + /* When creating a shared object, we must copy these + reloc types into the output file. We create a reloc + section in dynobj and make room for this reloc. */ if (sreloc == NULL) { - flagword flags; - - 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_alignment (dynobj, sreloc, 2)) - return FALSE; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); + if (sreloc == NULL) + goto fail; } - } - sreloc->size += sizeof (Elf32_External_Rela); + sreloc->size += sizeof (Elf32_External_Rela); + } } break; } + + if (ELF32_R_TYPE (rel->r_info) != R_MN10300_SYM_DIFF) + sym_diff_reloc_seen = FALSE; } - return TRUE; + result = TRUE; + fail: + if (isymbuf != NULL) + free (isymbuf); + + return result; } /* Return the section that should be marked against GC for a given @@ -955,26 +964,27 @@ mn10300_elf_gc_mark_hook (asection *sec, } /* Perform a relocation as part of a final link. */ + static bfd_reloc_status_type -mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, - input_section, contents, offset, value, - addend, h, symndx, info, sym_sec, is_local) - reloc_howto_type *howto; - bfd *input_bfd; - bfd *output_bfd ATTRIBUTE_UNUSED; - asection *input_section; - bfd_byte *contents; - bfd_vma offset; - bfd_vma value; - bfd_vma addend; - struct elf_link_hash_entry * h; - unsigned long symndx; - struct bfd_link_info *info; - asection *sym_sec ATTRIBUTE_UNUSED; - int is_local ATTRIBUTE_UNUSED; +mn10300_elf_final_link_relocate (reloc_howto_type *howto, + bfd *input_bfd, + bfd *output_bfd ATTRIBUTE_UNUSED, + asection *input_section, + bfd_byte *contents, + bfd_vma offset, + bfd_vma value, + bfd_vma addend, + struct elf_link_hash_entry * h, + unsigned long symndx, + struct bfd_link_info *info, + asection *sym_sec ATTRIBUTE_UNUSED, + int is_local ATTRIBUTE_UNUSED) { + static asection * sym_diff_section; + static bfd_vma sym_diff_value; + bfd_boolean is_sym_diff_reloc; unsigned long r_type = howto->type; - bfd_byte *hit_data = contents + offset; + bfd_byte * hit_data = contents + offset; bfd * dynobj; bfd_vma * local_got_offsets; asection * sgot; @@ -1006,13 +1016,66 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, return bfd_reloc_dangerous; } + is_sym_diff_reloc = FALSE; + if (sym_diff_section != NULL) + { + BFD_ASSERT (sym_diff_section == input_section); + + switch (r_type) + { + case R_MN10300_32: + case R_MN10300_24: + case R_MN10300_16: + case R_MN10300_8: + value -= sym_diff_value; + /* If we are computing a 32-bit value for the location lists + and the result is 0 then we add one to the value. A zero + value can result because of linker relaxation deleteing + prologue instructions and using a value of 1 (for the begin + and end offsets in the location list entry) results in a + nul entry which does not prevent the following entries from + being parsed. */ + if (r_type == R_MN10300_32 + && value == 0 + && strcmp (input_section->name, ".debug_loc") == 0) + value = 1; + sym_diff_section = NULL; + is_sym_diff_reloc = TRUE; + break; + + default: + sym_diff_section = NULL; + break; + } + } + switch (r_type) { + case R_MN10300_SYM_DIFF: + BFD_ASSERT (addend == 0); + /* Cache the input section and value. + The offset is unreliable, since relaxation may + have reduced the following reloc's offset. */ + sym_diff_section = input_section; + sym_diff_value = value; + return bfd_reloc_ok; + + case R_MN10300_ALIGN: case R_MN10300_NONE: return bfd_reloc_ok; case R_MN10300_32: if (info->shared + /* Do not generate relocs when an R_MN10300_32 has been used + with an R_MN10300_SYM_DIFF to compute a difference of two + symbols. */ + && is_sym_diff_reloc == FALSE + /* Also, do not generate a reloc when the symbol associated + with the R_MN10300_32 reloc is absolute - there is no + need for a run time computation in this case. */ + && sym_sec != bfd_abs_section_ptr + /* If the section is not going to be allocated at load time + then there is no need to generate relocs for it. */ && (input_section->flags & SEC_ALLOC) != 0) { Elf_Internal_Rela outrel; @@ -1023,22 +1086,10 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, 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) + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && 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; @@ -1127,7 +1178,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, value -= offset; value += addend; - if ((long) value > 0xff || (long) value < -0x100) + if ((long) value > 0x7f || (long) value < -0x80) return bfd_reloc_overflow; bfd_put_8 (input_bfd, value, hit_data); @@ -1139,7 +1190,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, value -= offset; value += addend; - if ((long) value > 0xffff || (long) value < -0x10000) + if ((long) value > 0x7fff || (long) value < -0x8000) return bfd_reloc_overflow; bfd_put_16 (input_bfd, value, hit_data); @@ -1160,7 +1211,6 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, case R_MN10300_GOTPC32: /* Use global offset table as symbol value. */ - value = bfd_get_section_by_name (dynobj, ".got")->output_section->vma; value -= (input_section->output_section->vma @@ -1173,7 +1223,6 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, case R_MN10300_GOTPC16: /* Use global offset table as symbol value. */ - value = bfd_get_section_by_name (dynobj, ".got")->output_section->vma; value -= (input_section->output_section->vma @@ -1181,7 +1230,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, value -= offset; value += addend; - if ((long) value > 0xffff || (long) value < -0x10000) + if ((long) value > 0x7fff || (long) value < -0x8000) return bfd_reloc_overflow; bfd_put_16 (input_bfd, value, hit_data); @@ -1213,7 +1262,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, ".got")->output_section->vma; value += addend; - if ((long) value > 0xffff || (long) value < -0x10000) + if ((long) value > 0x7fff || (long) value < -0x8000) return bfd_reloc_overflow; bfd_put_16 (input_bfd, value, hit_data); @@ -1262,7 +1311,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, value -= offset; value += addend; - if ((long) value > 0xffff || (long) value < -0x10000) + if ((long) value > 0x7fff || (long) value < -0x8000) return bfd_reloc_overflow; bfd_put_16 (input_bfd, value, hit_data); @@ -1350,7 +1399,7 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, } else if (r_type == R_MN10300_GOT16) { - if ((long) value > 0xffff || (long) value < -0x10000) + if ((long) value > 0x7fff || (long) value < -0x8000) return bfd_reloc_overflow; bfd_put_16 (input_bfd, value, hit_data); @@ -1364,17 +1413,16 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, } /* Relocate an MN10300 ELF section. */ + static bfd_boolean -mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +mn10300_elf_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1442,6 +1490,10 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section, && elf_hash_table (info)->dynamic_sections_created && !SYMBOL_REFERENCES_LOCAL (info, hh)) || (r_type == R_MN10300_32 + /* _32 relocs in executables force _COPY relocs, + such that the address of the symbol ends up + being local. */ + && !info->executable && !SYMBOL_REFERENCES_LOCAL (info, hh) && ((input_section->flags & SEC_ALLOC) != 0 /* DWARF will emit R_MN10300_32 relocations @@ -1483,14 +1535,14 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section, input_section, contents, rel->r_offset, relocation, rel->r_addend, - (struct elf_link_hash_entry *)h, + (struct elf_link_hash_entry *) h, r_symndx, info, sec, h == NULL); if (r != bfd_reloc_ok) { const char *name; - const char *msg = (const char *) 0; + const char *msg = NULL; if (h != NULL) name = h->root.root.root.string; @@ -1538,7 +1590,7 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section, default: msg = _("internal error: unknown error"); - /* fall through */ + /* Fall through. */ common_error: if (!((*info->callbacks->warning) @@ -1554,13 +1606,13 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section, } /* Finish initializing one hash table entry. */ + static bfd_boolean -elf32_mn10300_finish_hash_table_entry (gen_entry, in_args) - struct bfd_hash_entry *gen_entry; - PTR in_args; +elf32_mn10300_finish_hash_table_entry (struct bfd_hash_entry *gen_entry, + void * in_args) { struct elf32_mn10300_link_hash_entry *entry; - struct bfd_link_info *link_info = (struct bfd_link_info *)in_args; + 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; @@ -1618,20 +1670,22 @@ elf32_mn10300_finish_hash_table_entry (gen_entry, in_args) } /* Used to count hash table entries. */ + static bfd_boolean elf32_mn10300_count_hash_table_entries (struct bfd_hash_entry *gen_entry ATTRIBUTE_UNUSED, - PTR in_args) + void * in_args) { - int *count = (int *)in_args; + int *count = (int *) in_args; (*count) ++; return TRUE; } /* Used to enumerate hash table entries into a linear array. */ + static bfd_boolean elf32_mn10300_list_hash_table_entries (struct bfd_hash_entry *gen_entry, - PTR in_args) + void * in_args) { struct bfd_hash_entry ***ptr = (struct bfd_hash_entry ***) in_args; @@ -1641,17 +1695,329 @@ elf32_mn10300_list_hash_table_entries (struct bfd_hash_entry *gen_entry, } /* Used to sort the array created by the above. */ + static int sort_by_value (const void *va, const void *vb) { struct elf32_mn10300_link_hash_entry *a - = *(struct elf32_mn10300_link_hash_entry **)va; + = *(struct elf32_mn10300_link_hash_entry **) va; struct elf32_mn10300_link_hash_entry *b - = *(struct elf32_mn10300_link_hash_entry **)vb; + = *(struct elf32_mn10300_link_hash_entry **) vb; + + return a->value - b->value; +} + +/* Compute the stack size and movm arguments for the function + referred to by HASH at address ADDR in section with + contents CONTENTS, store the information in the hash table. */ + +static void +compute_function_info (bfd *abfd, + struct elf32_mn10300_link_hash_entry *hash, + bfd_vma addr, + unsigned char *contents) +{ + unsigned char byte1, byte2; + /* We only care about a very small subset of the possible prologue + sequences here. Basically we look for: + + movm [d2,d3,a2,a3],sp (optional) + add ,sp (optional, and only for sizes which fit in an unsigned + 8 bit number) + + If we find anything else, we quit. */ + + /* Look for movm [regs],sp. */ + byte1 = bfd_get_8 (abfd, contents + addr); + byte2 = bfd_get_8 (abfd, contents + addr + 1); + + if (byte1 == 0xcf) + { + hash->movm_args = byte2; + addr += 2; + byte1 = bfd_get_8 (abfd, contents + addr); + byte2 = bfd_get_8 (abfd, contents + addr + 1); + } + + /* Now figure out how much stack space will be allocated by the movm + instruction. We need this kept separate from the function's normal + stack space. */ + if (hash->movm_args) + { + /* Space for d2. */ + if (hash->movm_args & 0x80) + hash->movm_stack_size += 4; + + /* Space for d3. */ + if (hash->movm_args & 0x40) + hash->movm_stack_size += 4; + + /* Space for a2. */ + if (hash->movm_args & 0x20) + hash->movm_stack_size += 4; + + /* Space for a3. */ + if (hash->movm_args & 0x10) + hash->movm_stack_size += 4; + + /* "other" space. d0, d1, a0, a1, mdr, lir, lar, 4 byte pad. */ + if (hash->movm_args & 0x08) + hash->movm_stack_size += 8 * 4; + + if (bfd_get_mach (abfd) == bfd_mach_am33 + || bfd_get_mach (abfd) == bfd_mach_am33_2) + { + /* "exother" space. e0, e1, mdrq, mcrh, mcrl, mcvf */ + if (hash->movm_args & 0x1) + hash->movm_stack_size += 6 * 4; + + /* exreg1 space. e4, e5, e6, e7 */ + if (hash->movm_args & 0x2) + hash->movm_stack_size += 4 * 4; + + /* exreg0 space. e2, e3 */ + if (hash->movm_args & 0x4) + hash->movm_stack_size += 2 * 4; + } + } + + /* Now look for the two stack adjustment variants. */ + if (byte1 == 0xf8 && byte2 == 0xfe) + { + int temp = bfd_get_8 (abfd, contents + addr + 2); + temp = ((temp & 0xff) ^ (~0x7f)) + 0x80; + + hash->stack_size = -temp; + } + else if (byte1 == 0xfa && byte2 == 0xfe) + { + int temp = bfd_get_16 (abfd, contents + addr + 2); + temp = ((temp & 0xffff) ^ (~0x7fff)) + 0x8000; + temp = -temp; + + if (temp < 255) + hash->stack_size = temp; + } + + /* If the total stack to be allocated by the call instruction is more + than 255 bytes, then we can't remove the stack adjustment by using + "call" (we might still be able to remove the "movm" instruction. */ + if (hash->stack_size + hash->movm_stack_size > 255) + hash->stack_size = 0; +} + +/* Delete some bytes from a section while relaxing. */ + +static bfd_boolean +mn10300_elf_relax_delete_bytes (bfd *abfd, + asection *sec, + bfd_vma addr, + int count) +{ + Elf_Internal_Shdr *symtab_hdr; + unsigned int sec_shndx; + bfd_byte *contents; + Elf_Internal_Rela *irel, *irelend; + Elf_Internal_Rela *irelalign; + bfd_vma toaddr; + Elf_Internal_Sym *isym, *isymend; + struct elf_link_hash_entry **sym_hashes; + struct elf_link_hash_entry **end_hashes; + unsigned int symcount; + + sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); + + contents = elf_section_data (sec)->this_hdr.contents; + + irelalign = NULL; + toaddr = sec->size; + + irel = elf_section_data (sec)->relocs; + irelend = irel + sec->reloc_count; + + if (sec->reloc_count > 0) + { + /* If there is an align reloc at the end of the section ignore it. + GAS creates these relocs for reasons of its own, and they just + serve to keep the section artifically inflated. */ + if (ELF32_R_TYPE ((irelend - 1)->r_info) == (int) R_MN10300_ALIGN) + --irelend; + + /* The deletion must stop at the next ALIGN reloc for an aligment + power larger than, or not a multiple of, the number of bytes we + are deleting. */ + for (; irel < irelend; irel++) + { + int alignment = 1 << irel->r_addend; + + if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN + && irel->r_offset > addr + && irel->r_offset < toaddr + && (count < alignment + || alignment % count != 0)) + { + irelalign = irel; + toaddr = irel->r_offset; + break; + } + } + } + + /* Actually delete the bytes. */ + memmove (contents + addr, contents + addr + count, + (size_t) (toaddr - addr - count)); + + /* Adjust the section's size if we are shrinking it, or else + pad the bytes between the end of the shrunken region and + the start of the next region with NOP codes. */ + if (irelalign == NULL) + { + sec->size -= count; + /* Include symbols at the end of the section, but + not at the end of a sub-region of the section. */ + toaddr ++; + } + else + { + int i; + +#define NOP_OPCODE 0xcb + + for (i = 0; i < count; i ++) + bfd_put_8 (abfd, (bfd_vma) NOP_OPCODE, contents + toaddr - count + i); + } + + /* Adjust all the relocs. */ + for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) + { + /* Get the new reloc address. */ + if ((irel->r_offset > addr + && irel->r_offset < toaddr) + || (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN + && irel->r_offset == toaddr)) + irel->r_offset -= count; + } + + /* Adjust the local symbols in the section, reducing their value + by the number of bytes deleted. Note - symbols within the deleted + region are moved to the address of the start of the region, which + actually means that they will address the byte beyond the end of + the region once the deletion has been completed. */ + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + isym = (Elf_Internal_Sym *) symtab_hdr->contents; + for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) + { + if (isym->st_shndx == sec_shndx + && isym->st_value > addr + && isym->st_value < toaddr) + { + if (isym->st_value < addr + count) + isym->st_value = addr; + else + isym->st_value -= count; + } + /* Adjust the function symbol's size as well. */ + else if (isym->st_shndx == sec_shndx + && ELF_ST_TYPE (isym->st_info) == STT_FUNC + && isym->st_value + isym->st_size > addr + && isym->st_value + isym->st_size < toaddr) + isym->st_size -= count; + } + + /* Now adjust the global symbols defined in this section. */ + symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) + - symtab_hdr->sh_info); + sym_hashes = elf_sym_hashes (abfd); + end_hashes = sym_hashes + symcount; + for (; sym_hashes < end_hashes; sym_hashes++) + { + struct elf_link_hash_entry *sym_hash = *sym_hashes; + + if ((sym_hash->root.type == bfd_link_hash_defined + || sym_hash->root.type == bfd_link_hash_defweak) + && sym_hash->root.u.def.section == sec + && sym_hash->root.u.def.value > addr + && sym_hash->root.u.def.value < toaddr) + { + if (sym_hash->root.u.def.value < addr + count) + sym_hash->root.u.def.value = addr; + else + sym_hash->root.u.def.value -= count; + } + /* Adjust the function symbol's size as well. */ + else if (sym_hash->root.type == bfd_link_hash_defined + && sym_hash->root.u.def.section == sec + && sym_hash->type == STT_FUNC + && sym_hash->root.u.def.value + sym_hash->size > addr + && sym_hash->root.u.def.value + sym_hash->size < toaddr) + sym_hash->size -= count; + } + + /* See if we can move the ALIGN reloc forward. + We have adjusted r_offset for it already. */ + if (irelalign != NULL) + { + bfd_vma alignto, alignaddr; + + if ((int) irelalign->r_addend > 0) + { + /* This is the old address. */ + alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_addend); + /* This is where the align points to now. */ + alignaddr = BFD_ALIGN (irelalign->r_offset, + 1 << irelalign->r_addend); + if (alignaddr < alignto) + /* Tail recursion. */ + return mn10300_elf_relax_delete_bytes (abfd, sec, alignaddr, + (int) (alignto - alignaddr)); + } + } + + return TRUE; +} + +/* Return TRUE if a symbol exists at the given address, else return + FALSE. */ + +static bfd_boolean +mn10300_elf_symbol_address_p (bfd *abfd, + asection *sec, + Elf_Internal_Sym *isym, + bfd_vma addr) +{ + Elf_Internal_Shdr *symtab_hdr; + unsigned int sec_shndx; + Elf_Internal_Sym *isymend; + struct elf_link_hash_entry **sym_hashes; + struct elf_link_hash_entry **end_hashes; + unsigned int symcount; + + sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); + + /* Examine all the symbols. */ + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) + if (isym->st_shndx == sec_shndx + && isym->st_value == addr) + return TRUE; + + symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) + - symtab_hdr->sh_info); + sym_hashes = elf_sym_hashes (abfd); + end_hashes = sym_hashes + symcount; + for (; sym_hashes < end_hashes; sym_hashes++) + { + struct elf_link_hash_entry *sym_hash = *sym_hashes; - return a->value - b->value; -} + if ((sym_hash->root.type == bfd_link_hash_defined + || sym_hash->root.type == bfd_link_hash_defweak) + && sym_hash->root.u.def.section == sec + && sym_hash->root.u.def.value == addr) + return TRUE; + } + return FALSE; +} /* This function handles relaxing for the mn10300. @@ -1693,11 +2059,10 @@ sort_by_value (const void *va, const void *vb) and somewhat more difficult to support. */ static bfd_boolean -mn10300_elf_relax_section (abfd, sec, link_info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - bfd_boolean *again; +mn10300_elf_relax_section (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + bfd_boolean *again) { Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Rela *internal_relocs = NULL; @@ -1706,6 +2071,11 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) Elf_Internal_Sym *isymbuf = NULL; struct elf32_mn10300_link_hash_table *hash_table; asection *section = sec; + bfd_vma align_gap_adjustment; + + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); /* Assume nothing changes. */ *again = FALSE; @@ -1771,12 +2141,10 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) if ((section->flags & SEC_RELOC) != 0 && section->reloc_count != 0) { - /* Get a copy of the native relocations. */ - internal_relocs = (_bfd_elf_link_read_relocs - (input_bfd, section, (PTR) NULL, - (Elf_Internal_Rela *) NULL, - link_info->keep_memory)); + internal_relocs = _bfd_elf_link_read_relocs (input_bfd, section, + NULL, NULL, + link_info->keep_memory); if (internal_relocs == NULL) goto error_return; @@ -1835,7 +2203,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) local symbol in the global hash table. */ amt = strlen (sym_name) + 10; new_name = bfd_malloc (amt); - if (new_name == 0) + if (new_name == NULL) goto error_return; sprintf (new_name, "%s_%08x", sym_name, sym_sec->id); @@ -1944,7 +2312,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) local symbol in the global hash table. */ amt = strlen (sym_name) + 10; new_name = bfd_malloc (amt); - if (new_name == 0) + if (new_name == NULL) goto error_return; sprintf (new_name, "%s_%08x", sym_name, sym_sec->id); @@ -2034,26 +2402,28 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) elf32_mn10300_count_hash_table_entries, &static_count); - entries = (struct elf32_mn10300_link_hash_entry **) - bfd_malloc (static_count * sizeof (struct elf32_mn10300_link_hash_entry *)); + entries = bfd_malloc (static_count * sizeof (* ptr)); ptr = entries; elf32_mn10300_link_hash_traverse (hash_table->static_hash_table, elf32_mn10300_list_hash_table_entries, - &ptr); + & ptr); - qsort (entries, static_count, sizeof(entries[0]), sort_by_value); + qsort (entries, static_count, sizeof (entries[0]), sort_by_value); - for (i=0; ivalue && entries[i]->value == entries[i+1]->value) { int v = entries[i]->flags; int j; - for (j=i+1; jvalue == entries[i]->value; j++) + + for (j = i + 1; j < static_count && entries[j]->value == entries[i]->value; j++) v |= entries[j]->flags; - for (j=i; jvalue == entries[i]->value; j++) + + for (j = i; j < static_count && entries[j]->value == entries[i]->value; j++) entries[j]->flags = v; - i = j-1; + + i = j - 1; } } @@ -2099,10 +2469,9 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) if (section->reloc_count != 0) { /* Get a copy of the native relocations. */ - internal_relocs = (_bfd_elf_link_read_relocs - (input_bfd, section, (PTR) NULL, - (Elf_Internal_Rela *) NULL, - link_info->keep_memory)); + internal_relocs = _bfd_elf_link_read_relocs (input_bfd, section, + NULL, NULL, + link_info->keep_memory); if (internal_relocs == NULL) goto error_return; } @@ -2155,15 +2524,15 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) local symbol in the global hash table. */ amt = strlen (sym_name) + 10; new_name = bfd_malloc (amt); - if (new_name == 0) + if (new_name == NULL) goto error_return; sprintf (new_name, "%s_%08x", sym_name, sym_sec->id); sym_name = new_name; - elftab = &hash_table->static_hash_table->root; - sym_hash = ((struct elf32_mn10300_link_hash_entry *) - elf_link_hash_lookup (elftab, sym_name, - FALSE, FALSE, FALSE)); + elftab = & hash_table->static_hash_table->root; + sym_hash = (struct elf32_mn10300_link_hash_entry *) + elf_link_hash_lookup (elftab, sym_name, + FALSE, FALSE, FALSE); free (new_name); if (sym_hash == NULL) @@ -2276,10 +2645,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) if (! link_info->keep_memory) free (contents); else - { - /* Cache the section contents for elf_link_input_bfd. */ - elf_section_data (section)->this_hdr.contents = contents; - } + /* Cache the section contents for elf_link_input_bfd. */ + elf_section_data (section)->this_hdr.contents = contents; } contents = NULL; } @@ -2291,10 +2658,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) if (! link_info->keep_memory) free (isymbuf); else - { - /* Cache the symbols for elf_link_input_bfd. */ - symtab_hdr->contents = (unsigned char *) isymbuf; - } + /* Cache the symbols for elf_link_input_bfd. */ + symtab_hdr->contents = (unsigned char *) isymbuf; } isymbuf = NULL; } @@ -2319,17 +2684,45 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) symtab_hdr = &elf_tdata (abfd)->symtab_hdr; /* Get a copy of the native relocations. */ - internal_relocs = (_bfd_elf_link_read_relocs - (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL, - link_info->keep_memory)); + internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, + link_info->keep_memory); if (internal_relocs == NULL) goto error_return; + /* Scan for worst case alignment gap changes. Note that this logic + is not ideal; what we should do is run this scan for every + opcode/address range and adjust accordingly, but that's + expensive. Worst case is that for an alignment of N bytes, we + move by 2*N-N-1 bytes, assuming we have aligns of 1, 2, 4, 8, etc + all before it. Plus, this still doesn't cover cross-section + jumps with section alignment. */ + irelend = internal_relocs + sec->reloc_count; + align_gap_adjustment = 0; + for (irel = internal_relocs; irel < irelend; irel++) + { + if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN) + { + bfd_vma adj = 1 << irel->r_addend; + bfd_vma aend = irel->r_offset; + + aend = BFD_ALIGN (aend, 1 << irel->r_addend); + adj = 2 * adj - adj - 1; + + /* Record the biggest adjustmnet. Skip any alignment at the + end of our section. */ + if (align_gap_adjustment < adj + && aend < sec->output_section->vma + sec->output_offset + sec->size) + align_gap_adjustment = adj; + } + } + /* Walk through them looking for relaxing opportunities. */ irelend = internal_relocs + sec->reloc_count; for (irel = internal_relocs; irel < irelend; irel++) { bfd_vma symval; + bfd_signed_vma jump_offset; + asection *sym_sec = NULL; struct elf32_mn10300_link_hash_entry *h = NULL; /* If this isn't something that can be relaxed, then ignore @@ -2369,10 +2762,8 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) { Elf_Internal_Sym *isym; - 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); @@ -2390,24 +2781,42 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) 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; + symval = isym->st_value; + + /* GAS may reduce relocations against symbols in SEC_MERGE + sections to a relocation against the section symbol when + the original addend was zero. When the reloc is against + a section symbol we should include the addend in the + offset passed to _bfd_merged_section_offset, since the + location of interest is the original symbol. On the + other hand, an access to "sym+addend" where "sym" is not + a section symbol should not include the addend; Such an + access is presumed to be an offset from "sym"; The + location of interest is just "sym". */ + if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) + symval += irel->r_addend; + + symval = _bfd_merged_section_offset (abfd, & sym_sec, + elf_section_data (sym_sec)->sec_info, + symval); + + if (ELF_ST_TYPE (isym->st_info) != STT_SECTION) + symval += irel->r_addend; + + symval += sym_sec->output_section->vma + + sym_sec->output_offset - irel->r_addend; } else - { - symval = (isym->st_value - + sym_sec->output_section->vma - + sym_sec->output_offset); - } + 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) + if (new_name == NULL) goto error_return; sprintf (new_name, "%s_%08x", sym_name, sym_sec->id); sym_name = new_name; @@ -2428,12 +2837,16 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) BFD_ASSERT (h != NULL); if (h->root.root.type != bfd_link_hash_defined && h->root.root.type != bfd_link_hash_defweak) - { - /* This appears to be a reference to an undefined - symbol. Just ignore it--it will be caught by the - regular reloc processing. */ - continue; - } + /* This appears to be a reference to an undefined + symbol. Just ignore it--it will be caught by the + regular reloc processing. */ + continue; + + /* Check for a reference to a discarded symbol and ignore it. */ + if (h->root.root.u.def.section->output_section == NULL) + continue; + + sym_sec = h->root.root.u.def.section->output_section; symval = (h->root.root.u.def.value + h->root.root.u.def.section->output_section->vma @@ -2537,8 +2950,16 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) /* See if the value will fit in 16 bits, note the high value is 0x7fff + 2 as the target will be two bytes closer if we are - able to relax. */ - if ((long) value < 0x8001 && (long) value > -0x8000) + able to relax, if it's in the same section. */ + if (sec->output_section == sym_sec->output_section) + jump_offset = 0x8001; + else + jump_offset = 0x7fff; + + /* Account for jumps across alignment boundaries using + align_gap_adjustment. */ + if ((bfd_signed_vma) value < jump_offset - (bfd_signed_vma) align_gap_adjustment + && ((bfd_signed_vma) value > -0x8000 + (bfd_signed_vma) align_gap_adjustment)) { unsigned char code; @@ -3143,7 +3564,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) case 0x93: /* sp-based offsets are zero-extended. */ if (code >= 0x90 && code <= 0x93 - && (long)value < 0) + && (long) value < 0) continue; /* Note that we've changed the relocation contents, etc. */ @@ -3200,7 +3621,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) /* mov imm16, an zero-extends the immediate. */ if (code == 0xdc - && (long)value < 0) + && (long) value < 0) continue; /* Note that we've changed the relocation contents, etc. */ @@ -3281,12 +3702,12 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) case 0xe3: /* cmp imm16, an zero-extends the immediate. */ if (code == 0xdc - && (long)value < 0) + && (long) value < 0) continue; /* So do sp-based offsets. */ if (code >= 0xb0 && code <= 0xb3 - && (long)value < 0) + && (long) value < 0) continue; /* Note that we've changed the relocation contents, etc. */ @@ -3405,242 +3826,16 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) return FALSE; } -/* Compute the stack size and movm arguments for the function - referred to by HASH at address ADDR in section with - contents CONTENTS, store the information in the hash table. */ -static void -compute_function_info (abfd, hash, addr, contents) - bfd *abfd; - struct elf32_mn10300_link_hash_entry *hash; - bfd_vma addr; - unsigned char *contents; -{ - unsigned char byte1, byte2; - /* We only care about a very small subset of the possible prologue - sequences here. Basically we look for: - - movm [d2,d3,a2,a3],sp (optional) - add ,sp (optional, and only for sizes which fit in an unsigned - 8 bit number) - - If we find anything else, we quit. */ - - /* Look for movm [regs],sp */ - byte1 = bfd_get_8 (abfd, contents + addr); - byte2 = bfd_get_8 (abfd, contents + addr + 1); - - if (byte1 == 0xcf) - { - hash->movm_args = byte2; - addr += 2; - byte1 = bfd_get_8 (abfd, contents + addr); - byte2 = bfd_get_8 (abfd, contents + addr + 1); - } - - /* Now figure out how much stack space will be allocated by the movm - instruction. We need this kept separate from the function's normal - stack space. */ - if (hash->movm_args) - { - /* Space for d2. */ - if (hash->movm_args & 0x80) - hash->movm_stack_size += 4; - - /* Space for d3. */ - if (hash->movm_args & 0x40) - hash->movm_stack_size += 4; - - /* Space for a2. */ - if (hash->movm_args & 0x20) - hash->movm_stack_size += 4; - - /* Space for a3. */ - if (hash->movm_args & 0x10) - hash->movm_stack_size += 4; - - /* "other" space. d0, d1, a0, a1, mdr, lir, lar, 4 byte pad. */ - if (hash->movm_args & 0x08) - hash->movm_stack_size += 8 * 4; - - if (bfd_get_mach (abfd) == bfd_mach_am33 - || bfd_get_mach (abfd) == bfd_mach_am33_2) - { - /* "exother" space. e0, e1, mdrq, mcrh, mcrl, mcvf */ - if (hash->movm_args & 0x1) - hash->movm_stack_size += 6 * 4; - - /* exreg1 space. e4, e5, e6, e7 */ - if (hash->movm_args & 0x2) - hash->movm_stack_size += 4 * 4; - - /* exreg0 space. e2, e3 */ - if (hash->movm_args & 0x4) - hash->movm_stack_size += 2 * 4; - } - } - - /* Now look for the two stack adjustment variants. */ - if (byte1 == 0xf8 && byte2 == 0xfe) - { - int temp = bfd_get_8 (abfd, contents + addr + 2); - temp = ((temp & 0xff) ^ (~0x7f)) + 0x80; - - hash->stack_size = -temp; - } - else if (byte1 == 0xfa && byte2 == 0xfe) - { - int temp = bfd_get_16 (abfd, contents + addr + 2); - temp = ((temp & 0xffff) ^ (~0x7fff)) + 0x8000; - temp = -temp; - - if (temp < 255) - hash->stack_size = temp; - } - - /* If the total stack to be allocated by the call instruction is more - than 255 bytes, then we can't remove the stack adjustment by using - "call" (we might still be able to remove the "movm" instruction. */ - if (hash->stack_size + hash->movm_stack_size > 255) - hash->stack_size = 0; - - return; -} - -/* Delete some bytes from a section while relaxing. */ - -static bfd_boolean -mn10300_elf_relax_delete_bytes (abfd, sec, addr, count) - bfd *abfd; - asection *sec; - bfd_vma addr; - int count; -{ - Elf_Internal_Shdr *symtab_hdr; - unsigned int sec_shndx; - bfd_byte *contents; - Elf_Internal_Rela *irel, *irelend; - Elf_Internal_Rela *irelalign; - bfd_vma toaddr; - Elf_Internal_Sym *isym, *isymend; - struct elf_link_hash_entry **sym_hashes; - struct elf_link_hash_entry **end_hashes; - unsigned int symcount; - - sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); - - 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; - irelend = irel + sec->reloc_count; - - /* Actually delete the bytes. */ - memmove (contents + addr, contents + addr + count, - (size_t) (toaddr - addr - count)); - sec->size -= count; - - /* Adjust all the relocs. */ - for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) - { - /* Get the new reloc address. */ - if ((irel->r_offset > addr - && irel->r_offset < toaddr)) - irel->r_offset -= count; - } - - /* Adjust the local symbols defined in this section. */ - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - isym = (Elf_Internal_Sym *) symtab_hdr->contents; - for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) - { - if (isym->st_shndx == sec_shndx - && isym->st_value > addr - && isym->st_value < toaddr) - isym->st_value -= count; - } - - /* Now adjust the global symbols defined in this section. */ - symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) - - symtab_hdr->sh_info); - sym_hashes = elf_sym_hashes (abfd); - end_hashes = sym_hashes + symcount; - for (; sym_hashes < end_hashes; sym_hashes++) - { - struct elf_link_hash_entry *sym_hash = *sym_hashes; - if ((sym_hash->root.type == bfd_link_hash_defined - || sym_hash->root.type == bfd_link_hash_defweak) - && sym_hash->root.u.def.section == sec - && sym_hash->root.u.def.value > addr - && sym_hash->root.u.def.value < toaddr) - { - sym_hash->root.u.def.value -= count; - } - } - - return TRUE; -} - -/* Return TRUE if a symbol exists at the given address, else return - FALSE. */ -static bfd_boolean -mn10300_elf_symbol_address_p (abfd, sec, isym, addr) - bfd *abfd; - asection *sec; - Elf_Internal_Sym *isym; - bfd_vma addr; -{ - Elf_Internal_Shdr *symtab_hdr; - unsigned int sec_shndx; - Elf_Internal_Sym *isymend; - struct elf_link_hash_entry **sym_hashes; - struct elf_link_hash_entry **end_hashes; - unsigned int symcount; - - sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); - - /* Examine all the symbols. */ - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) - { - if (isym->st_shndx == sec_shndx - && isym->st_value == addr) - return TRUE; - } - - symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) - - symtab_hdr->sh_info); - sym_hashes = elf_sym_hashes (abfd); - end_hashes = sym_hashes + symcount; - for (; sym_hashes < end_hashes; sym_hashes++) - { - struct elf_link_hash_entry *sym_hash = *sym_hashes; - if ((sym_hash->root.type == bfd_link_hash_defined - || sym_hash->root.type == bfd_link_hash_defweak) - && sym_hash->root.u.def.section == sec - && sym_hash->root.u.def.value == addr) - return TRUE; - } - - return FALSE; -} - /* This is a version of bfd_generic_get_relocated_section_contents which uses mn10300_elf_relocate_section. */ static bfd_byte * -mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order, - data, relocatable, symbols) - bfd *output_bfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - bfd_boolean relocatable; - asymbol **symbols; +mn10300_elf_get_relocated_section_contents (bfd *output_bfd, + struct bfd_link_info *link_info, + struct bfd_link_order *link_order, + bfd_byte *data, + bfd_boolean relocatable, + asymbol **symbols) { Elf_Internal_Shdr *symtab_hdr; asection *input_section = link_order->u.indirect.section; @@ -3670,9 +3865,8 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order, Elf_Internal_Sym *isym, *isymend; bfd_size_type amt; - internal_relocs = (_bfd_elf_link_read_relocs - (input_bfd, input_section, (PTR) NULL, - (Elf_Internal_Rela *) NULL, FALSE)); + internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section, + NULL, NULL, FALSE); if (internal_relocs == NULL) goto error_return; @@ -3689,7 +3883,7 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order, amt = symtab_hdr->sh_info; amt *= sizeof (asection *); - sections = (asection **) bfd_malloc (amt); + sections = bfd_malloc (amt); if (sections == NULL && amt != 0) goto error_return; @@ -3711,8 +3905,8 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order, } if (! mn10300_elf_relocate_section (output_bfd, link_info, input_bfd, - input_section, data, internal_relocs, - isymbuf, sections)) + input_section, data, internal_relocs, + isymbuf, sections)) goto error_return; if (sections != NULL) @@ -3743,28 +3937,26 @@ mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order, /* Create an entry in an MN10300 ELF linker hash table. */ static struct bfd_hash_entry * -elf32_mn10300_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; +elf32_mn10300_link_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) { struct elf32_mn10300_link_hash_entry *ret = (struct elf32_mn10300_link_hash_entry *) entry; /* Allocate the structure if it has not already been allocated by a subclass. */ - if (ret == (struct elf32_mn10300_link_hash_entry *) NULL) - ret = ((struct elf32_mn10300_link_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf32_mn10300_link_hash_entry))); - if (ret == (struct elf32_mn10300_link_hash_entry *) NULL) + if (ret == NULL) + ret = (struct elf32_mn10300_link_hash_entry *) + bfd_hash_allocate (table, sizeof (* ret)); + if (ret == NULL) return (struct bfd_hash_entry *) ret; /* Call the allocation method of the superclass. */ - ret = ((struct elf32_mn10300_link_hash_entry *) + ret = (struct elf32_mn10300_link_hash_entry *) _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != (struct elf32_mn10300_link_hash_entry *) NULL) + table, string); + if (ret != NULL) { ret->direct_calls = 0; ret->stack_size = 0; @@ -3780,14 +3972,13 @@ elf32_mn10300_link_hash_newfunc (entry, table, string) /* Create an mn10300 ELF linker hash table. */ static struct bfd_link_hash_table * -elf32_mn10300_link_hash_table_create (abfd) - bfd *abfd; +elf32_mn10300_link_hash_table_create (bfd *abfd) { struct elf32_mn10300_link_hash_table *ret; - bfd_size_type amt = sizeof (struct elf32_mn10300_link_hash_table); + bfd_size_type amt = sizeof (* ret); - ret = (struct elf32_mn10300_link_hash_table *) bfd_malloc (amt); - if (ret == (struct elf32_mn10300_link_hash_table *) NULL) + ret = bfd_malloc (amt); + if (ret == NULL) return NULL; if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, @@ -3800,8 +3991,7 @@ elf32_mn10300_link_hash_table_create (abfd) ret->flags = 0; amt = sizeof (struct elf_link_hash_table); - ret->static_hash_table - = (struct elf32_mn10300_link_hash_table *) bfd_malloc (amt); + ret->static_hash_table = bfd_malloc (amt); if (ret->static_hash_table == NULL) { free (ret); @@ -3816,14 +4006,13 @@ elf32_mn10300_link_hash_table_create (abfd) free (ret); return NULL; } - return &ret->root.root; + return & ret->root.root; } /* Free an mn10300 ELF linker hash table. */ static void -elf32_mn10300_link_hash_table_free (hash) - struct bfd_link_hash_table *hash; +elf32_mn10300_link_hash_table_free (struct bfd_link_hash_table *hash) { struct elf32_mn10300_link_hash_table *ret = (struct elf32_mn10300_link_hash_table *) hash; @@ -3835,8 +4024,7 @@ elf32_mn10300_link_hash_table_free (hash) } static unsigned long -elf_mn10300_mach (flags) - flagword flags; +elf_mn10300_mach (flagword flags) { switch (flags & EF_MN10300_MACH) { @@ -3856,10 +4044,9 @@ elf_mn10300_mach (flags) file. This gets the MN10300 architecture right based on the machine number. */ -void -_bfd_mn10300_elf_final_write_processing (abfd, linker) - bfd *abfd; - bfd_boolean linker ATTRIBUTE_UNUSED; +static void +_bfd_mn10300_elf_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { unsigned long val; @@ -3883,9 +4070,8 @@ _bfd_mn10300_elf_final_write_processing (abfd, linker) elf_elfheader (abfd)->e_flags |= val; } -bfd_boolean -_bfd_mn10300_elf_object_p (abfd) - bfd *abfd; +static bfd_boolean +_bfd_mn10300_elf_object_p (bfd *abfd) { bfd_default_set_arch_mach (abfd, bfd_arch_mn10300, elf_mn10300_mach (elf_elfheader (abfd)->e_flags)); @@ -3895,10 +4081,8 @@ _bfd_mn10300_elf_object_p (abfd) /* Merge backend specific data from an object file to the output object file when linking. */ -bfd_boolean -_bfd_mn10300_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +static bfd_boolean +_bfd_mn10300_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) @@ -3915,9 +4099,9 @@ _bfd_mn10300_elf_merge_private_bfd_data (ibfd, obfd) return TRUE; } -#define PLT0_ENTRY_SIZE 15 -#define PLT_ENTRY_SIZE 20 -#define PIC_PLT_ENTRY_SIZE 24 +#define PLT0_ENTRY_SIZE 15 +#define PLT_ENTRY_SIZE 20 +#define PIC_PLT_ENTRY_SIZE 24 static const bfd_byte elf_mn10300_plt0_entry[PLT0_ENTRY_SIZE] = { @@ -3961,7 +4145,7 @@ static const bfd_byte elf_mn10300_pic_plt_entry[PIC_PLT_ENTRY_SIZE] = /* Return offset of the GOT id in PLT0 entry. */ #define elf_mn10300_plt0_gotid_offset(info) 9 -/* Return offset of the temporary 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. */ @@ -3978,9 +4162,7 @@ static const bfd_byte elf_mn10300_pic_plt_entry[PIC_PLT_ENTRY_SIZE] = /* Create dynamic sections when linking against a dynamic object. */ static bfd_boolean -_bfd_mn10300_elf_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +_bfd_mn10300_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) { flagword flags; asection * s; @@ -4004,7 +4186,6 @@ _bfd_mn10300_elf_create_dynamic_sections (abfd, info) /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and .rel[a].bss sections. */ - flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED); @@ -4033,7 +4214,7 @@ _bfd_mn10300_elf_create_dynamic_sections (abfd, info) continue; secname = bfd_get_section_name (abfd, sec); - relname = (char *) bfd_malloc (strlen (secname) + 6); + relname = bfd_malloc (strlen (secname) + 6); strcpy (relname, ".rela"); strcat (relname, secname); @@ -4091,9 +4272,8 @@ _bfd_mn10300_elf_create_dynamic_sections (abfd, info) understand. */ static bfd_boolean -_bfd_mn10300_elf_adjust_dynamic_symbol (info, h) - struct bfd_link_info * info; - struct elf_link_hash_entry * h; +_bfd_mn10300_elf_adjust_dynamic_symbol (struct bfd_link_info * info, + struct elf_link_hash_entry * h) { bfd * dynobj; asection * s; @@ -4161,13 +4341,11 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (info, h) /* 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->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->size += sizeof (Elf32_External_Rela); @@ -4242,9 +4420,8 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (info, h) /* Set the sizes of the dynamic sections. */ static bfd_boolean -_bfd_mn10300_elf_size_dynamic_sections (output_bfd, info) - bfd * output_bfd; - struct bfd_link_info * info; +_bfd_mn10300_elf_size_dynamic_sections (bfd * output_bfd, + struct bfd_link_info * info) { bfd * dynobj; asection * s; @@ -4295,7 +4472,7 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info) of the dynobj section names depend upon the input files. */ name = bfd_get_section_name (dynobj, s); - if (strcmp (name, ".plt") == 0) + if (streq (name, ".plt")) { /* Remember whether there is a PLT. */ plt = s->size != 0; @@ -4308,7 +4485,7 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info) /* Remember whether there are any reloc sections other than .rela.plt. */ - if (strcmp (name, ".rela.plt") != 0) + if (! streq (name, ".rela.plt")) { const char * outname; @@ -4334,7 +4511,7 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info) } } else if (! CONST_STRNEQ (name, ".got") - && strcmp (name, ".dynbss") != 0) + && ! streq (name, ".dynbss")) /* It's not one of our sections, so don't allocate space. */ continue; @@ -4361,7 +4538,7 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info) 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->size); + s->contents = bfd_zalloc (dynobj, s->size); if (s->contents == NULL) return FALSE; } @@ -4411,11 +4588,10 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info) dynamic sections here. */ static bfd_boolean -_bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd * output_bfd; - struct bfd_link_info * info; - struct elf_link_hash_entry * h; - Elf_Internal_Sym * sym; +_bfd_mn10300_elf_finish_dynamic_symbol (bfd * output_bfd, + struct bfd_link_info * info, + struct elf_link_hash_entry * h, + Elf_Internal_Sym * sym) { bfd * dynobj; @@ -4514,14 +4690,13 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym) Elf_Internal_Rela rel; /* 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"); BFD_ASSERT (sgot != NULL && srel != NULL); rel.r_offset = (sgot->output_section->vma + sgot->output_offset - + (h->got.offset &~ 1)); + + (h->got.offset & ~1)); /* If this is a -Bsymbolic link, and the symbol is defined locally, we just want to emit a RELATIVE reloc. Likewise if @@ -4569,14 +4744,14 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym) + h->root.u.def.section->output_offset); rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_COPY); rel.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rel, + bfd_elf32_swap_reloca_out (output_bfd, & rel, (bfd_byte *) ((Elf32_External_Rela *) s->contents + s->reloc_count)); ++ s->reloc_count; } /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 + if (streq (h->root.root.string, "_DYNAMIC") || h == elf_hash_table (info)->hgot) sym->st_shndx = SHN_ABS; @@ -4586,9 +4761,8 @@ _bfd_mn10300_elf_finish_dynamic_symbol (output_bfd, info, h, sym) /* Finish up the dynamic sections. */ static bfd_boolean -_bfd_mn10300_elf_finish_dynamic_sections (output_bfd, info) - bfd * output_bfd; - struct bfd_link_info * info; +_bfd_mn10300_elf_finish_dynamic_sections (bfd * output_bfd, + struct bfd_link_info * info) { bfd * dynobj; asection * sgot; @@ -4714,14 +4888,10 @@ _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; + 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; } }