X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=bfd%2Felf32-m32c.c;h=8436fb10fb4f805d5130e3f611cfb1c1ed4b2f03;hb=daa4adae63f91377fe9b3e8d7421a0ceb4a51e26;hp=3ddab6e8d259e0c65893fbbac8012cf9b5feec33;hpb=b90efa5b79ac1524ec260f8eb89d1be37e0219a7;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c index 3ddab6e8d2..8436fb10fb 100644 --- a/bfd/elf32-m32c.c +++ b/bfd/elf32-m32c.c @@ -1,5 +1,5 @@ /* M16C/M32C specific support for 32-bit ELF. - Copyright (C) 2005-2015 Free Software Foundation, Inc. + Copyright (C) 2005-2016 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -40,6 +40,8 @@ void dump_symtab (bfd *, void *, void *); #endif static bfd_boolean m32c_elf_relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again); +static bfd_reloc_status_type m32c_apply_reloc_24 + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static reloc_howto_type m32c_elf_howto_table [] = @@ -47,11 +49,11 @@ static reloc_howto_type m32c_elf_howto_table [] = /* This reloc does nothing. */ HOWTO (R_M32C_NONE, /* type */ 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + 3, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ + complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_M32C_NONE", /* name */ FALSE, /* partial_inplace */ @@ -83,7 +85,7 @@ static reloc_howto_type m32c_elf_howto_table [] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + m32c_apply_reloc_24, /* special_function */ "R_M32C_24", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -264,7 +266,7 @@ m32c_reloc_type_lookup { unsigned int i; - for (i = ARRAY_SIZE (m32c_reloc_map); --i;) + for (i = ARRAY_SIZE (m32c_reloc_map); i--;) if (m32c_reloc_map [i].bfd_reloc_val == code) return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val]; @@ -299,7 +301,7 @@ m32c_info_to_howto_rela r_type = ELF32_R_TYPE (dst->r_info); if (r_type >= (unsigned int) R_M32C_max) { - _bfd_error_handler (_("%A: invalid M32C reloc number: %d"), abfd, r_type); + _bfd_error_handler (_("%B: invalid M32C reloc number: %d"), abfd, r_type); r_type = 0; } cache_ptr->howto = & m32c_elf_howto_table [r_type]; @@ -307,6 +309,48 @@ m32c_info_to_howto_rela +/* Apply R_M32C_24 relocations. We have to do this because it's not a + power-of-two size, and the generic code may think it overruns the + section if it's right at the end. + + Must return something other than bfd_reloc_continue to avoid the + above problem. Typical return values include bfd_reloc_ok or + bfd_reloc_overflow. +*/ + +static bfd_reloc_status_type m32c_apply_reloc_24 (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol, + void *vdata_start ATTRIBUTE_UNUSED, + asection *input_section, + bfd *ibfd ATTRIBUTE_UNUSED, + char **error_msg ATTRIBUTE_UNUSED) +{ + bfd_vma relocation; + bfd_reloc_status_type s; + + s = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, + vdata_start, + input_section, ibfd, error_msg); + if (s != bfd_reloc_continue) + return s; + + /* Get symbol value. (Common symbols are special.) */ + if (bfd_is_com_section (symbol->section)) + relocation = 0; + else + relocation = symbol->value; + + relocation += symbol->section->output_offset; + + /* Add in supplied addend. */ + relocation += reloc_entry->addend; + + reloc_entry->addend = relocation; + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; +} + /* Relocate an M32C ELF section. There is some attempt to make this function usable for many architectures, both USE_REL and USE_RELA ['twould be nice if such a critter existed], @@ -433,7 +477,7 @@ m32c_elf_relocate_section } else if (h->root.type == bfd_link_hash_undefweak) ; - else if (!info->relocatable) + else if (!bfd_link_relocatable (info)) { if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, @@ -446,7 +490,7 @@ m32c_elf_relocate_section RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, 1, relend, howto, 0, contents); - if (info->relocatable) + if (bfd_link_relocatable (info)) { /* This is a relocatable link. We don't have to change anything, unless the reloc is against a section symbol, @@ -535,9 +579,32 @@ m32c_elf_relocate_section printf ("\n"); } #endif - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, relocation, - rel->r_addend); + switch (ELF32_R_TYPE(rel->r_info)) + { + case R_M32C_24: + /* Like m32c_apply_reloc_24, we must handle this one separately. */ + relocation += rel->r_addend; + + /* Sanity check the address. */ + if (rel->r_offset + 3 + > bfd_get_section_limit_octets (input_bfd, input_section)) + r = bfd_reloc_outofrange; + else + { + bfd_put_8 (input_bfd, relocation & 0xff, contents + rel->r_offset); + bfd_put_8 (input_bfd, (relocation >> 8) & 0xff, contents + rel->r_offset + 1); + bfd_put_8 (input_bfd, (relocation >> 16) & 0xff, contents + rel->r_offset + 2); + r = bfd_reloc_ok; + } + + break; + + default: + r = _bfd_final_link_relocate (howto, input_bfd, input_section, + contents, rel->r_offset, relocation, + rel->r_addend); + break; + } if (r != bfd_reloc_ok) { @@ -604,7 +671,7 @@ m32c_elf_check_relocs asection *splt; bfd *dynobj; - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; @@ -726,7 +793,7 @@ m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *dynobj; asection *splt; - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; dynobj = elf_hash_table (info)->dynobj; @@ -1098,7 +1165,7 @@ m32c_elf_relax_plt_section (asection *splt, /* Assume nothing changes. */ *again = FALSE; - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; /* Quick check for an empty plt. */ @@ -1400,14 +1467,17 @@ m32c_elf_relax_section /* We don't have to do anything for a relocatable link, if this section does not have relocs, or if this is not a code section. */ - if (link_info->relocatable + if (bfd_link_relocatable (link_info) || (sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0) return TRUE; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; + symtab_hdr = & elf_symtab_hdr (abfd); + if (elf_symtab_shndx_list (abfd)) + shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr; + else + shndx_hdr = NULL; /* Get the section contents. */ if (elf_section_data (sec)->this_hdr.contents != NULL) @@ -1428,7 +1498,7 @@ m32c_elf_relax_section symtab_hdr->contents = (bfd_byte *) intsyms; } - if (shndx_hdr->sh_size != 0) + if (shndx_hdr && shndx_hdr->sh_size != 0) { bfd_size_type amt; @@ -1976,8 +2046,16 @@ m32c_elf_relax_delete_bytes isymend = isym + symtab_hdr->sh_info; sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); - shndx_hdr = & elf_tdata (abfd)->symtab_shndx_hdr; - shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents; + if (elf_symtab_shndx_list (abfd)) + { + shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr; + shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents; + } + else + { + shndx_hdr = NULL; + shndx_buf = NULL; + } shndx = shndx_buf; for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))