From 603b72571dd17826efe9843dab8fbb0d5012a1f3 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 19 Oct 2007 11:48:57 +0000 Subject: [PATCH] * elf-m10300.c: Convert to ISO C. * tc-mn10300.c: Convert to ISO C. --- bfd/ChangeLog | 4 + bfd/elf-m10300.c | 895 ++++++++++++++++++---------------------- gas/config/tc-mn10300.c | 836 +++++++++++++------------------------ 3 files changed, 676 insertions(+), 1059 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index aa17c293d01..6d7fa26d077 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,7 @@ +2007-10-19 Nick Clifton + + * elf-m10300.c: Convert to ISO C. + 2007-10-18 H.J. Lu Alan Modra diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 4849ffd205c..9aedc06b044 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -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) */ @@ -498,15 +446,16 @@ static reloc_howto_type elf_mn10300_howto_table[] = { 0xffffffff, /* src_mask */ 0xffffffff, /* 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, }, @@ -536,9 +485,8 @@ static const struct mn10300_reloc_map mn10300_reloc_map[] = { /* 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 +569,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 +587,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 +598,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,11 +614,10 @@ 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) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -704,6 +642,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) dynobj = elf_hash_table (info)->dynobj; local_got_offsets = elf_local_got_offsets (abfd); rel_end = relocs + sec->reloc_count; + for (rel = relocs; rel < rel_end; rel++) { struct elf_link_hash_entry *h; @@ -818,7 +757,7 @@ 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; @@ -842,7 +781,6 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) } sgot->size += 4; - break; case R_MN10300_PLT32: @@ -864,7 +802,6 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) break; h->needs_plt = 1; - break; case R_MN10300_24: @@ -901,8 +838,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) return FALSE; BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); + && streq (bfd_get_section_name (abfd, sec), name + 5)); sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) @@ -913,9 +849,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) | 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); + sreloc = bfd_make_section_with_flags (dynobj, name, flags); if (sreloc == NULL || ! bfd_set_section_alignment (dynobj, sreloc, 2)) return FALSE; @@ -954,26 +888,24 @@ 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) { 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; @@ -1032,9 +964,9 @@ mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd, return FALSE; BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); + && streq (bfd_get_section_name (input_bfd, + input_section), + name + 5)); sreloc = bfd_get_section_by_name (dynobj, name); BFD_ASSERT (sreloc != NULL); @@ -1159,7 +1091,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 @@ -1172,7 +1103,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 @@ -1363,17 +1293,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; @@ -1482,14 +1411,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; @@ -1537,7 +1466,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) @@ -1553,13 +1482,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; @@ -1617,9 +1546,10 @@ 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; @@ -1628,9 +1558,10 @@ elf32_mn10300_count_hash_table_entries (struct bfd_hash_entry *gen_entry ATTRIBU } /* 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; @@ -1640,6 +1571,7 @@ 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) { @@ -1651,6 +1583,224 @@ sort_by_value (const void *va, const void *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; + + /* 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 (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 function handles relaxing for the mn10300. @@ -1692,11 +1842,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; @@ -1770,12 +1919,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; @@ -2033,26 +2180,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; } } @@ -2098,10 +2247,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; } @@ -2159,10 +2307,10 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) 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) @@ -2275,10 +2423,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; } @@ -2290,10 +2436,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; } @@ -2318,9 +2462,8 @@ 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; @@ -2403,6 +2546,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again) + 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); @@ -2427,12 +2571,10 @@ 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; symval = (h->root.root.u.def.value + h->root.root.u.def.section->output_section->vma @@ -3404,242 +3546,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; @@ -3669,9 +3585,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; @@ -3688,7 +3603,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; @@ -3710,8 +3625,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) @@ -3742,28 +3657,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; @@ -3779,14 +3692,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, @@ -3799,8 +3711,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); @@ -3815,14 +3726,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; @@ -3834,8 +3744,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) { @@ -3855,10 +3764,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; @@ -3882,9 +3790,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)); @@ -3894,10 +3801,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) @@ -3914,9 +3819,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] = { @@ -3960,7 +3865,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. */ @@ -3977,9 +3882,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; @@ -4003,7 +3906,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); @@ -4032,7 +3934,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); @@ -4090,9 +3992,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; @@ -4160,13 +4061,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); @@ -4241,9 +4140,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; @@ -4294,7 +4192,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; @@ -4307,7 +4205,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; @@ -4333,7 +4231,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; @@ -4360,7 +4258,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; } @@ -4410,11 +4308,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; @@ -4513,14 +4410,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 @@ -4568,14 +4464,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; @@ -4585,9 +4481,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; @@ -4713,14 +4608,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; } } diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c index 9b2441fa735..671c0089f7f 100644 --- a/gas/config/tc-mn10300.c +++ b/gas/config/tc-mn10300.c @@ -24,6 +24,7 @@ #include "subsegs.h" #include "opcode/mn10300.h" #include "dwarf2dbg.h" +#include "libiberty.h" /* Structure to hold information about predefined registers. */ struct reg_name @@ -59,7 +60,7 @@ const relax_typeS md_relax_table[] = are because the branch instruction is translated into a jump instruction that is now +2 or +3 bytes further on in memory, and the correct size of jump instruction must be selected. */ - /* bCC relaxing */ + /* bCC relaxing. */ {0x7f, -0x80, 2, 1}, {0x7fff + 2, -0x8000 + 2, 5, 2}, {0x7fffffff, -0x80000000, 7, 0}, @@ -69,49 +70,34 @@ const relax_typeS md_relax_table[] = {0x7fff + 3, -0x8000 + 3, 6, 5}, {0x7fffffff, -0x80000000, 8, 0}, - /* call relaxing */ + /* call relaxing. */ {0x7fff, -0x8000, 5, 7}, {0x7fffffff, -0x80000000, 7, 0}, - /* calls relaxing */ + /* calls relaxing. */ {0x7fff, -0x8000, 4, 9}, {0x7fffffff, -0x80000000, 6, 0}, - /* jmp relaxing */ + /* jmp relaxing. */ {0x7f, -0x80, 2, 11}, {0x7fff, -0x8000, 3, 12}, {0x7fffffff, -0x80000000, 5, 0}, - /* fbCC relaxing */ + /* fbCC relaxing. */ {0x7f, -0x80, 3, 14}, {0x7fff + 3, -0x8000 + 3, 6, 15}, {0x7fffffff, -0x80000000, 8, 0}, }; -/* Local functions. */ -static void mn10300_insert_operand PARAMS ((unsigned long *, unsigned long *, - const struct mn10300_operand *, - offsetT, char *, unsigned, - unsigned)); -static unsigned long check_operand PARAMS ((unsigned long, - const struct mn10300_operand *, - offsetT)); -static int reg_name_search PARAMS ((const struct reg_name *, int, const char *)); -static bfd_boolean data_register_name PARAMS ((expressionS *expressionP)); -static bfd_boolean address_register_name PARAMS ((expressionS *expressionP)); -static bfd_boolean other_register_name PARAMS ((expressionS *expressionP)); -static bfd_boolean r_register_name PARAMS ((expressionS *expressionP)); -static bfd_boolean xr_register_name PARAMS ((expressionS *expressionP)); -static void set_arch_mach PARAMS ((int)); - /* Set linkrelax here to avoid fixups in most sections. */ int linkrelax = 1; static int current_machine; /* Fixups. */ -#define MAX_INSN_FIXUPS (5) +#define MAX_INSN_FIXUPS 5 + struct mn10300_fixup { expressionS exp; @@ -126,24 +112,17 @@ static int fc; int mn10300_reg_operands[MN10300_MAX_OPERANDS]; const char *md_shortopts = ""; -struct option md_longopts[] = { - {NULL, no_argument, NULL, 0} -}; -size_t md_longopts_size = sizeof (md_longopts); -/* The target specific pseudo-ops which we support. */ -const pseudo_typeS md_pseudo_table[] = +struct option md_longopts[] = { - { "am30", set_arch_mach, AM30 }, - { "am33", set_arch_mach, AM33 }, - { "am33_2", (void (*) PARAMS ((int))) set_arch_mach, AM33_2 }, - { "mn10300", set_arch_mach, MN103 }, - {NULL, 0, 0} + {NULL, no_argument, NULL, 0} }; +size_t md_longopts_size = sizeof (md_longopts); + #define HAVE_AM33_2 (current_machine == AM33_2) -#define HAVE_AM33 (current_machine == AM33 || HAVE_AM33_2) -#define HAVE_AM30 (current_machine == AM30) +#define HAVE_AM33 (current_machine == AM33 || HAVE_AM33_2) +#define HAVE_AM30 (current_machine == AM30) /* Opcode hash table. */ static struct hash_control *mn10300_hash; @@ -156,8 +135,6 @@ static const struct reg_name data_registers[] = { "d2", 2 }, { "d3", 3 }, }; -#define DATA_REG_NAME_CNT \ - (sizeof (data_registers) / sizeof (struct reg_name)) static const struct reg_name address_registers[] = { @@ -167,9 +144,6 @@ static const struct reg_name address_registers[] = { "a3", 3 }, }; -#define ADDRESS_REG_NAME_CNT \ - (sizeof (address_registers) / sizeof (struct reg_name)) - static const struct reg_name r_registers[] = { { "a0", 8 }, @@ -214,9 +188,6 @@ static const struct reg_name r_registers[] = { "r9", 9 }, }; -#define R_REG_NAME_CNT \ - (sizeof (r_registers) / sizeof (struct reg_name)) - static const struct reg_name xr_registers[] = { { "mcrh", 2 }, @@ -242,26 +213,6 @@ static const struct reg_name xr_registers[] = { "xr9", 9 }, }; -#define XR_REG_NAME_CNT \ - (sizeof (xr_registers) / sizeof (struct reg_name)) - -/* We abuse the `value' field, that would be otherwise unused, to - encode the architecture on which (access to) the register was - introduced. FIXME: we should probably warn when we encounter a - register name when assembling for an architecture that doesn't - support it, before parsing it as a symbol name. */ -static const struct reg_name other_registers[] = -{ - { "epsw", AM33 }, - { "mdr", 0 }, - { "pc", AM33 }, - { "psw", 0 }, - { "sp", 0 }, -}; - -#define OTHER_REG_NAME_CNT \ - (sizeof (other_registers) / sizeof (struct reg_name)) - static const struct reg_name float_registers[] = { { "fs0", 0 }, @@ -298,9 +249,6 @@ static const struct reg_name float_registers[] = { "fs9", 9 }, }; -#define FLOAT_REG_NAME_CNT \ - (sizeof (float_registers) / sizeof (struct reg_name)) - static const struct reg_name double_registers[] = { { "fd0", 0 }, @@ -321,28 +269,40 @@ static const struct reg_name double_registers[] = { "fd8", 8 }, }; -#define DOUBLE_REG_NAME_CNT \ - (sizeof (double_registers) / sizeof (struct reg_name)) +/* We abuse the `value' field, that would be otherwise unused, to + encode the architecture on which (access to) the register was + introduced. FIXME: we should probably warn when we encounter a + register name when assembling for an architecture that doesn't + support it, before parsing it as a symbol name. */ +static const struct reg_name other_registers[] = +{ + { "epsw", AM33 }, + { "mdr", 0 }, + { "pc", AM33 }, + { "psw", 0 }, + { "sp", 0 }, +}; +#define OTHER_REG_NAME_CNT ARRAY_SIZE (other_registers) -/* reg_name_search does a binary search of the given register table - to see if "name" is a valid regiter name. Returns the register - number from the array on success, or -1 on failure. */ +/* Perform a binary search of the given register table REGS to see + if NAME is a valid regiter name. Returns the register number from + the array on success, or -1 on failure. */ static int -reg_name_search (regs, regcount, name) - const struct reg_name *regs; - int regcount; - const char *name; +reg_name_search (const struct reg_name *regs, + int regcount, + const char *name) { - int middle, low, high; - int cmp; + int low, high; low = 0; high = regcount - 1; do { + int cmp, middle; + middle = (low + high) / 2; cmp = strcasecmp (name, regs[middle].name); if (cmp < 0) @@ -353,23 +313,22 @@ reg_name_search (regs, regcount, name) return regs[middle].value; } while (low <= high); + return -1; } -/* Summary of register_name(). - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: An expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in - * its original state. - */ +/* Looks at the current position in the input line to see if it is + the name of a register in TABLE. If it is, then the name is + converted into an expression returned in EXPRESSIONP (with X_op + set to O_register and X_add_number set to the register number), the + input pointer is left pointing at the first non-blank character after + the name and the function returns TRUE. Otherwise the input pointer + is left alone and the function returns FALSE. */ static bfd_boolean -r_register_name (expressionP) - expressionS *expressionP; +get_register_name (expressionS * expressionP, + const struct reg_name * table, + size_t table_length) { int reg_number; char *name; @@ -380,7 +339,7 @@ r_register_name (expressionP) start = name = input_line_pointer; c = get_symbol_end (); - reg_number = reg_name_search (r_registers, R_REG_NAME_CNT, name); + reg_number = reg_name_search (table, table_length, name); /* Put back the delimiting char. */ *input_line_pointer = c; @@ -403,257 +362,45 @@ r_register_name (expressionP) return FALSE; } -/* Summary of register_name(). - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: An expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in - * its original state. - */ - static bfd_boolean -xr_register_name (expressionP) - expressionS *expressionP; +r_register_name (expressionS *expressionP) { - int reg_number; - char *name; - char *start; - char c; - - /* Find the spelling of the operand. */ - start = name = input_line_pointer; - - c = get_symbol_end (); - reg_number = reg_name_search (xr_registers, XR_REG_NAME_CNT, name); - - /* Put back the delimiting char. */ - *input_line_pointer = c; - - /* Look to see if it's in the register table. */ - if (reg_number >= 0) - { - expressionP->X_op = O_register; - expressionP->X_add_number = reg_number; - - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - - return TRUE; - } - - /* Reset the line as if we had not done anything. */ - input_line_pointer = start; - return FALSE; + return get_register_name (expressionP, r_registers, ARRAY_SIZE (r_registers)); } -/* Summary of register_name(). - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: An expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in - * its original state. - */ static bfd_boolean -data_register_name (expressionP) - expressionS *expressionP; +xr_register_name (expressionS *expressionP) { - int reg_number; - char *name; - char *start; - char c; - - /* Find the spelling of the operand. */ - start = name = input_line_pointer; - - c = get_symbol_end (); - reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name); - - /* Put back the delimiting char. */ - *input_line_pointer = c; - - /* Look to see if it's in the register table. */ - if (reg_number >= 0) - { - expressionP->X_op = O_register; - expressionP->X_add_number = reg_number; - - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - - return TRUE; - } - - /* Reset the line as if we had not done anything. */ - input_line_pointer = start; - return FALSE; + return get_register_name (expressionP, xr_registers, ARRAY_SIZE (xr_registers)); } -/* Summary of register_name(). - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: An expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in - * its original state. - */ - static bfd_boolean -address_register_name (expressionP) - expressionS *expressionP; +data_register_name (expressionS *expressionP) { - int reg_number; - char *name; - char *start; - char c; - - /* Find the spelling of the operand. */ - start = name = input_line_pointer; - - c = get_symbol_end (); - reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name); - - /* Put back the delimiting char. */ - *input_line_pointer = c; - - /* Look to see if it's in the register table. */ - if (reg_number >= 0) - { - expressionP->X_op = O_register; - expressionP->X_add_number = reg_number; - - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - - return TRUE; - } - - /* Reset the line as if we had not done anything. */ - input_line_pointer = start; - return FALSE; + return get_register_name (expressionP, data_registers, ARRAY_SIZE (data_registers)); } -/* Summary of register_name(). - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: An expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in - * its original state. - */ - static bfd_boolean -other_register_name (expressionP) - expressionS *expressionP; +address_register_name (expressionS *expressionP) { - int reg_number; - char *name; - char *start; - char c; - - /* Find the spelling of the operand. */ - start = name = input_line_pointer; - - c = get_symbol_end (); - reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name); - - /* Put back the delimiting char. */ - *input_line_pointer = c; - - /* Look to see if it's in the register table. */ - if (reg_number == 0 - || (reg_number == AM33 && HAVE_AM33)) - { - expressionP->X_op = O_register; - expressionP->X_add_number = 0; - - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - - return TRUE; - } - - /* Reset the line as if we had not done anything. */ - input_line_pointer = start; - return FALSE; + return get_register_name (expressionP, address_registers, ARRAY_SIZE (address_registers)); } -static bfd_boolean double_register_name PARAMS ((expressionS *)); -static bfd_boolean float_register_name PARAMS ((expressionS *)); - -/* Summary of float_register_name: - - in: Input_line_pointer points to 1st char of operand. - - out: A expressionS. - The operand may have been a register: in this case, X_op == O_register, - X_add_number is set to the register number, and truth is returned. - Input_line_pointer->(next non-blank) char after operand, or is in - its original state. */ - static bfd_boolean -float_register_name (expressionP) - expressionS *expressionP; +float_register_name (expressionS *expressionP) { - int reg_number; - char *name; - char *start; - char c; - - /* Find the spelling of the operand. */ - start = name = input_line_pointer; - - c = get_symbol_end (); - reg_number = reg_name_search (float_registers, FLOAT_REG_NAME_CNT, name); - - /* Put back the delimiting char. */ - * input_line_pointer = c; - - /* Look to see if it's in the register table. */ - if (reg_number >= 0) - { - expressionP->X_op = O_register; - expressionP->X_add_number = reg_number; - - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - - return TRUE; - } - - /* Reset the line as if we had not done anything. */ - input_line_pointer = start; - return FALSE; + return get_register_name (expressionP, float_registers, ARRAY_SIZE (float_registers)); } -/* Summary of double_register_name: - - in: Input_line_pointer points to 1st char of operand. - - out: A expressionS. - The operand may have been a register: in this case, X_op == O_register, - X_add_number is set to the register number, and truth is returned. - Input_line_pointer->(next non-blank) char after operand, or is in - its original state. */ +static bfd_boolean +double_register_name (expressionS *expressionP) +{ + return get_register_name (expressionP, double_registers, ARRAY_SIZE (double_registers)); +} static bfd_boolean -double_register_name (expressionP) - expressionS *expressionP; +other_register_name (expressionS *expressionP) { int reg_number; char *name; @@ -664,16 +411,17 @@ double_register_name (expressionP) start = name = input_line_pointer; c = get_symbol_end (); - reg_number = reg_name_search (double_registers, DOUBLE_REG_NAME_CNT, name); + reg_number = reg_name_search (other_registers, ARRAY_SIZE (other_registers), name); /* Put back the delimiting char. */ - * input_line_pointer = c; + *input_line_pointer = c; /* Look to see if it's in the register table. */ - if (reg_number >= 0) + if (reg_number == 0 + || (reg_number == AM33 && HAVE_AM33)) { expressionP->X_op = O_register; - expressionP->X_add_number = reg_number; + expressionP->X_add_number = 0; /* Make the rest nice. */ expressionP->X_add_symbol = NULL; @@ -688,24 +436,20 @@ double_register_name (expressionP) } void -md_show_usage (stream) - FILE *stream; +md_show_usage (FILE *stream) { fprintf (stream, _("MN10300 assembler options:\n\ none yet\n")); } int -md_parse_option (c, arg) - int c ATTRIBUTE_UNUSED; - char *arg ATTRIBUTE_UNUSED; +md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED) { return 0; } symbolS * -md_undefined_symbol (name) - char *name ATTRIBUTE_UNUSED; +md_undefined_symbol (char *name ATTRIBUTE_UNUSED) { return 0; } @@ -717,10 +461,9 @@ md_atof (int type, char *litp, int *sizep) } void -md_convert_frag (abfd, sec, fragP) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - fragS *fragP; +md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + fragS *fragP) { static unsigned long label_count = 0; char buf[40]; @@ -1149,19 +892,18 @@ md_convert_frag (abfd, sec, fragP) } valueT -md_section_align (seg, addr) - asection *seg; - valueT addr; +md_section_align (asection *seg, valueT addr) { int align = bfd_get_section_alignment (stdoutput, seg); + return ((addr + (1 << align) - 1) & (-1 << align)); } void -md_begin () +md_begin (void) { char *prev_name = ""; - register const struct mn10300_opcode *op; + const struct mn10300_opcode *op; mn10300_hash = hash_new (); @@ -1197,12 +939,8 @@ md_begin () static symbolS *GOT_symbol; -static inline int mn10300_check_fixup PARAMS ((struct mn10300_fixup *)); -static inline int mn10300_PIC_related_p PARAMS ((symbolS *)); - static inline int -mn10300_PIC_related_p (sym) - symbolS *sym; +mn10300_PIC_related_p (symbolS *sym) { expressionS *exp; @@ -1220,8 +958,7 @@ mn10300_PIC_related_p (sym) } static inline int -mn10300_check_fixup (fixup) - struct mn10300_fixup *fixup; +mn10300_check_fixup (struct mn10300_fixup *fixup) { expressionS *exp = &fixup->exp; @@ -1267,10 +1004,7 @@ mn10300_check_fixup (fixup) } void -mn10300_cons_fix_new (frag, off, size, exp) - fragS *frag; - int off, size; - expressionS *exp; +mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp) { struct mn10300_fixup fixup; @@ -1329,9 +1063,162 @@ mn10300_cons_fix_new (frag, off, size, exp) fix_new_exp (frag, off, size, &fixup.exp, 0, fixup.reloc); } +static bfd_boolean +check_operand (const struct mn10300_operand *operand, + offsetT val) +{ + /* No need to check 32bit operands for a bit. Note that + MN10300_OPERAND_SPLIT is an implicit 32bit operand. */ + if (operand->bits != 32 + && (operand->flags & MN10300_OPERAND_SPLIT) == 0) + { + long min, max; + offsetT test; + int bits; + + bits = operand->bits; + if (operand->flags & MN10300_OPERAND_24BIT) + bits = 24; + + if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) + { + max = (1 << (bits - 1)) - 1; + min = - (1 << (bits - 1)); + } + else + { + max = (1 << bits) - 1; + min = 0; + } + + test = val; + + if (test < (offsetT) min || test > (offsetT) max) + return FALSE; + } + return TRUE; +} + +/* Insert an operand value into an instruction. */ + +static void +mn10300_insert_operand (unsigned long *insnp, + unsigned long *extensionp, + const struct mn10300_operand *operand, + offsetT val, + char *file, + unsigned int line, + unsigned int shift) +{ + /* No need to check 32bit operands for a bit. Note that + MN10300_OPERAND_SPLIT is an implicit 32bit operand. */ + if (operand->bits != 32 + && (operand->flags & MN10300_OPERAND_SPLIT) == 0) + { + long min, max; + offsetT test; + int bits; + + bits = operand->bits; + if (operand->flags & MN10300_OPERAND_24BIT) + bits = 24; + + if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) + { + max = (1 << (bits - 1)) - 1; + min = - (1 << (bits - 1)); + } + else + { + max = (1 << bits) - 1; + min = 0; + } + + test = val; + + if (test < (offsetT) min || test > (offsetT) max) + as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line); + } + + if ((operand->flags & MN10300_OPERAND_SPLIT) != 0) + { + *insnp |= (val >> (32 - operand->bits)) & ((1 << operand->bits) - 1); + *extensionp |= ((val & ((1 << (32 - operand->bits)) - 1)) + << operand->shift); + } + else if ((operand->flags & MN10300_OPERAND_24BIT) != 0) + { + *insnp |= (val >> (24 - operand->bits)) & ((1 << operand->bits) - 1); + *extensionp |= ((val & ((1 << (24 - operand->bits)) - 1)) + << operand->shift); + } + else if ((operand->flags & (MN10300_OPERAND_FSREG | MN10300_OPERAND_FDREG))) + { + /* See devo/opcodes/m10300-opc.c just before #define FSM0 for an + explanation of these variables. Note that FMT-implied shifts + are not taken into account for FP registers. */ + unsigned long mask_low, mask_high; + int shl_low, shr_high, shl_high; + + switch (operand->bits) + { + case 5: + /* Handle regular FP registers. */ + if (operand->shift >= 0) + { + /* This is an `m' register. */ + shl_low = operand->shift; + shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4; + } + else + { + /* This is an `n' register. */ + shl_low = -operand->shift; + shl_high = shl_low / 4; + } + + mask_low = 0x0f; + mask_high = 0x10; + shr_high = 4; + break; + + case 3: + /* Handle accumulators. */ + shl_low = -operand->shift; + shl_high = 0; + mask_low = 0x03; + mask_high = 0x04; + shr_high = 2; + break; + + default: + abort (); + } + *insnp |= ((((val & mask_high) >> shr_high) << shl_high) + | ((val & mask_low) << shl_low)); + } + else if ((operand->flags & MN10300_OPERAND_EXTENDED) == 0) + { + *insnp |= (((long) val & ((1 << operand->bits) - 1)) + << (operand->shift + shift)); + + if ((operand->flags & MN10300_OPERAND_REPEATED) != 0) + *insnp |= (((long) val & ((1 << operand->bits) - 1)) + << (operand->shift + shift + operand->bits)); + } + else + { + *extensionp |= (((long) val & ((1 << operand->bits) - 1)) + << (operand->shift + shift)); + + if ((operand->flags & MN10300_OPERAND_REPEATED) != 0) + *extensionp |= (((long) val & ((1 << operand->bits) - 1)) + << (operand->shift + shift + operand->bits)); + } +} + void -md_assemble (str) - char *str; +md_assemble (char *str) { char *s; struct mn10300_opcode *opcode; @@ -1717,8 +1604,8 @@ md_assemble (str) } } input_line_pointer++; - mn10300_insert_operand (&insn, &extension, operand, - value, (char *) NULL, 0, 0); + mn10300_insert_operand (& insn, & extension, operand, + value, NULL, 0, 0); goto keep_going; } @@ -1815,8 +1702,8 @@ md_assemble (str) else extra_shift = 0; - mn10300_insert_operand (&insn, &extension, operand, - ex.X_add_number, (char *) NULL, + mn10300_insert_operand (& insn, & extension, operand, + ex.X_add_number, NULL, 0, extra_shift); /* And note the register number in the register array. */ @@ -1830,16 +1717,15 @@ md_assemble (str) then promote it (ie this opcode does not match). */ if (operand->flags & (MN10300_OPERAND_PROMOTE | MN10300_OPERAND_RELAX) - && !check_operand (insn, operand, ex.X_add_number)) + && !check_operand (operand, ex.X_add_number)) { input_line_pointer = hold; str = hold; goto error; } - mn10300_insert_operand (&insn, &extension, operand, - ex.X_add_number, (char *) NULL, - 0, 0); + mn10300_insert_operand (& insn, & extension, operand, + ex.X_add_number, NULL, 0, 0); break; default: @@ -1870,7 +1756,6 @@ keep_going: while (*str == ' ' || *str == ',') ++str; - } /* Make sure we used all the operands! */ @@ -2262,15 +2147,13 @@ keep_going: then it is done here. */ arelent * -tc_gen_reloc (seg, fixp) - asection *seg ATTRIBUTE_UNUSED; - fixS *fixp; +tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) { arelent *reloc; - reloc = (arelent *) xmalloc (sizeof (arelent)); + reloc = xmalloc (sizeof (arelent)); reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); - if (reloc->howto == (reloc_howto_type *) NULL) + if (reloc->howto == NULL) { as_bad_where (fixp->fx_file, fixp->fx_line, _("reloc %d not supported by object file format"), @@ -2283,7 +2166,7 @@ tc_gen_reloc (seg, fixp) && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section) { fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy); - fixp->fx_subsy = 0; + fixp->fx_subsy = NULL; } if (fixp->fx_addsy && fixp->fx_subsy) @@ -2297,7 +2180,7 @@ tc_gen_reloc (seg, fixp) to a constant. */ if (S_GET_SEGMENT (fixp->fx_subsy) == seg) { - reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->addend = (reloc->address - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset); @@ -2375,7 +2258,7 @@ tc_gen_reloc (seg, fixp) } else { - reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->addend = fixp->fx_offset; } @@ -2383,9 +2266,7 @@ tc_gen_reloc (seg, fixp) } int -md_estimate_size_before_relax (fragp, seg) - fragS *fragp; - asection *seg; +md_estimate_size_before_relax (fragS *fragp, asection *seg) { if (fragp->fr_subtype == 6 && (!S_IS_DEFINED (fragp->fr_symbol) @@ -2409,10 +2290,9 @@ md_estimate_size_before_relax (fragp, seg) } long -md_pcrel_from (fixp) - fixS *fixp; +md_pcrel_from (fixS *fixp) { - if (fixp->fx_addsy != (symbolS *) NULL && !S_IS_DEFINED (fixp->fx_addsy)) + if (fixp->fx_addsy != NULL && !S_IS_DEFINED (fixp->fx_addsy)) { /* The symbol is undefined. Let the linker figure it out. */ return 0; @@ -2421,10 +2301,7 @@ md_pcrel_from (fixp) } void -md_apply_fix (fixP, valP, seg) - fixS * fixP; - valueT * valP; - segT seg; +md_apply_fix (fixS * fixP, valueT * valP, segT seg) { char * fixpos = fixP->fx_where + fixP->fx_frag->fr_literal; int size = 0; @@ -2446,7 +2323,7 @@ md_apply_fix (fixP, valP, seg) *valuep, and must use fx_offset instead. However, if the reloc is PC relative, we do want to use *valuep since it includes the result of md_pcrel_from. */ - if (fixP->fx_addsy != (symbolS *) NULL && ! fixP->fx_pcrel) + if (fixP->fx_addsy != NULL && ! fixP->fx_pcrel) value = fixP->fx_offset; /* If the fix is relative to a symbol which is not defined, or not @@ -2498,197 +2375,36 @@ md_apply_fix (fixP, valP, seg) adjusted. */ bfd_boolean -mn10300_fix_adjustable (fixp) - struct fix *fixp; +mn10300_fix_adjustable (struct fix *fixp) { if (TC_FORCE_RELOCATION_LOCAL (fixp)) - return 0; + return FALSE; if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) - return 0; + return FALSE; /* Do not adjust relocations involving symbols in code sections, because it breaks linker relaxations. This could be fixed in the linker, but this fix is simpler, and it pretty much only affects object size a little bit. */ if (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) - return 0; + return FALSE; /* Likewise, do not adjust symbols that won't be merged, or debug symbols, because they too break relaxation. We do want to adjust other mergable symbols, like .rodata, because code relaxations need section-relative symbols to properly relax them. */ if (! (S_GET_SEGMENT(fixp->fx_addsy)->flags & SEC_MERGE)) - return 0; + return FALSE; if (strncmp (S_GET_SEGMENT (fixp->fx_addsy)->name, ".debug", 6) == 0) - return 0; - - return 1; -} - -/* Insert an operand value into an instruction. */ - -static void -mn10300_insert_operand (insnp, extensionp, operand, val, file, line, shift) - unsigned long *insnp; - unsigned long *extensionp; - const struct mn10300_operand *operand; - offsetT val; - char *file; - unsigned int line; - unsigned int shift; -{ - /* No need to check 32bit operands for a bit. Note that - MN10300_OPERAND_SPLIT is an implicit 32bit operand. */ - if (operand->bits != 32 - && (operand->flags & MN10300_OPERAND_SPLIT) == 0) - { - long min, max; - offsetT test; - int bits; - - bits = operand->bits; - if (operand->flags & MN10300_OPERAND_24BIT) - bits = 24; - - if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) - { - max = (1 << (bits - 1)) - 1; - min = - (1 << (bits - 1)); - } - else - { - max = (1 << bits) - 1; - min = 0; - } - - test = val; - - if (test < (offsetT) min || test > (offsetT) max) - as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line); - } - - if ((operand->flags & MN10300_OPERAND_SPLIT) != 0) - { - *insnp |= (val >> (32 - operand->bits)) & ((1 << operand->bits) - 1); - *extensionp |= ((val & ((1 << (32 - operand->bits)) - 1)) - << operand->shift); - } - else if ((operand->flags & MN10300_OPERAND_24BIT) != 0) - { - *insnp |= (val >> (24 - operand->bits)) & ((1 << operand->bits) - 1); - *extensionp |= ((val & ((1 << (24 - operand->bits)) - 1)) - << operand->shift); - } - else if ((operand->flags & (MN10300_OPERAND_FSREG | MN10300_OPERAND_FDREG))) - { - /* See devo/opcodes/m10300-opc.c just before #define FSM0 for an - explanation of these variables. Note that FMT-implied shifts - are not taken into account for FP registers. */ - unsigned long mask_low, mask_high; - int shl_low, shr_high, shl_high; - - switch (operand->bits) - { - case 5: - /* Handle regular FP registers. */ - if (operand->shift >= 0) - { - /* This is an `m' register. */ - shl_low = operand->shift; - shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4; - } - else - { - /* This is an `n' register. */ - shl_low = -operand->shift; - shl_high = shl_low / 4; - } - - mask_low = 0x0f; - mask_high = 0x10; - shr_high = 4; - break; - - case 3: - /* Handle accumulators. */ - shl_low = -operand->shift; - shl_high = 0; - mask_low = 0x03; - mask_high = 0x04; - shr_high = 2; - break; - - default: - abort (); - } - *insnp |= ((((val & mask_high) >> shr_high) << shl_high) - | ((val & mask_low) << shl_low)); - } - else if ((operand->flags & MN10300_OPERAND_EXTENDED) == 0) - { - *insnp |= (((long) val & ((1 << operand->bits) - 1)) - << (operand->shift + shift)); - - if ((operand->flags & MN10300_OPERAND_REPEATED) != 0) - *insnp |= (((long) val & ((1 << operand->bits) - 1)) - << (operand->shift + shift + operand->bits)); - } - else - { - *extensionp |= (((long) val & ((1 << operand->bits) - 1)) - << (operand->shift + shift)); - - if ((operand->flags & MN10300_OPERAND_REPEATED) != 0) - *extensionp |= (((long) val & ((1 << operand->bits) - 1)) - << (operand->shift + shift + operand->bits)); - } -} - -static unsigned long -check_operand (insn, operand, val) - unsigned long insn ATTRIBUTE_UNUSED; - const struct mn10300_operand *operand; - offsetT val; -{ - /* No need to check 32bit operands for a bit. Note that - MN10300_OPERAND_SPLIT is an implicit 32bit operand. */ - if (operand->bits != 32 - && (operand->flags & MN10300_OPERAND_SPLIT) == 0) - { - long min, max; - offsetT test; - int bits; - - bits = operand->bits; - if (operand->flags & MN10300_OPERAND_24BIT) - bits = 24; - - if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) - { - max = (1 << (bits - 1)) - 1; - min = - (1 << (bits - 1)); - } - else - { - max = (1 << bits) - 1; - min = 0; - } - - test = val; + return FALSE; - if (test < (offsetT) min || test > (offsetT) max) - return 0; - else - return 1; - } - return 1; + return TRUE; } static void -set_arch_mach (mach) - int mach; +set_arch_mach (int mach) { if (!bfd_set_arch_mach (stdoutput, bfd_arch_mn10300, mach)) as_warn (_("could not set architecture and machine")); @@ -2696,11 +2412,8 @@ set_arch_mach (mach) current_machine = mach; } -static inline char * mn10300_end_of_match PARAMS ((char *, char *)); - static inline char * -mn10300_end_of_match (cont, what) - char *cont, *what; +mn10300_end_of_match (char *cont, char *what) { int len = strlen (what); @@ -2712,11 +2425,10 @@ mn10300_end_of_match (cont, what) } int -mn10300_parse_name (name, exprP, mode, nextcharP) - char const *name; - expressionS *exprP; - enum expr_mode mode; - char *nextcharP; +mn10300_parse_name (char const *name, + expressionS *exprP, + enum expr_mode mode, + char *nextcharP) { char *next = input_line_pointer; char *next_end; @@ -2780,3 +2492,13 @@ mn10300_parse_name (name, exprP, mode, nextcharP) return 1; } + +/* The target specific pseudo-ops which we support. */ +const pseudo_typeS md_pseudo_table[] = +{ + { "am30", set_arch_mach, AM30 }, + { "am33", set_arch_mach, AM33 }, + { "am33_2", set_arch_mach, AM33_2 }, + { "mn10300", set_arch_mach, MN103 }, + {NULL, 0, 0} +}; -- 2.30.2