X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcoff-sh.c;h=2236884138c0cb7eb07598a990cc470e24a26e83;hb=421d1616230a78449dc2f5abb60f03d38b96c3cf;hp=e505a1af9eb3f8dbcfe78c7416caf22c70a708dc;hpb=abd8680d6efd97e7ba848a6392ee3ad72be18cd0;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c index e505a1af9e..2236884138 100644 --- a/bfd/coff-sh.c +++ b/bfd/coff-sh.c @@ -1,66 +1,122 @@ -/* BFD back-end for Hitachi Super-H COFF binaries. - Copyright 1993, 94, 95, 96, 97, 98, 1999, 2000 Free Software Foundation, Inc. +/* BFD back-end for Renesas Super-H COFF binaries. + Copyright (C) 1993-2020 Free Software Foundation, Inc. Contributed by Cygnus Support. Written by Steve Chamberlain, . Relaxing code written by Ian Lance Taylor, . -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" +#include "libiberty.h" #include "libbfd.h" #include "bfdlink.h" #include "coff/sh.h" #include "coff/internal.h" + +#undef bfd_pe_print_pdata + +#ifdef COFF_WITH_PE +#include "coff/pe.h" + +#ifndef COFF_IMAGE_WITH_PE +static bfd_boolean sh_align_load_span + (bfd *, asection *, bfd_byte *, + bfd_boolean (*) (bfd *, asection *, void *, bfd_byte *, bfd_vma), + void *, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, bfd_boolean *); + +#define _bfd_sh_align_load_span sh_align_load_span +#endif + +#define bfd_pe_print_pdata _bfd_pe_print_ce_compressed_pdata + +#else + +#define bfd_pe_print_pdata NULL + +#endif /* COFF_WITH_PE. */ + #include "libcoff.h" /* Internal functions. */ -static bfd_reloc_status_type sh_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static long get_symbol_value PARAMS ((asymbol *)); -static boolean sh_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); -static boolean sh_relax_delete_bytes - PARAMS ((bfd *, asection *, bfd_vma, int)); -static const struct sh_opcode *sh_insn_info PARAMS ((unsigned int)); -static boolean sh_align_loads - PARAMS ((bfd *, asection *, struct internal_reloc *, bfd_byte *, boolean *)); -static boolean sh_swap_insns - PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma)); -static boolean sh_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); -static bfd_byte *sh_coff_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean, asymbol **)); +#ifdef COFF_WITH_PE +/* Can't build import tables with 2**4 alignment. */ +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2 +#else /* Default section alignment to 2**4. */ -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (4) +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 4 +#endif + +#ifdef COFF_IMAGE_WITH_PE +/* Align PE executables. */ +#define COFF_PAGE_SIZE 0x1000 +#endif /* Generate long file names. */ #define COFF_LONG_FILENAMES +#ifdef COFF_WITH_PE +/* Return TRUE if this relocation should + appear in the output .reloc section. */ + +static bfd_boolean +in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, + reloc_howto_type * howto) +{ + return ! howto->pc_relative && howto->type != R_SH_IMAGEBASE; +} +#endif + +static bfd_reloc_status_type +sh_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); +static bfd_boolean +sh_relocate_section (bfd *, struct bfd_link_info *, bfd *, asection *, + bfd_byte *, struct internal_reloc *, + struct internal_syment *, asection **); +static bfd_boolean +sh_align_loads (bfd *, asection *, struct internal_reloc *, + bfd_byte *, bfd_boolean *); + /* The supported relocations. There are a lot of relocations defined in coff/internal.h which we do not expect to ever see. */ static reloc_howto_type sh_coff_howtos[] = { EMPTY_HOWTO (0), EMPTY_HOWTO (1), +#ifdef COFF_WITH_PE + /* Windows CE */ + HOWTO (R_SH_IMM32CE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + sh_reloc, /* special_function */ + "r_imm32ce", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +#else EMPTY_HOWTO (2), +#endif EMPTY_HOWTO (3), /* R_SH_PCREL8 */ EMPTY_HOWTO (4), /* R_SH_PCREL16 */ EMPTY_HOWTO (5), /* R_SH_HIGH8 */ @@ -73,15 +129,15 @@ static reloc_howto_type sh_coff_howtos[] = 1, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_pcdisp8by2", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xff, /* src_mask */ 0xff, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ EMPTY_HOWTO (11), /* R_SH_PCDISP8 */ @@ -89,15 +145,15 @@ static reloc_howto_type sh_coff_howtos[] = 1, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 12, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_pcdisp12by2", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xfff, /* src_mask */ 0xfff, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ EMPTY_HOWTO (13), @@ -105,18 +161,34 @@ static reloc_howto_type sh_coff_howtos[] = 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_imm32", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ EMPTY_HOWTO (15), +#ifdef COFF_WITH_PE + HOWTO (R_SH_IMAGEBASE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + sh_reloc, /* special_function */ + "rva32", /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +#else EMPTY_HOWTO (16), /* R_SH_IMM8 */ +#endif EMPTY_HOWTO (17), /* R_SH_IMM8BY2 */ EMPTY_HOWTO (18), /* R_SH_IMM8BY4 */ EMPTY_HOWTO (19), /* R_SH_IMM4 */ @@ -127,169 +199,169 @@ static reloc_howto_type sh_coff_howtos[] = 1, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_pcrelimm8by2", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xff, /* src_mask */ 0xff, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ HOWTO (R_SH_PCRELIMM8BY4, /* type */ 2, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ - true, /* pc_relative */ + TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_pcrelimm8by4", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xff, /* src_mask */ 0xff, /* dst_mask */ - true), /* pcrel_offset */ + TRUE), /* pcrel_offset */ HOWTO (R_SH_IMM16, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_imm16", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffff, /* src_mask */ 0xffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_SWITCH16, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_switch16", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffff, /* src_mask */ 0xffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_SWITCH32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_switch32", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_USES, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_uses", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffff, /* src_mask */ 0xffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_COUNT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_count", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_ALIGN, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_align", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_CODE, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_code", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_DATA, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_data", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_LABEL, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_label", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ + FALSE), /* pcrel_offset */ HOWTO (R_SH_SWITCH8, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ sh_reloc, /* special_function */ "r_switch8", /* name */ - true, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xff, /* src_mask */ 0xff, /* dst_mask */ - false) /* pcrel_offset */ + FALSE) /* pcrel_offset */ }; #define SH_COFF_HOWTO_COUNT (sizeof sh_coff_howtos / sizeof sh_coff_howtos[0]) @@ -303,9 +375,10 @@ static reloc_howto_type sh_coff_howtos[] = /* FIXME: This should not be set here. */ #define __A_MAGIC_SET__ +#ifndef COFF_WITH_PE /* Swap the r_offset field in and out. */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 +#define SWAP_IN_RELOC_OFFSET H_GET_32 +#define SWAP_OUT_RELOC_OFFSET H_PUT_32 /* Swap out extra information in the reloc structure. */ #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ @@ -315,18 +388,18 @@ static reloc_howto_type sh_coff_howtos[] = dst->r_stuff[1] = 'C'; \ } \ while (0) +#endif /* Get the value of a symbol, when performing a relocation. */ static long -get_symbol_value (symbol) - asymbol *symbol; -{ +get_symbol_value (asymbol *symbol) +{ bfd_vma relocation; if (bfd_is_com_section (symbol->section)) - relocation = 0; - else + relocation = 0; + else relocation = (symbol->value + symbol->section->output_section->vma + symbol->section->output_offset); @@ -334,6 +407,119 @@ get_symbol_value (symbol) return relocation; } +#ifdef COFF_WITH_PE +/* Convert an rtype to howto for the COFF backend linker. + Copied from coff-i386. */ +#define coff_rtype_to_howto coff_sh_rtype_to_howto + + +static reloc_howto_type * +coff_sh_rtype_to_howto (bfd * abfd ATTRIBUTE_UNUSED, + asection * sec, + struct internal_reloc * rel, + struct coff_link_hash_entry * h, + struct internal_syment * sym, + bfd_vma * addendp) +{ + reloc_howto_type * howto; + + howto = sh_coff_howtos + rel->r_type; + + *addendp = 0; + + if (howto->pc_relative) + *addendp += sec->vma; + + if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) + { + /* This is a common symbol. The section contents include the + size (sym->n_value) as an addend. The relocate_section + function will be adding in the final value of the symbol. We + need to subtract out the current size in order to get the + correct result. */ + BFD_ASSERT (h != NULL); + } + + if (howto->pc_relative) + { + *addendp -= 4; + + /* If the symbol is defined, then the generic code is going to + add back the symbol value in order to cancel out an + adjustment it made to the addend. However, we set the addend + to 0 at the start of this function. We need to adjust here, + to avoid the adjustment the generic code will make. FIXME: + This is getting a bit hackish. */ + if (sym != NULL && sym->n_scnum != 0) + *addendp -= sym->n_value; + } + + if (rel->r_type == R_SH_IMAGEBASE) + *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase; + + return howto; +} + +#endif /* COFF_WITH_PE */ + +/* This structure is used to map BFD reloc codes to SH PE relocs. */ +struct shcoff_reloc_map +{ + bfd_reloc_code_real_type bfd_reloc_val; + unsigned char shcoff_reloc_val; +}; + +#ifdef COFF_WITH_PE +/* An array mapping BFD reloc codes to SH PE relocs. */ +static const struct shcoff_reloc_map sh_reloc_map[] = +{ + { BFD_RELOC_32, R_SH_IMM32CE }, + { BFD_RELOC_RVA, R_SH_IMAGEBASE }, + { BFD_RELOC_CTOR, R_SH_IMM32CE }, +}; +#else +/* An array mapping BFD reloc codes to SH PE relocs. */ +static const struct shcoff_reloc_map sh_reloc_map[] = +{ + { BFD_RELOC_32, R_SH_IMM32 }, + { BFD_RELOC_CTOR, R_SH_IMM32 }, +}; +#endif + +/* Given a BFD reloc code, return the howto structure for the + corresponding SH PE reloc. */ +#define coff_bfd_reloc_type_lookup sh_coff_reloc_type_lookup +#define coff_bfd_reloc_name_lookup sh_coff_reloc_name_lookup + +static reloc_howto_type * +sh_coff_reloc_type_lookup (bfd *abfd, + bfd_reloc_code_real_type code) +{ + unsigned int i; + + for (i = ARRAY_SIZE (sh_reloc_map); i--;) + if (sh_reloc_map[i].bfd_reloc_val == code) + return &sh_coff_howtos[(int) sh_reloc_map[i].shcoff_reloc_val]; + + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + abfd, (unsigned int) code); + return NULL; +} + +static reloc_howto_type * +sh_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; i < sizeof (sh_coff_howtos) / sizeof (sh_coff_howtos[0]); i++) + if (sh_coff_howtos[i].name != NULL + && strcasecmp (sh_coff_howtos[i].name, r_name) == 0) + return &sh_coff_howtos[i]; + + return NULL; +} + /* This macro is used in coffcode.h to get the howto corresponding to an internal reloc. */ @@ -345,22 +531,22 @@ get_symbol_value (symbol) /* This is the same as the macro in coffcode.h, except that it copies r_offset into reloc_entry->addend for some relocs. */ -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ + { \ + coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ + if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ + coffsym = (obj_symbols (abfd) \ + + (cache_ptr->sym_ptr_ptr - symbols)); \ + else if (ptr) \ + coffsym = coff_symbol_from (ptr); \ + if (coffsym != (coff_symbol_type *) NULL \ + && coffsym->native->u.syment.n_scnum == 0) \ + cache_ptr->addend = 0; \ + else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ + && ptr->section != (asection *) NULL) \ + cache_ptr->addend = - (ptr->section->vma + ptr->value); \ + else \ + cache_ptr->addend = 0; \ if ((reloc).r_type == R_SH_SWITCH8 \ || (reloc).r_type == R_SH_SWITCH16 \ || (reloc).r_type == R_SH_SWITCH32 \ @@ -373,17 +559,15 @@ get_symbol_value (symbol) /* This is the howto function for the SH relocations. */ static bfd_reloc_status_type -sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - unsigned long insn; +sh_reloc (bfd * abfd, + arelent * reloc_entry, + asymbol * symbol_in, + void * data, + asection * input_section, + bfd * output_bfd, + char ** error_message ATTRIBUTE_UNUSED) +{ + bfd_vma insn; bfd_vma sym_value; unsigned short r_type; bfd_vma addr = reloc_entry->address; @@ -401,6 +585,10 @@ sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, /* Almost all relocs have to do with relaxing. If any work must be done for them, it has been done in sh_relax_section. */ if (r_type != R_SH_IMM32 +#ifdef COFF_WITH_PE + && r_type != R_SH_IMM32CE + && r_type != R_SH_IMAGEBASE +#endif && (r_type != R_SH_PCDISP || (symbol_in->flags & BSF_LOCAL) != 0)) return bfd_reloc_ok; @@ -409,15 +597,29 @@ sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, && bfd_is_und_section (symbol_in->section)) return bfd_reloc_undefined; + if (addr > input_section->size) + return bfd_reloc_outofrange; + sym_value = get_symbol_value (symbol_in); switch (r_type) { case R_SH_IMM32: +#ifdef COFF_WITH_PE + case R_SH_IMM32CE: +#endif + insn = bfd_get_32 (abfd, hit_data); + insn += sym_value + reloc_entry->addend; + bfd_put_32 (abfd, insn, hit_data); + break; +#ifdef COFF_WITH_PE + case R_SH_IMAGEBASE: insn = bfd_get_32 (abfd, hit_data); insn += sym_value + reloc_entry->addend; + insn -= pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase; bfd_put_32 (abfd, insn, hit_data); break; +#endif case R_SH_PCDISP: insn = bfd_get_16 (abfd, hit_data); sym_value += reloc_entry->addend; @@ -425,12 +627,10 @@ sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, + input_section->output_offset + addr + 4); - sym_value += (insn & 0xfff) << 1; - if (insn & 0x800) - sym_value -= 0x1000; - insn = (insn & 0xf000) | (sym_value & 0xfff); + sym_value += (((insn & 0xfff) ^ 0x800) - 0x800) << 1; + insn = (insn & 0xf000) | ((sym_value >> 1) & 0xfff); bfd_put_16 (abfd, insn, hit_data); - if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000) + if (sym_value + 0x1000 >= 0x2000 || (sym_value & 1) != 0) return bfd_reloc_overflow; break; default: @@ -456,6 +656,9 @@ sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, #include "coffcode.h" +static bfd_boolean +sh_relax_delete_bytes (bfd *, asection *, bfd_vma, int); + /* This function handles relaxing on the SH. Function calls on the SH look like this: @@ -499,42 +702,40 @@ sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, align load and store instructions on four byte boundaries if we can, by swapping them with one of the adjacent instructions. */ -static boolean -sh_relax_section (abfd, sec, link_info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - boolean *again; +static bfd_boolean +sh_relax_section (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + bfd_boolean *again) { struct internal_reloc *internal_relocs; - struct internal_reloc *free_relocs = NULL; - boolean have_code; + bfd_boolean have_code; struct internal_reloc *irel, *irelend; bfd_byte *contents = NULL; - bfd_byte *free_contents = NULL; - *again = false; + *again = FALSE; - if (link_info->relocateable + if (bfd_link_relocatable (link_info) || (sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0) - return true; + return TRUE; - /* If this is the first time we have been called for this section, - initialize the cooked size. */ - if (sec->_cooked_size == 0) - sec->_cooked_size = sec->_raw_size; + if (coff_section_data (abfd, sec) == NULL) + { + bfd_size_type amt = sizeof (struct coff_section_tdata); + sec->used_by_bfd = bfd_zalloc (abfd, amt); + if (sec->used_by_bfd == NULL) + return FALSE; + } internal_relocs = (_bfd_coff_read_internal_relocs (abfd, sec, link_info->keep_memory, - (bfd_byte *) NULL, false, + (bfd_byte *) NULL, FALSE, (struct internal_reloc *) NULL)); if (internal_relocs == NULL) goto error_return; - if (! link_info->keep_memory) - free_relocs = internal_relocs; - have_code = false; + have_code = FALSE; irelend = internal_relocs + sec->reloc_count; for (irel = internal_relocs; irel < irelend; irel++) @@ -546,7 +747,7 @@ sh_relax_section (abfd, sec, link_info, again) bfd_signed_vma foff; if (irel->r_type == R_SH_CODE) - have_code = true; + have_code = TRUE; if (irel->r_type != R_SH_USES) continue; @@ -554,34 +755,28 @@ sh_relax_section (abfd, sec, link_info, again) /* Get the section contents. */ if (contents == NULL) { - if (coff_section_data (abfd, sec) != NULL - && coff_section_data (abfd, sec)->contents != NULL) + if (coff_section_data (abfd, sec)->contents != NULL) contents = coff_section_data (abfd, sec)->contents; else { - contents = (bfd_byte *) bfd_malloc (sec->_raw_size); - if (contents == NULL) - goto error_return; - free_contents = contents; - - if (! bfd_get_section_contents (abfd, sec, contents, - (file_ptr) 0, sec->_raw_size)) + if (!bfd_malloc_and_get_section (abfd, sec, &contents)) goto error_return; } } /* The r_offset field of the R_SH_USES reloc will point us to - the register load. The 4 is because the r_offset field is - computed as though it were a jump offset, which are based - from 4 bytes after the jump instruction. */ + the register load. The 4 is because the r_offset field is + computed as though it were a jump offset, which are based + from 4 bytes after the jump instruction. */ laddr = irel->r_vaddr - sec->vma + 4; /* Careful to sign extend the 32-bit offset. */ laddr += ((irel->r_offset & 0xffffffff) ^ 0x80000000) - 0x80000000; - if (laddr >= sec->_raw_size) + if (laddr >= sec->size) { - (*_bfd_error_handler) ("%s: 0x%lx: warning: bad R_SH_USES offset", - bfd_get_filename (abfd), - (unsigned long) irel->r_vaddr); + /* xgettext: c-format */ + _bfd_error_handler + (_("%pB: %#" PRIx64 ": warning: bad R_SH_USES offset"), + abfd, (uint64_t) irel->r_vaddr); continue; } insn = bfd_get_16 (abfd, contents + laddr); @@ -589,42 +784,53 @@ sh_relax_section (abfd, sec, link_info, again) /* If the instruction is not mov.l NN,rN, we don't know what to do. */ if ((insn & 0xf000) != 0xd000) { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr, insn)); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: %#" PRIx64 ": warning: R_SH_USES points to unrecognized insn %#x"), + abfd, (uint64_t) irel->r_vaddr, insn); continue; } /* Get the address from which the register is being loaded. The - displacement in the mov.l instruction is quadrupled. It is a - displacement from four bytes after the movl instruction, but, - before adding in the PC address, two least significant bits - of the PC are cleared. We assume that the section is aligned - on a four byte boundary. */ + displacement in the mov.l instruction is quadrupled. It is a + displacement from four bytes after the movl instruction, but, + before adding in the PC address, two least significant bits + of the PC are cleared. We assume that the section is aligned + on a four byte boundary. */ paddr = insn & 0xff; paddr *= 4; - paddr += (laddr + 4) &~ 3; - if (paddr >= sec->_raw_size) + paddr += (laddr + 4) &~ (bfd_vma) 3; + if (paddr >= sec->size) { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: bad R_SH_USES load offset", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr)); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: %#" PRIx64 ": warning: bad R_SH_USES load offset"), + abfd, (uint64_t) irel->r_vaddr); continue; } /* Get the reloc for the address from which the register is - being loaded. This reloc will tell us which function is - actually being called. */ + being loaded. This reloc will tell us which function is + actually being called. */ paddr += sec->vma; for (irelfn = internal_relocs; irelfn < irelend; irelfn++) if (irelfn->r_vaddr == paddr - && irelfn->r_type == R_SH_IMM32) +#ifdef COFF_WITH_PE + && (irelfn->r_type == R_SH_IMM32 + || irelfn->r_type == R_SH_IMM32CE + || irelfn->r_type == R_SH_IMAGEBASE) + +#else + && irelfn->r_type == R_SH_IMM32 +#endif + ) break; if (irelfn >= irelend) { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: could not find expected reloc", - bfd_get_filename (abfd), (unsigned long) paddr)); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: %#" PRIx64 ": warning: could not find expected reloc"), + abfd, (uint64_t) paddr); continue; } @@ -638,9 +844,10 @@ sh_relax_section (abfd, sec, link_info, again) &sym); if (sym.n_scnum != 0 && sym.n_scnum != sec->target_index) { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: symbol in unexpected section", - bfd_get_filename (abfd), (unsigned long) paddr)); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: %#" PRIx64 ": warning: symbol in unexpected section"), + abfd, (uint64_t) paddr); continue; } @@ -661,8 +868,8 @@ sh_relax_section (abfd, sec, link_info, again) && h->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. */ + symbol. Just ignore it--it will be caught by the + regular reloc processing. */ continue; } @@ -696,49 +903,40 @@ sh_relax_section (abfd, sec, link_info, again) that would be more work, but would require less memory when the linker is run. */ - if (coff_section_data (abfd, sec) == NULL) - { - sec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (sec->used_by_bfd == NULL) - goto error_return; - } - coff_section_data (abfd, sec)->relocs = internal_relocs; - coff_section_data (abfd, sec)->keep_relocs = true; - free_relocs = NULL; + coff_section_data (abfd, sec)->keep_relocs = TRUE; coff_section_data (abfd, sec)->contents = contents; - coff_section_data (abfd, sec)->keep_contents = true; - free_contents = NULL; + coff_section_data (abfd, sec)->keep_contents = TRUE; - obj_coff_keep_syms (abfd) = true; + obj_coff_keep_syms (abfd) = TRUE; /* Replace the jsr with a bsr. */ /* Change the R_SH_USES reloc into an R_SH_PCDISP reloc, and - replace the jsr with a bsr. */ + replace the jsr with a bsr. */ irel->r_type = R_SH_PCDISP; irel->r_symndx = irelfn->r_symndx; if (sym.n_sclass != C_EXT) { /* If this needs to be changed because of future relaxing, - it will be handled here like other internal PCDISP - relocs. */ + it will be handled here like other internal PCDISP + relocs. */ bfd_put_16 (abfd, - 0xb000 | ((foff >> 1) & 0xfff), + (bfd_vma) 0xb000 | ((foff >> 1) & 0xfff), contents + irel->r_vaddr - sec->vma); } else { /* We can't fully resolve this yet, because the external - symbol value may be changed by future relaxing. We let - the final link phase handle it. */ - bfd_put_16 (abfd, 0xb000, contents + irel->r_vaddr - sec->vma); + symbol value may be changed by future relaxing. We let + the final link phase handle it. */ + bfd_put_16 (abfd, (bfd_vma) 0xb000, + contents + irel->r_vaddr - sec->vma); } /* See if there is another R_SH_USES reloc referring to the same - register load. */ + register load. */ for (irelscan = internal_relocs; irelscan < irelend; irelscan++) if (irelscan->r_type == R_SH_USES && laddr == irelscan->r_vaddr - sec->vma + 4 + irelscan->r_offset) @@ -753,8 +951,8 @@ sh_relax_section (abfd, sec, link_info, again) } /* Look for a R_SH_COUNT reloc on the location where the - function address is stored. Do this before deleting any - bytes, to avoid confusion about the address. */ + function address is stored. Do this before deleting any + bytes, to avoid confusion about the address. */ for (irelcount = internal_relocs; irelcount < irelend; irelcount++) if (irelcount->r_vaddr == paddr && irelcount->r_type == R_SH_COUNT) @@ -765,34 +963,35 @@ sh_relax_section (abfd, sec, link_info, again) goto error_return; /* That will change things, so, just in case it permits some - other function call to come within range, we should relax - again. Note that this is not required, and it may be slow. */ - *again = true; + other function call to come within range, we should relax + again. Note that this is not required, and it may be slow. */ + *again = TRUE; /* Now check whether we got a COUNT reloc. */ if (irelcount >= irelend) { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: could not find expected COUNT reloc", - bfd_get_filename (abfd), (unsigned long) paddr)); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: %#" PRIx64 ": warning: could not find expected COUNT reloc"), + abfd, (uint64_t) paddr); continue; } /* The number of uses is stored in the r_offset field. We've - just deleted one. */ + just deleted one. */ if (irelcount->r_offset == 0) { - ((*_bfd_error_handler) ("%s: 0x%lx: warning: bad count", - bfd_get_filename (abfd), - (unsigned long) paddr)); + /* xgettext: c-format */ + _bfd_error_handler (_("%pB: %#" PRIx64 ": warning: bad count"), + abfd, (uint64_t) paddr); continue; } --irelcount->r_offset; /* If there are no more uses, we can delete the address. Reload - the address from irelfn, in case it was changed by the - previous call to sh_relax_delete_bytes. */ + the address from irelfn, in case it was changed by the + previous call to sh_relax_delete_bytes. */ if (irelcount->r_offset == 0) { if (! sh_relax_delete_bytes (abfd, sec, @@ -807,23 +1006,16 @@ sh_relax_section (abfd, sec, link_info, again) byte boundaries. */ if (have_code) { - boolean swapped; + bfd_boolean swapped; /* Get the section contents. */ if (contents == NULL) { - if (coff_section_data (abfd, sec) != NULL - && coff_section_data (abfd, sec)->contents != NULL) + if (coff_section_data (abfd, sec)->contents != NULL) contents = coff_section_data (abfd, sec)->contents; else { - contents = (bfd_byte *) bfd_malloc (sec->_raw_size); - if (contents == NULL) - goto error_return; - free_contents = contents; - - if (! bfd_get_section_contents (abfd, sec, contents, - (file_ptr) 0, sec->_raw_size)) + if (!bfd_malloc_and_get_section (abfd, sec, &contents)) goto error_return; } } @@ -833,69 +1025,52 @@ sh_relax_section (abfd, sec, link_info, again) if (swapped) { - if (coff_section_data (abfd, sec) == NULL) - { - sec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (sec->used_by_bfd == NULL) - goto error_return; - } - coff_section_data (abfd, sec)->relocs = internal_relocs; - coff_section_data (abfd, sec)->keep_relocs = true; - free_relocs = NULL; + coff_section_data (abfd, sec)->keep_relocs = TRUE; coff_section_data (abfd, sec)->contents = contents; - coff_section_data (abfd, sec)->keep_contents = true; - free_contents = NULL; + coff_section_data (abfd, sec)->keep_contents = TRUE; - obj_coff_keep_syms (abfd) = true; + obj_coff_keep_syms (abfd) = TRUE; } } - if (free_relocs != NULL) + if (internal_relocs != NULL + && internal_relocs != coff_section_data (abfd, sec)->relocs) { - free (free_relocs); - free_relocs = NULL; + if (! link_info->keep_memory) + free (internal_relocs); + else + coff_section_data (abfd, sec)->relocs = internal_relocs; } - if (free_contents != NULL) + if (contents != NULL && contents != coff_section_data (abfd, sec)->contents) { if (! link_info->keep_memory) - free (free_contents); + free (contents); else - { - /* Cache the section contents for coff_link_input_bfd. */ - if (coff_section_data (abfd, sec) == NULL) - { - sec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (sec->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, sec)->relocs = NULL; - } - coff_section_data (abfd, sec)->contents = contents; - } + /* Cache the section contents for coff_link_input_bfd. */ + coff_section_data (abfd, sec)->contents = contents; } - return true; + return TRUE; error_return: - if (free_relocs != NULL) - free (free_relocs); - if (free_contents != NULL) - free (free_contents); - return false; + if (internal_relocs != NULL + && internal_relocs != coff_section_data (abfd, sec)->relocs) + free (internal_relocs); + if (contents != NULL && contents != coff_section_data (abfd, sec)->contents) + free (contents); + return FALSE; } /* Delete some bytes from a section while relaxing. */ -static boolean -sh_relax_delete_bytes (abfd, sec, addr, count) - bfd *abfd; - asection *sec; - bfd_vma addr; - int count; +static bfd_boolean +sh_relax_delete_bytes (bfd *abfd, + asection *sec, + bfd_vma addr, + int count) { bfd_byte *contents; struct internal_reloc *irel, *irelend; @@ -908,11 +1083,11 @@ sh_relax_delete_bytes (abfd, sec, addr, count) contents = coff_section_data (abfd, sec)->contents; - /* The deletion must stop at the next ALIGN reloc for an aligment + /* The deletion must stop at the next ALIGN reloc for an alignment power larger than the number of bytes we are deleting. */ irelalign = NULL; - toaddr = sec->_cooked_size; + toaddr = sec->size; irel = coff_section_data (abfd, sec)->relocs; irelend = irel + sec->reloc_count; @@ -929,9 +1104,10 @@ sh_relax_delete_bytes (abfd, sec, addr, count) } /* Actually delete the bytes. */ - memmove (contents + addr, contents + addr + count, toaddr - addr - count); + memmove (contents + addr, contents + addr + count, + (size_t) (toaddr - addr - count)); if (irelalign == NULL) - sec->_cooked_size -= count; + sec->size -= count; else { int i; @@ -940,7 +1116,7 @@ sh_relax_delete_bytes (abfd, sec, addr, count) BFD_ASSERT ((count & 1) == 0); for (i = 0; i < count; i += 2) - bfd_put_16 (abfd, NOP_OPCODE, contents + toaddr - count + i); + bfd_put_16 (abfd, (bfd_vma) NOP_OPCODE, contents + toaddr - count + i); } /* Adjust all the relocs. */ @@ -952,7 +1128,7 @@ sh_relax_delete_bytes (abfd, sec, addr, count) struct internal_syment sym; int off, adjust, oinsn; bfd_signed_vma voff = 0; - boolean overflow; + bfd_boolean overflow; /* Get the new reloc address. */ nraddr = irel->r_vaddr - sec->vma; @@ -974,7 +1150,7 @@ sh_relax_delete_bytes (abfd, sec, addr, count) irel->r_type = R_SH_UNUSED; /* If this is a PC relative reloc, see if the range it covers - includes the bytes we have deleted. */ + includes the bytes we have deleted. */ switch (irel->r_type) { default: @@ -996,10 +1172,14 @@ sh_relax_delete_bytes (abfd, sec, addr, count) break; case R_SH_IMM32: +#ifdef COFF_WITH_PE + case R_SH_IMM32CE: + case R_SH_IMAGEBASE: +#endif /* If this reloc is against a symbol defined in this - section, and the symbol will not be adjusted below, we - must check the addend to see it will put the value in - range to be adjusted, and hence must be changed. */ + section, and the symbol will not be adjusted below, we + must check the addend to see it will put the value in + range to be adjusted, and hence must be changed. */ bfd_coff_swap_sym_in (abfd, ((bfd_byte *) obj_coff_external_syms (abfd) + (irel->r_symndx @@ -1110,7 +1290,7 @@ sh_relax_delete_bytes (abfd, sec, addr, count) if (adjust != 0) { oinsn = insn; - overflow = false; + overflow = FALSE; switch (irel->r_type) { default: @@ -1121,15 +1301,15 @@ sh_relax_delete_bytes (abfd, sec, addr, count) case R_SH_PCRELIMM8BY2: insn += adjust / 2; if ((oinsn & 0xff00) != (insn & 0xff00)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); + overflow = TRUE; + bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr); break; case R_SH_PCDISP: insn += adjust / 2; if ((oinsn & 0xf000) != (insn & 0xf000)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); + overflow = TRUE; + bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr); break; case R_SH_PCRELIMM8BY4: @@ -1142,27 +1322,27 @@ sh_relax_delete_bytes (abfd, sec, addr, count) ++insn; } if ((oinsn & 0xff00) != (insn & 0xff00)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); + overflow = TRUE; + bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr); break; case R_SH_SWITCH8: voff += adjust; if (voff < 0 || voff >= 0xff) - overflow = true; - bfd_put_8 (abfd, voff, contents + nraddr); + overflow = TRUE; + bfd_put_8 (abfd, (bfd_vma) voff, contents + nraddr); break; case R_SH_SWITCH16: voff += adjust; if (voff < - 0x8000 || voff >= 0x8000) - overflow = true; - bfd_put_signed_16 (abfd, voff, contents + nraddr); + overflow = TRUE; + bfd_put_signed_16 (abfd, (bfd_vma) voff, contents + nraddr); break; case R_SH_SWITCH32: voff += adjust; - bfd_put_signed_32 (abfd, voff, contents + nraddr); + bfd_put_signed_32 (abfd, (bfd_vma) voff, contents + nraddr); break; case R_SH_USES: @@ -1172,11 +1352,12 @@ sh_relax_delete_bytes (abfd, sec, addr, count) if (overflow) { - ((*_bfd_error_handler) - ("%s: 0x%lx: fatal: reloc overflow while relaxing", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr)); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: %#" PRIx64 ": fatal: reloc overflow while relaxing"), + abfd, (uint64_t) irel->r_vaddr); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } } @@ -1198,13 +1379,13 @@ sh_relax_delete_bytes (abfd, sec, addr, count) continue; /* We always cache the relocs. Perhaps, if info->keep_memory is - false, we should free them, if we are permitted to, when we - leave sh_coff_relax_section. */ + FALSE, we should free them, if we are permitted to, when we + leave sh_coff_relax_section. */ internal_relocs = (_bfd_coff_read_internal_relocs - (abfd, o, true, (bfd_byte *) NULL, false, + (abfd, o, TRUE, (bfd_byte *) NULL, FALSE, (struct internal_reloc *) NULL)); if (internal_relocs == NULL) - return false; + return FALSE; ocontents = NULL; irelscanend = internal_relocs + o->reloc_count; @@ -1212,7 +1393,13 @@ sh_relax_delete_bytes (abfd, sec, addr, count) { struct internal_syment sym; +#ifdef COFF_WITH_PE + if (irelscan->r_type != R_SH_IMM32 + && irelscan->r_type != R_SH_IMAGEBASE + && irelscan->r_type != R_SH_IMM32CE) +#else if (irelscan->r_type != R_SH_IMM32) +#endif continue; bfd_coff_swap_sym_in (abfd, @@ -1233,17 +1420,12 @@ sh_relax_delete_bytes (abfd, sec, addr, count) ocontents = coff_section_data (abfd, o)->contents; else { + if (!bfd_malloc_and_get_section (abfd, o, &ocontents)) + return FALSE; /* We always cache the section contents. - Perhaps, if info->keep_memory is false, we - should free them, if we are permitted to, - when we leave sh_coff_relax_section. */ - ocontents = (bfd_byte *) bfd_malloc (o->_raw_size); - if (ocontents == NULL) - return false; - if (! bfd_get_section_contents (abfd, o, ocontents, - (file_ptr) 0, - o->_raw_size)) - return false; + Perhaps, if info->keep_memory is FALSE, we + should free them, if we are permitted to, + when we leave sh_coff_relax_section. */ coff_section_data (abfd, o)->contents = ocontents; } } @@ -1254,7 +1436,7 @@ sh_relax_delete_bytes (abfd, sec, addr, count) bfd_put_32 (abfd, val - count, ocontents + irelscan->r_vaddr - o->vma); - coff_section_data (abfd, o)->keep_contents = true; + coff_section_data (abfd, o)->keep_contents = TRUE; } } } @@ -1266,11 +1448,10 @@ sh_relax_delete_bytes (abfd, sec, addr, count) if (obj_symbols (abfd) != NULL || obj_raw_syments (abfd) != NULL) { - ((*_bfd_error_handler) - ("%s: fatal: generic symbols retrieved before relaxing", - bfd_get_filename (abfd))); + _bfd_error_handler + (_("%pB: fatal: generic symbols retrieved before relaxing"), abfd); bfd_set_error (bfd_error_invalid_operation); - return false; + return FALSE; } /* Adjust all the symbols. */ @@ -1282,7 +1463,7 @@ sh_relax_delete_bytes (abfd, sec, addr, count) { struct internal_syment isym; - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym); + bfd_coff_swap_sym_in (abfd, esym, &isym); if (isym.n_scnum == sec->target_index && (bfd_vma) isym.n_value > addr @@ -1290,7 +1471,7 @@ sh_relax_delete_bytes (abfd, sec, addr, count) { isym.n_value -= count; - bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym); + bfd_coff_swap_sym_out (abfd, &isym, esym); if (*sym_hash != NULL) { @@ -1319,11 +1500,11 @@ sh_relax_delete_bytes (abfd, sec, addr, count) { /* Tail recursion. */ return sh_relax_delete_bytes (abfd, sec, alignaddr, - alignto - alignaddr); + (int) (alignto - alignaddr)); } } - return true; + return TRUE; } /* This is yet another version of the SH opcode table, used to rapidly @@ -1364,7 +1545,7 @@ struct sh_opcode mask value in the sh_major_opcode structure. */ unsigned short opcode; /* Flags for this instruction. */ - unsigned flags; + unsigned long flags; }; /* Flag which appear in the sh_opcode structure. */ @@ -1437,28 +1618,11 @@ struct sh_opcode #define SETSAS (0x40000) #define SETSAS_REG(x) USESAS_REG (x) -static boolean sh_insn_uses_reg - PARAMS ((unsigned int, const struct sh_opcode *, unsigned int)); -static boolean sh_insn_sets_reg - PARAMS ((unsigned int, const struct sh_opcode *, unsigned int)); -static boolean sh_insn_uses_or_sets_reg - PARAMS ((unsigned int, const struct sh_opcode *, unsigned int)); -static boolean sh_insn_uses_freg - PARAMS ((unsigned int, const struct sh_opcode *, unsigned int)); -static boolean sh_insn_sets_freg - PARAMS ((unsigned int, const struct sh_opcode *, unsigned int)); -static boolean sh_insn_uses_or_sets_freg - PARAMS ((unsigned int, const struct sh_opcode *, unsigned int)); -static boolean sh_insns_conflict - PARAMS ((unsigned int, const struct sh_opcode *, unsigned int, - const struct sh_opcode *)); -static boolean sh_load_use - PARAMS ((unsigned int, const struct sh_opcode *, unsigned int, - const struct sh_opcode *)); +#define MAP(a) a, sizeof a / sizeof a[0] -/* The opcode maps. */ +#ifndef COFF_IMAGE_WITH_PE -#define MAP(a) a, sizeof a / sizeof a[0] +/* The opcode maps. */ static const struct sh_opcode sh_opcode00[] = { @@ -1493,26 +1657,6 @@ static const struct sh_opcode sh_opcode01[] = { 0x00ba, SETS1 | USESSP } /* sts y1,rn */ }; -/* These sixteen instructions can be handled with one table entry below. */ -#if 0 - { 0x0002, SETS1 | USESSP }, /* stc sr,rn */ - { 0x0012, SETS1 | USESSP }, /* stc gbr,rn */ - { 0x0022, SETS1 | USESSP }, /* stc vbr,rn */ - { 0x0032, SETS1 | USESSP }, /* stc ssr,rn */ - { 0x0042, SETS1 | USESSP }, /* stc spc,rn */ - { 0x0052, SETS1 | USESSP }, /* stc mod,rn */ - { 0x0062, SETS1 | USESSP }, /* stc rs,rn */ - { 0x0072, SETS1 | USESSP }, /* stc re,rn */ - { 0x0082, SETS1 | USESSP }, /* stc r0_bank,rn */ - { 0x0092, SETS1 | USESSP }, /* stc r1_bank,rn */ - { 0x00a2, SETS1 | USESSP }, /* stc r2_bank,rn */ - { 0x00b2, SETS1 | USESSP }, /* stc r3_bank,rn */ - { 0x00c2, SETS1 | USESSP }, /* stc r4_bank,rn */ - { 0x00d2, SETS1 | USESSP }, /* stc r5_bank,rn */ - { 0x00e2, SETS1 | USESSP }, /* stc r6_bank,rn */ - { 0x00f2, SETS1 | USESSP } /* stc r7_bank,rn */ -#endif - static const struct sh_opcode sh_opcode02[] = { { 0x0002, SETS1 | USESSP }, /* stc ,rn */ @@ -1643,44 +1787,6 @@ static const struct sh_opcode sh_opcode40[] = { 0x40b2, STORE | SETS1 | USES1 | USESSP }, /* sts.l y1,@-rn */ { 0x40b6, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,y1 */ { 0x40ba, SETSSP | USES1 } /* lds.l rm,y1 */ -#if 0 /* These groups sixteen insns can be - handled with one table entry each below. */ - { 0x4003, STORE | SETS1 | USES1 | USESSP }, /* stc.l sr,@-rn */ - { 0x4013, STORE | SETS1 | USES1 | USESSP }, /* stc.l gbr,@-rn */ - { 0x4023, STORE | SETS1 | USES1 | USESSP }, /* stc.l vbr,@-rn */ - { 0x4033, STORE | SETS1 | USES1 | USESSP }, /* stc.l ssr,@-rn */ - { 0x4043, STORE | SETS1 | USES1 | USESSP }, /* stc.l spc,@-rn */ - { 0x4053, STORE | SETS1 | USES1 | USESSP }, /* stc.l mod,@-rn */ - { 0x4063, STORE | SETS1 | USES1 | USESSP }, /* stc.l rs,@-rn */ - { 0x4073, STORE | SETS1 | USES1 | USESSP }, /* stc.l re,@-rn */ - { 0x4083, STORE | SETS1 | USES1 | USESSP }, /* stc.l r0_bank,@-rn */ - .. - { 0x40f3, STORE | SETS1 | USES1 | USESSP }, /* stc.l r7_bank,@-rn */ - - { 0x4007, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,sr */ - { 0x4017, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,gbr */ - { 0x4027, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,vbr */ - { 0x4037, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,ssr */ - { 0x4047, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,spc */ - { 0x4057, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,mod */ - { 0x4067, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,rs */ - { 0x4077, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,re */ - { 0x4087, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,r0_bank */ - .. - { 0x40f7, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,r7_bank */ - - { 0x400e, SETSSP | USES1 }, /* ldc rm,sr */ - { 0x401e, SETSSP | USES1 }, /* ldc rm,gbr */ - { 0x402e, SETSSP | USES1 }, /* ldc rm,vbr */ - { 0x403e, SETSSP | USES1 }, /* ldc rm,ssr */ - { 0x404e, SETSSP | USES1 }, /* ldc rm,spc */ - { 0x405e, SETSSP | USES1 }, /* ldc rm,mod */ - { 0x406e, SETSSP | USES1 }, /* ldc rm,rs */ - { 0x407e, SETSSP | USES1 } /* ldc rm,re */ - { 0x408e, SETSSP | USES1 } /* ldc rm,r0_bank */ - .. - { 0x40fe, SETSSP | USES1 } /* ldc rm,r7_bank */ -#endif }; static const struct sh_opcode sh_opcode41[] = @@ -1923,8 +2029,7 @@ static const struct sh_minor_opcode sh_dsp_opcodef[] = recognized. */ static const struct sh_opcode * -sh_insn_info (insn) - unsigned int insn; +sh_insn_info (unsigned int insn) { const struct sh_major_opcode *maj; const struct sh_minor_opcode *min, *minend; @@ -1942,36 +2047,21 @@ sh_insn_info (insn) opend = op + min->count; /* Since the opcodes tables are sorted, we could use a binary - search here if the count were above some cutoff value. */ + search here if the count were above some cutoff value. */ for (; op < opend; op++) if (op->opcode == l) return op; } - return NULL; -} - -/* See whether an instruction uses or sets a general purpose register */ - -static boolean -sh_insn_uses_or_sets_reg (insn, op, reg) - unsigned int insn; - const struct sh_opcode *op; - unsigned int reg; -{ - if (sh_insn_uses_reg (insn, op, reg)) - return true; - - return sh_insn_sets_reg (insn, op, reg); + return NULL; } /* See whether an instruction uses a general purpose register. */ -static boolean -sh_insn_uses_reg (insn, op, reg) - unsigned int insn; - const struct sh_opcode *op; - unsigned int reg; +static bfd_boolean +sh_insn_uses_reg (unsigned int insn, + const struct sh_opcode *op, + unsigned int reg) { unsigned int f; @@ -1979,27 +2069,27 @@ sh_insn_uses_reg (insn, op, reg) if ((f & USES1) != 0 && USES1_REG (insn) == reg) - return true; + return TRUE; if ((f & USES2) != 0 && USES2_REG (insn) == reg) - return true; + return TRUE; if ((f & USESR0) != 0 && reg == 0) - return true; + return TRUE; if ((f & USESAS) && reg == USESAS_REG (insn)) - return true; + return TRUE; if ((f & USESR8) && reg == 8) - return true; + return TRUE; - return false; + return FALSE; } + /* See whether an instruction sets a general purpose register. */ -static boolean -sh_insn_sets_reg (insn, op, reg) - unsigned int insn; - const struct sh_opcode *op; - unsigned int reg; +static bfd_boolean +sh_insn_sets_reg (unsigned int insn, + const struct sh_opcode *op, + unsigned int reg) { unsigned int f; @@ -2007,40 +2097,38 @@ sh_insn_sets_reg (insn, op, reg) if ((f & SETS1) != 0 && SETS1_REG (insn) == reg) - return true; + return TRUE; if ((f & SETS2) != 0 && SETS2_REG (insn) == reg) - return true; + return TRUE; if ((f & SETSR0) != 0 && reg == 0) - return true; + return TRUE; if ((f & SETSAS) && reg == SETSAS_REG (insn)) - return true; + return TRUE; - return false; + return FALSE; } -/* See whether an instruction uses or sets a floating point register */ +/* See whether an instruction uses or sets a general purpose register */ -static boolean -sh_insn_uses_or_sets_freg (insn, op, reg) - unsigned int insn; - const struct sh_opcode *op; - unsigned int reg; +static bfd_boolean +sh_insn_uses_or_sets_reg (unsigned int insn, + const struct sh_opcode *op, + unsigned int reg) { - if (sh_insn_uses_freg (insn, op, reg)) - return true; + if (sh_insn_uses_reg (insn, op, reg)) + return TRUE; - return sh_insn_sets_freg (insn, op, reg); + return sh_insn_sets_reg (insn, op, reg); } /* See whether an instruction uses a floating point register. */ -static boolean -sh_insn_uses_freg (insn, op, freg) - unsigned int insn; - const struct sh_opcode *op; - unsigned int freg; +static bfd_boolean +sh_insn_uses_freg (unsigned int insn, + const struct sh_opcode *op, + unsigned int freg) { unsigned int f; @@ -2054,27 +2142,26 @@ sh_insn_uses_freg (insn, op, freg) of a double precision value. So what this all boils down to is that we have to ignore the lowest bit of the register number. */ - + if ((f & USESF1) != 0 && (USESF1_REG (insn) & 0xe) == (freg & 0xe)) - return true; + return TRUE; if ((f & USESF2) != 0 && (USESF2_REG (insn) & 0xe) == (freg & 0xe)) - return true; + return TRUE; if ((f & USESF0) != 0 && freg == 0) - return true; + return TRUE; - return false; + return FALSE; } /* See whether an instruction sets a floating point register. */ -static boolean -sh_insn_sets_freg (insn, op, freg) - unsigned int insn; - const struct sh_opcode *op; - unsigned int freg; +static bfd_boolean +sh_insn_sets_freg (unsigned int insn, + const struct sh_opcode *op, + unsigned int freg) { unsigned int f; @@ -2088,25 +2175,37 @@ sh_insn_sets_freg (insn, op, freg) of a double precision value. So what this all boils down to is that we have to ignore the lowest bit of the register number. */ - + if ((f & SETSF1) != 0 && (SETSF1_REG (insn) & 0xe) == (freg & 0xe)) - return true; + return TRUE; + + return FALSE; +} + +/* See whether an instruction uses or sets a floating point register */ - return false; +static bfd_boolean +sh_insn_uses_or_sets_freg (unsigned int insn, + const struct sh_opcode *op, + unsigned int reg) +{ + if (sh_insn_uses_freg (insn, op, reg)) + return TRUE; + + return sh_insn_sets_freg (insn, op, reg); } /* See whether instructions I1 and I2 conflict, assuming I1 comes before I2. OP1 and OP2 are the corresponding sh_opcode structures. - This should return true if there is a conflict, or false if the + This should return TRUE if there is a conflict, or FALSE if the instructions can be swapped safely. */ -static boolean -sh_insns_conflict (i1, op1, i2, op2) - unsigned int i1; - const struct sh_opcode *op1; - unsigned int i2; - const struct sh_opcode *op2; +static bfd_boolean +sh_insns_conflict (unsigned int i1, + const struct sh_opcode *op1, + unsigned int i2, + const struct sh_opcode *op2) { unsigned int f1, f2; @@ -2117,69 +2216,68 @@ sh_insns_conflict (i1, op1, i2, op2) FIXME: shouldn't test raw opcodes here. */ if (((i1 & 0xf0ff) == 0x4066 && (i2 & 0xf000) == 0xf000) || ((i2 & 0xf0ff) == 0x4066 && (i1 & 0xf000) == 0xf000)) - return true; + return TRUE; if ((f1 & (BRANCH | DELAY)) != 0 || (f2 & (BRANCH | DELAY)) != 0) - return true; + return TRUE; if (((f1 | f2) & SETSSP) && (f1 & (SETSSP | USESSP)) && (f2 & (SETSSP | USESSP))) - return true; + return TRUE; if ((f1 & SETS1) != 0 && sh_insn_uses_or_sets_reg (i2, op2, SETS1_REG (i1))) - return true; + return TRUE; if ((f1 & SETS2) != 0 && sh_insn_uses_or_sets_reg (i2, op2, SETS2_REG (i1))) - return true; + return TRUE; if ((f1 & SETSR0) != 0 && sh_insn_uses_or_sets_reg (i2, op2, 0)) - return true; + return TRUE; if ((f1 & SETSAS) && sh_insn_uses_or_sets_reg (i2, op2, SETSAS_REG (i1))) - return true; + return TRUE; if ((f1 & SETSF1) != 0 && sh_insn_uses_or_sets_freg (i2, op2, SETSF1_REG (i1))) - return true; + return TRUE; if ((f2 & SETS1) != 0 && sh_insn_uses_or_sets_reg (i1, op1, SETS1_REG (i2))) - return true; + return TRUE; if ((f2 & SETS2) != 0 && sh_insn_uses_or_sets_reg (i1, op1, SETS2_REG (i2))) - return true; + return TRUE; if ((f2 & SETSR0) != 0 && sh_insn_uses_or_sets_reg (i1, op1, 0)) - return true; + return TRUE; if ((f2 & SETSAS) && sh_insn_uses_or_sets_reg (i1, op1, SETSAS_REG (i2))) - return true; + return TRUE; if ((f2 & SETSF1) != 0 && sh_insn_uses_or_sets_freg (i1, op1, SETSF1_REG (i2))) - return true; + return TRUE; /* The instructions do not conflict. */ - return false; + return FALSE; } /* I1 is a load instruction, and I2 is some other instruction. Return - true if I1 loads a register which I2 uses. */ + TRUE if I1 loads a register which I2 uses. */ -static boolean -sh_load_use (i1, op1, i2, op2) - unsigned int i1; - const struct sh_opcode *op1; - unsigned int i2; - const struct sh_opcode *op2; +static bfd_boolean +sh_load_use (unsigned int i1, + const struct sh_opcode *op1, + unsigned int i2, + const struct sh_opcode *op2) { unsigned int f1; f1 = op1->flags; if ((f1 & LOAD) == 0) - return false; + return FALSE; /* If both SETS1 and SETSSP are set, that means a load to a special register using postincrement addressing mode, which we don't care @@ -2187,17 +2285,17 @@ sh_load_use (i1, op1, i2, op2) if ((f1 & SETS1) != 0 && (f1 & SETSSP) == 0 && sh_insn_uses_reg (i2, op2, (i1 & 0x0f00) >> 8)) - return true; + return TRUE; if ((f1 & SETSR0) != 0 && sh_insn_uses_reg (i2, op2, 0)) - return true; + return TRUE; if ((f1 & SETSF1) != 0 && sh_insn_uses_freg (i2, op2, (i1 & 0x0f00) >> 8)) - return true; + return TRUE; - return false; + return FALSE; } /* Try to align loads and stores within a span of memory. This is @@ -2208,21 +2306,22 @@ sh_load_use (i1, op1, i2, op2) passed to SWAP. PLABEL is a pointer to the current label in a sorted list of labels; LABEL_END is the end of the list. START and STOP are the range of memory to examine. If a swap is made, - *PSWAPPED is set to true. */ - -boolean -_bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, - plabel, label_end, start, stop, pswapped) - bfd *abfd; - asection *sec; - bfd_byte *contents; - boolean (*swap) PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma)); - PTR relocs; - bfd_vma **plabel; - bfd_vma *label_end; - bfd_vma start; - bfd_vma stop; - boolean *pswapped; + *PSWAPPED is set to TRUE. */ + +#ifdef COFF_WITH_PE +static +#endif +bfd_boolean +_bfd_sh_align_load_span (bfd *abfd, + asection *sec, + bfd_byte *contents, + bfd_boolean (*swap) (bfd *, asection *, void *, bfd_byte *, bfd_vma), + void * relocs, + bfd_vma **plabel, + bfd_vma *label_end, + bfd_vma start, + bfd_vma stop, + bfd_boolean *pswapped) { int dsp = (abfd->arch_info->mach == bfd_mach_sh_dsp || abfd->arch_info->mach == bfd_mach_sh3_dsp); @@ -2232,14 +2331,14 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, desirable. In fact, it is counter-productive, since it interferes with the schedules generated by the compiler. */ if (abfd->arch_info->mach == bfd_mach_sh4) - return true; + return TRUE; /* If we are linking sh[3]-dsp code, swap the FPU instructions for DSP instructions. */ if (dsp) { sh_opcodes[0xf].minor_opcodes = sh_dsp_opcodef; - sh_opcodes[0xf].count = sizeof sh_dsp_opcodef / sizeof sh_dsp_opcodef; + sh_opcodes[0xf].count = sizeof sh_dsp_opcodef / sizeof sh_dsp_opcodef [0]; } /* Instructions should be aligned on 2 byte boundaries. */ @@ -2285,7 +2384,7 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, if (dsp && i - 2 > start) { unsigned pprev_insn = bfd_get_16 (abfd, contents + i - 4); - + if ((pprev_insn & 0xfc00) == 0xf800) prev_op = NULL; else @@ -2306,14 +2405,14 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, && (prev_op->flags & (LOAD | STORE)) == 0 && ! sh_insns_conflict (prev_insn, prev_op, insn, op)) { - boolean ok; + bfd_boolean ok; /* The load/store instruction does not have a label, and there is a previous instruction; PREV_INSN is not itself a load/store instruction, and PREV_INSN and INSN do not conflict. */ - ok = true; + ok = TRUE; if (i >= start + 4) { @@ -2328,7 +2427,7 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, can not swap. */ if (prev2_op == NULL || (prev2_op->flags & DELAY) != 0) - ok = false; + ok = FALSE; /* If the instruction before PREV_INSN is a load, and it sets a register which INSN uses, then @@ -2338,14 +2437,14 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, if (ok && (prev2_op->flags & LOAD) != 0 && sh_load_use (prev2_insn, prev2_op, insn, op)) - ok = false; + ok = FALSE; } if (ok) { if (! (*swap) (abfd, sec, relocs, contents, i - 2)) - return false; - *pswapped = true; + return FALSE; + *pswapped = TRUE; continue; } } @@ -2367,12 +2466,12 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, && (next_op->flags & (LOAD | STORE)) == 0 && ! sh_insns_conflict (insn, op, next_insn, next_op)) { - boolean ok; + bfd_boolean ok; /* NEXT_INSN is not itself a load/store instruction, and it does not conflict with INSN. */ - ok = true; + ok = TRUE; /* If PREV_INSN is a load, and it sets a register which NEXT_INSN uses, then putting NEXT_INSN @@ -2381,7 +2480,7 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, if (prev_op != NULL && (prev_op->flags & LOAD) != 0 && sh_load_use (prev_insn, prev_op, next_insn, next_op)) - ok = false; + ok = FALSE; /* If INSN is a load, and it sets a register which the insn after NEXT_INSN uses, then doing the @@ -2401,108 +2500,35 @@ _bfd_sh_align_load_span (abfd, sec, contents, swap, relocs, next2_insn = bfd_get_16 (abfd, contents + i + 4); next2_op = sh_insn_info (next2_insn); - if ((next2_op->flags & (LOAD | STORE)) == 0 - && sh_load_use (insn, op, next2_insn, next2_op)) - ok = false; + if (next2_op == NULL + || ((next2_op->flags & (LOAD | STORE)) == 0 + && sh_load_use (insn, op, next2_insn, next2_op))) + ok = FALSE; } if (ok) { if (! (*swap) (abfd, sec, relocs, contents, i)) - return false; - *pswapped = true; + return FALSE; + *pswapped = TRUE; continue; } } } } - return true; -} - -/* Look for loads and stores which we can align to four byte - boundaries. See the longer comment above sh_relax_section for why - this is desirable. This sets *PSWAPPED if some instruction was - swapped. */ - -static boolean -sh_align_loads (abfd, sec, internal_relocs, contents, pswapped) - bfd *abfd; - asection *sec; - struct internal_reloc *internal_relocs; - bfd_byte *contents; - boolean *pswapped; -{ - struct internal_reloc *irel, *irelend; - bfd_vma *labels = NULL; - bfd_vma *label, *label_end; - - *pswapped = false; - - irelend = internal_relocs + sec->reloc_count; - - /* Get all the addresses with labels on them. */ - labels = (bfd_vma *) bfd_malloc (sec->reloc_count * sizeof (bfd_vma)); - if (labels == NULL) - goto error_return; - label_end = labels; - for (irel = internal_relocs; irel < irelend; irel++) - { - if (irel->r_type == R_SH_LABEL) - { - *label_end = irel->r_vaddr - sec->vma; - ++label_end; - } - } - - /* Note that the assembler currently always outputs relocs in - address order. If that ever changes, this code will need to sort - the label values and the relocs. */ - - label = labels; - - for (irel = internal_relocs; irel < irelend; irel++) - { - bfd_vma start, stop; - - if (irel->r_type != R_SH_CODE) - continue; - - start = irel->r_vaddr - sec->vma; - - for (irel++; irel < irelend; irel++) - if (irel->r_type == R_SH_DATA) - break; - if (irel < irelend) - stop = irel->r_vaddr - sec->vma; - else - stop = sec->_cooked_size; - - if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_swap_insns, - (PTR) internal_relocs, &label, - label_end, start, stop, pswapped)) - goto error_return; - } - - free (labels); - - return true; - - error_return: - if (labels != NULL) - free (labels); - return false; + return TRUE; } +#endif /* not COFF_IMAGE_WITH_PE */ /* Swap two SH instructions. */ -static boolean -sh_swap_insns (abfd, sec, relocs, contents, addr) - bfd *abfd; - asection *sec; - PTR relocs; - bfd_byte *contents; - bfd_vma addr; +static bfd_boolean +sh_swap_insns (bfd * abfd, + asection * sec, + void * relocs, + bfd_byte * contents, + bfd_vma addr) { struct internal_reloc *internal_relocs = (struct internal_reloc *) relocs; unsigned short i1, i2; @@ -2511,8 +2537,8 @@ sh_swap_insns (abfd, sec, relocs, contents, addr) /* Swap the instructions themselves. */ i1 = bfd_get_16 (abfd, contents + addr); i2 = bfd_get_16 (abfd, contents + addr + 2); - bfd_put_16 (abfd, i2, contents + addr); - bfd_put_16 (abfd, i1, contents + addr + 2); + bfd_put_16 (abfd, (bfd_vma) i2, contents + addr); + bfd_put_16 (abfd, (bfd_vma) i1, contents + addr + 2); /* Adjust all reloc addresses. */ irelend = internal_relocs + sec->reloc_count; @@ -2521,8 +2547,8 @@ sh_swap_insns (abfd, sec, relocs, contents, addr) int type, add; /* There are a few special types of relocs that we don't want to - adjust. These relocs do not apply to the instruction itself, - but are only associated with the address. */ + adjust. These relocs do not apply to the instruction itself, + but are only associated with the address. */ type = irel->r_type; if (type == R_SH_ALIGN || type == R_SH_CODE @@ -2531,11 +2557,11 @@ sh_swap_insns (abfd, sec, relocs, contents, addr) continue; /* If an R_SH_USES reloc points to one of the addresses being - swapped, we must adjust it. It would be incorrect to do this - for a jump, though, since we want to execute both - instructions after the jump. (We have avoided swapping - around a label, so the jump will not wind up executing an - instruction it shouldn't). */ + swapped, we must adjust it. It would be incorrect to do this + for a jump, though, since we want to execute both + instructions after the jump. (We have avoided swapping + around a label, so the jump will not wind up executing an + instruction it shouldn't). */ if (type == R_SH_USES) { bfd_vma off; @@ -2564,10 +2590,10 @@ sh_swap_insns (abfd, sec, relocs, contents, addr) { bfd_byte *loc; unsigned short insn, oinsn; - boolean overflow; + bfd_boolean overflow; loc = contents + irel->r_vaddr - sec->vma; - overflow = false; + overflow = FALSE; switch (type) { default: @@ -2579,8 +2605,8 @@ sh_swap_insns (abfd, sec, relocs, contents, addr) oinsn = insn; insn += add / 2; if ((oinsn & 0xff00) != (insn & 0xff00)) - overflow = true; - bfd_put_16 (abfd, insn, loc); + overflow = TRUE; + bfd_put_16 (abfd, (bfd_vma) insn, loc); break; case R_SH_PCDISP: @@ -2588,25 +2614,25 @@ sh_swap_insns (abfd, sec, relocs, contents, addr) oinsn = insn; insn += add / 2; if ((oinsn & 0xf000) != (insn & 0xf000)) - overflow = true; - bfd_put_16 (abfd, insn, loc); + overflow = TRUE; + bfd_put_16 (abfd, (bfd_vma) insn, loc); break; case R_SH_PCRELIMM8BY4: /* This reloc ignores the least significant 3 bits of - the program counter before adding in the offset. - This means that if ADDR is at an even address, the - swap will not affect the offset. If ADDR is an at an - odd address, then the instruction will be crossing a - four byte boundary, and must be adjusted. */ + the program counter before adding in the offset. + This means that if ADDR is at an even address, the + swap will not affect the offset. If ADDR is an at an + odd address, then the instruction will be crossing a + four byte boundary, and must be adjusted. */ if ((addr & 3) != 0) { insn = bfd_get_16 (abfd, loc); oinsn = insn; insn += add / 2; if ((oinsn & 0xff00) != (insn & 0xff00)) - overflow = true; - bfd_put_16 (abfd, insn, loc); + overflow = TRUE; + bfd_put_16 (abfd, (bfd_vma) insn, loc); } break; @@ -2614,32 +2640,106 @@ sh_swap_insns (abfd, sec, relocs, contents, addr) if (overflow) { - ((*_bfd_error_handler) - ("%s: 0x%lx: fatal: reloc overflow while relaxing", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr)); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: %#" PRIx64 ": fatal: reloc overflow while relaxing"), + abfd, (uint64_t) irel->r_vaddr); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } } } - return true; + return TRUE; +} + +/* Look for loads and stores which we can align to four byte + boundaries. See the longer comment above sh_relax_section for why + this is desirable. This sets *PSWAPPED if some instruction was + swapped. */ + +static bfd_boolean +sh_align_loads (bfd *abfd, + asection *sec, + struct internal_reloc *internal_relocs, + bfd_byte *contents, + bfd_boolean *pswapped) +{ + struct internal_reloc *irel, *irelend; + bfd_vma *labels = NULL; + bfd_vma *label, *label_end; + bfd_size_type amt; + + *pswapped = FALSE; + + irelend = internal_relocs + sec->reloc_count; + + /* Get all the addresses with labels on them. */ + amt = (bfd_size_type) sec->reloc_count * sizeof (bfd_vma); + labels = (bfd_vma *) bfd_malloc (amt); + if (labels == NULL) + goto error_return; + label_end = labels; + for (irel = internal_relocs; irel < irelend; irel++) + { + if (irel->r_type == R_SH_LABEL) + { + *label_end = irel->r_vaddr - sec->vma; + ++label_end; + } + } + + /* Note that the assembler currently always outputs relocs in + address order. If that ever changes, this code will need to sort + the label values and the relocs. */ + + label = labels; + + for (irel = internal_relocs; irel < irelend; irel++) + { + bfd_vma start, stop; + + if (irel->r_type != R_SH_CODE) + continue; + + start = irel->r_vaddr - sec->vma; + + for (irel++; irel < irelend; irel++) + if (irel->r_type == R_SH_DATA) + break; + if (irel < irelend) + stop = irel->r_vaddr - sec->vma; + else + stop = sec->size; + + if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_swap_insns, + internal_relocs, &label, + label_end, start, stop, pswapped)) + goto error_return; + } + + free (labels); + + return TRUE; + + error_return: + if (labels != NULL) + free (labels); + return FALSE; } /* This is a modification of _bfd_coff_generic_relocate_section, which will handle SH relaxing. */ -static boolean -sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, - relocs, syms, sections) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; +static bfd_boolean +sh_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + struct internal_reloc *relocs, + struct internal_syment *syms, + asection **sections) { struct internal_reloc *rel; struct internal_reloc *relend; @@ -2657,8 +2757,12 @@ sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, bfd_reloc_status_type rstat; /* Almost all relocs have to do with relaxing. If any work must - be done for them, it has been done in sh_relax_section. */ + be done for them, it has been done in sh_relax_section. */ if (rel->r_type != R_SH_IMM32 +#ifdef COFF_WITH_PE + && rel->r_type != R_SH_IMM32CE + && rel->r_type != R_SH_IMAGEBASE +#endif && rel->r_type != R_SH_PCDISP) continue; @@ -2670,15 +2774,16 @@ sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, sym = NULL; } else - { + { if (symndx < 0 || (unsigned long) symndx >= obj_raw_syment_count (input_bfd)) { - (*_bfd_error_handler) - ("%s: illegal symbol index %ld in relocs", - bfd_get_filename (input_bfd), symndx); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: illegal symbol index %ld in relocs"), + input_bfd, symndx); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } h = obj_coff_sym_hashes (input_bfd)[symndx]; sym = syms + symndx; @@ -2700,9 +2805,14 @@ sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, if (howto == NULL) { bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } +#ifdef COFF_WITH_PE + if (rel->r_type == R_SH_IMAGEBASE) + addend -= pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase; +#endif + val = 0; if (h == NULL) @@ -2721,7 +2831,7 @@ sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, else { sec = sections[symndx]; - val = (sec->output_section->vma + val = (sec->output_section->vma + sec->output_offset + sym->n_value - sec->vma); @@ -2739,13 +2849,10 @@ sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, + sec->output_section->vma + sec->output_offset); } - else if (! info->relocateable) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } + else if (! bfd_link_relocatable (info)) + (*info->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, input_section, + rel->r_vaddr - input_section->vma, TRUE); } rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, @@ -2767,40 +2874,38 @@ sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, if (symndx == -1) name = "*ABS*"; else if (h != NULL) - name = h->root.root.string; + name = NULL; else if (sym->_n._n_n._n_zeroes == 0 && sym->_n._n_n._n_offset != 0) name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; else { - strncpy (buf, sym->_n._n_name, SYMNMLEN); + strncpy (buf, sym->_n._n_name, SYMNMLEN); buf[SYMNMLEN] = '\0'; name = buf; } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; + (*info->callbacks->reloc_overflow) + (info, (h ? &h->root : NULL), name, howto->name, + (bfd_vma) 0, input_bfd, input_section, + rel->r_vaddr - input_section->vma); } } } - return true; + return TRUE; } /* This is a version of bfd_generic_get_relocated_section_contents which uses sh_relocate_section. */ static bfd_byte * -sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order, - data, relocateable, symbols) - bfd *output_bfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; +sh_coff_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) { asection *input_section = link_order->u.indirect.section; bfd *input_bfd = input_section->owner; @@ -2810,16 +2915,16 @@ sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order, /* We only need to handle the case of relaxing, or of having a particular set of section contents, specially. */ - if (relocateable + if (relocatable || coff_section_data (input_bfd, input_section) == NULL || coff_section_data (input_bfd, input_section)->contents == NULL) return bfd_generic_get_relocated_section_contents (output_bfd, link_info, link_order, data, - relocateable, + relocatable, symbols); memcpy (data, coff_section_data (input_bfd, input_section)->contents, - input_section->_raw_size); + (size_t) input_section->size); if ((input_section->flags & SEC_RELOC) != 0 && input_section->reloc_count > 0) @@ -2828,24 +2933,26 @@ sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order, bfd_byte *esym, *esymend; struct internal_syment *isymp; asection **secpp; + bfd_size_type amt; if (! _bfd_coff_get_external_symbols (input_bfd)) goto error_return; internal_relocs = (_bfd_coff_read_internal_relocs - (input_bfd, input_section, false, (bfd_byte *) NULL, - false, (struct internal_reloc *) NULL)); + (input_bfd, input_section, FALSE, (bfd_byte *) NULL, + FALSE, (struct internal_reloc *) NULL)); if (internal_relocs == NULL) goto error_return; - internal_syms = ((struct internal_syment *) - bfd_malloc (obj_raw_syment_count (input_bfd) - * sizeof (struct internal_syment))); + amt = obj_raw_syment_count (input_bfd); + amt *= sizeof (struct internal_syment); + internal_syms = (struct internal_syment *) bfd_malloc (amt); if (internal_syms == NULL) goto error_return; - sections = (asection **) bfd_malloc (obj_raw_syment_count (input_bfd) - * sizeof (asection *)); + amt = obj_raw_syment_count (input_bfd); + amt *= sizeof (asection *); + sections = (asection **) bfd_malloc (amt); if (sections == NULL) goto error_return; @@ -2855,7 +2962,7 @@ sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order, esymend = esym + obj_raw_syment_count (input_bfd) * symesz; while (esym < esymend) { - bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); + bfd_coff_swap_sym_in (input_bfd, esym, isymp); if (isymp->n_scnum != 0) *secpp = coff_section_from_bfd_index (input_bfd, isymp->n_scnum); @@ -2899,20 +3006,29 @@ sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order, /* The target vectors. */ -CREATE_BIG_COFF_TARGET_VEC (shcoff_vec, "coff-sh", BFD_IS_RELAXABLE, 0, '_', NULL) +#ifndef TARGET_SHL_SYM +CREATE_BIG_COFF_TARGET_VEC (sh_coff_vec, "coff-sh", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE) +#endif #ifdef TARGET_SHL_SYM #define TARGET_SYM TARGET_SHL_SYM #else -#define TARGET_SYM shlcoff_vec +#define TARGET_SYM sh_coff_le_vec #endif - + #ifndef TARGET_SHL_NAME #define TARGET_SHL_NAME "coff-shl" #endif -CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE, 0, '_', NULL) - +#ifdef COFF_WITH_PE +CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE, + SEC_CODE | SEC_DATA, '_', NULL, COFF_SWAP_TABLE); +#else +CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE, + 0, '_', NULL, COFF_SWAP_TABLE) +#endif + +#ifndef TARGET_SHL_SYM /* Some people want versions of the SH COFF target which do not align to 16 byte boundaries. We implement that by adding a couple of new @@ -2929,8 +3045,7 @@ CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE, 0, Otherwise we won't recognize the non default endianness. */ static const bfd_target * -coff_small_object_p (abfd) - bfd *abfd; +coff_small_object_p (bfd *abfd) { if (abfd->target_defaulted) { @@ -2942,26 +3057,24 @@ coff_small_object_p (abfd) /* Set the section alignment for the small versions. */ -static boolean -coff_small_new_section_hook (abfd, section) - bfd *abfd; - asection *section; +static bfd_boolean +coff_small_new_section_hook (bfd *abfd, asection *section) { if (! coff_new_section_hook (abfd, section)) - return false; + return FALSE; /* We must align to at least a four byte boundary, because longword accesses must be on a four byte boundary. */ if (section->alignment_power == COFF_DEFAULT_SECTION_ALIGNMENT_POWER) section->alignment_power = 2; - return true; + return TRUE; } /* This is copied from bfd_coff_std_swap_table so that we can change the default section alignment power. */ -static const bfd_coff_backend_data bfd_coff_small_swap_table = +static bfd_coff_backend_data bfd_coff_small_swap_table = { coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, coff_swap_aux_out, coff_swap_sym_out, @@ -2970,16 +3083,23 @@ static const bfd_coff_backend_data bfd_coff_small_swap_table = coff_swap_scnhdr_out, FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ, FILNMLEN, #ifdef COFF_LONG_FILENAMES - true, + TRUE, #else - false, + FALSE, #endif -#ifdef COFF_LONG_SECTION_NAMES - true, + COFF_DEFAULT_LONG_SECTION_NAMES, + 2, +#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS + TRUE, #else - false, + FALSE, #endif +#ifdef COFF_DEBUG_STRING_WIDE_PREFIX + 4, +#else 2, +#endif + 32768, coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in, coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, @@ -2988,7 +3108,8 @@ static const bfd_coff_backend_data bfd_coff_small_swap_table = coff_classify_symbol, coff_compute_section_file_positions, coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, coff_adjust_symndx, coff_link_add_one_symbol, - coff_link_output_has_begun, coff_final_link_postscript + coff_link_output_has_begun, coff_final_link_postscript, + bfd_pe_print_pdata }; #define coff_small_close_and_cleanup \ @@ -3000,23 +3121,24 @@ static const bfd_coff_backend_data bfd_coff_small_swap_table = #define coff_small_get_section_contents_in_window \ coff_get_section_contents_in_window -extern const bfd_target shlcoff_small_vec; +extern const bfd_target sh_coff_small_le_vec; -const bfd_target shcoff_small_vec = +const bfd_target sh_coff_small_vec = { "coff-sh-small", /* name */ bfd_target_coff_flavour, BFD_ENDIAN_BIG, /* data byte order is big */ BFD_ENDIAN_BIG, /* header byte order is big */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE), + (HAS_RELOC | EXEC_P /* object flags */ + | HAS_LINENO | HAS_DEBUG + | HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE), (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), '_', /* leading symbol underscore */ '/', /* ar_pad_char */ 15, /* ar_max_namelen */ + 0, /* match priority. */ bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32, bfd_putb32, bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ @@ -3024,12 +3146,24 @@ const bfd_target shcoff_small_vec = bfd_getb32, bfd_getb_signed_32, bfd_putb32, bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, coff_small_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, + { /* bfd_check_format */ + _bfd_dummy_target, + coff_small_object_p, + bfd_generic_archive_p, + _bfd_dummy_target + }, + { /* bfd_set_format */ + _bfd_bool_bfd_false_error, + coff_mkobject, + _bfd_generic_mkarchive, + _bfd_bool_bfd_false_error + }, + { /* bfd_write_contents */ + _bfd_bool_bfd_false_error, + coff_write_object_contents, + _bfd_write_archive_contents, + _bfd_bool_bfd_false_error + }, BFD_JUMP_TABLE_GENERIC (coff_small), BFD_JUMP_TABLE_COPY (coff), @@ -3041,26 +3175,27 @@ const bfd_target shcoff_small_vec = BFD_JUMP_TABLE_LINK (coff), BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - & shlcoff_small_vec, - - (PTR) &bfd_coff_small_swap_table + &sh_coff_small_le_vec, + + &bfd_coff_small_swap_table }; -const bfd_target shlcoff_small_vec = +const bfd_target sh_coff_small_le_vec = { "coff-shl-small", /* name */ bfd_target_coff_flavour, BFD_ENDIAN_LITTLE, /* data byte order is little */ BFD_ENDIAN_LITTLE, /* header byte order is little endian too*/ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE), + (HAS_RELOC | EXEC_P /* object flags */ + | HAS_LINENO | HAS_DEBUG + | HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE), (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), '_', /* leading symbol underscore */ '/', /* ar_pad_char */ 15, /* ar_max_namelen */ + 0, /* match priority. */ bfd_getl64, bfd_getl_signed_64, bfd_putl64, bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ @@ -3068,12 +3203,24 @@ const bfd_target shlcoff_small_vec = bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - {_bfd_dummy_target, coff_small_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, + { /* bfd_check_format */ + _bfd_dummy_target, + coff_small_object_p, + bfd_generic_archive_p, + _bfd_dummy_target + }, + { /* bfd_set_format */ + _bfd_bool_bfd_false_error, + coff_mkobject, + _bfd_generic_mkarchive, + _bfd_bool_bfd_false_error + }, + { /* bfd_write_contents */ + _bfd_bool_bfd_false_error, + coff_write_object_contents, + _bfd_write_archive_contents, + _bfd_bool_bfd_false_error + }, BFD_JUMP_TABLE_GENERIC (coff_small), BFD_JUMP_TABLE_COPY (coff), @@ -3085,7 +3232,8 @@ const bfd_target shlcoff_small_vec = BFD_JUMP_TABLE_LINK (coff), BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - & shcoff_small_vec, - - (PTR) &bfd_coff_small_swap_table + &sh_coff_small_vec, + + &bfd_coff_small_swap_table }; +#endif