diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2004-05-17 21:54:57 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2004-05-17 21:54:57 +0000 |
commit | 631eeff208608ed7b44459bd6c8ae905bcd7e8b6 (patch) | |
tree | 7be124105a0929655708fbbc134f9c2e3189c3f3 /gnu/usr.bin/binutils/bfd/coff-arm.c | |
parent | a7c8e0ae4a4b349099d02bc9d56bcf1979c0f0c3 (diff) |
Resolve merge conflicts, adjust method of W^X handing (.sh files)
remove testsuites (not useable) remove mmalloc (not part of new binutils).
Diffstat (limited to 'gnu/usr.bin/binutils/bfd/coff-arm.c')
-rw-r--r-- | gnu/usr.bin/binutils/bfd/coff-arm.c | 1167 |
1 files changed, 618 insertions, 549 deletions
diff --git a/gnu/usr.bin/binutils/bfd/coff-arm.c b/gnu/usr.bin/binutils/bfd/coff-arm.c index 8bb4e6c4940..f089a6c824d 100644 --- a/gnu/usr.bin/binutils/bfd/coff-arm.c +++ b/gnu/usr.bin/binutils/bfd/coff-arm.c @@ -1,6 +1,6 @@ /* BFD back-end for ARM COFF files. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001 + 2000, 2001, 2002 Free Software Foundation, Inc. Written by Cygnus Support. @@ -36,18 +36,39 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Macros for manipulation the bits in the flags field of the coff data structure. */ -#define APCS_26_FLAG( abfd ) (coff_data (abfd)->flags & F_APCS_26) -#define APCS_FLOAT_FLAG( abfd ) (coff_data (abfd)->flags & F_APCS_FLOAT) -#define PIC_FLAG( abfd ) (coff_data (abfd)->flags & F_PIC) -#define APCS_SET( abfd ) (coff_data (abfd)->flags & F_APCS_SET) -#define SET_APCS_FLAGS( abfd, flgs) (coff_data (abfd)->flags = \ - (coff_data (abfd)->flags & ~ (F_APCS_26 | F_APCS_FLOAT | F_PIC)) \ - | (flgs | F_APCS_SET)) -#define INTERWORK_FLAG( abfd ) (coff_data (abfd)->flags & F_INTERWORK) -#define INTERWORK_SET( abfd ) (coff_data (abfd)->flags & F_INTERWORK_SET) -#define SET_INTERWORK_FLAG( abfd, flg ) (coff_data (abfd)->flags = \ - (coff_data (abfd)->flags & ~ F_INTERWORK) \ - | (flg | F_INTERWORK_SET)) +#define APCS_26_FLAG(abfd) \ + (coff_data (abfd)->flags & F_APCS_26) + +#define APCS_FLOAT_FLAG(abfd) \ + (coff_data (abfd)->flags & F_APCS_FLOAT) + +#define PIC_FLAG(abfd) \ + (coff_data (abfd)->flags & F_PIC) + +#define APCS_SET(abfd) \ + (coff_data (abfd)->flags & F_APCS_SET) + +#define SET_APCS_FLAGS(abfd, flgs) \ + do \ + { \ + coff_data (abfd)->flags &= ~(F_APCS_26 | F_APCS_FLOAT | F_PIC); \ + coff_data (abfd)->flags |= (flgs) | F_APCS_SET; \ + } \ + while (0) + +#define INTERWORK_FLAG(abfd) \ + (coff_data (abfd)->flags & F_INTERWORK) + +#define INTERWORK_SET(abfd) \ + (coff_data (abfd)->flags & F_INTERWORK_SET) + +#define SET_INTERWORK_FLAG(abfd, flg) \ + do \ + { \ + coff_data (abfd)->flags &= ~F_INTERWORK; \ + coff_data (abfd)->flags |= (flg) | F_INTERWORK_SET; \ + } \ + while (0) #ifndef NUM_ELEM #define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0])) @@ -59,66 +80,72 @@ typedef unsigned long int insn32; typedef unsigned short int insn16; /* Forward declarations for stupid compilers. */ -static boolean coff_arm_relocate_section +static bfd_boolean coff_arm_relocate_section PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, struct internal_reloc *, struct internal_syment *, asection **)); static bfd_reloc_status_type aoutarm_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static bfd_reloc_status_type aoutarm_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +#ifndef ARM_WINCE static bfd_reloc_status_type coff_thumb_pcrel_23 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type coff_thumb_pcrel_12 - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static bfd_reloc_status_type coff_thumb_pcrel_9 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static insn32 insert_thumb_branch + PARAMS ((insn32, int)); +#endif +static bfd_reloc_status_type coff_thumb_pcrel_12 + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static bfd_reloc_status_type coff_arm_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static boolean coff_arm_adjust_symndx +static bfd_boolean coff_arm_adjust_symndx PARAMS ((bfd *, struct bfd_link_info *, bfd *, - asection *, struct internal_reloc *, boolean *)); + asection *, struct internal_reloc *, bfd_boolean *)); static reloc_howto_type * coff_arm_rtype_to_howto PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *)); + struct coff_link_hash_entry *, struct internal_syment *, + bfd_vma *)); static bfd_reloc_status_type coff_thumb_pcrel_common PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **, thumb_pcrel_branchtype)); -static CONST struct reloc_howto_struct * coff_arm_reloc_type_lookup +static const struct reloc_howto_struct * coff_arm_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type)); static struct bfd_link_hash_table * coff_arm_link_hash_table_create PARAMS ((bfd *)); -static insn32 insert_thumb_branch - PARAMS ((insn32, int)); static struct coff_link_hash_entry * find_thumb_glue - PARAMS ((struct bfd_link_info *, CONST char *, bfd *)); + PARAMS ((struct bfd_link_info *, const char *, bfd *)); static struct coff_link_hash_entry * find_arm_glue - PARAMS ((struct bfd_link_info *, CONST char *, bfd *)); + PARAMS ((struct bfd_link_info *, const char *, bfd *)); #ifndef COFF_IMAGE_WITH_PE static void record_arm_to_thumb_glue PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *)); +#ifndef ARM_WINCE static void record_thumb_to_arm_glue PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *)); #endif -static boolean coff_arm_merge_private_bfd_data +#endif +static bfd_boolean coff_arm_merge_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean coff_arm_print_private_bfd_data +static bfd_boolean coff_arm_print_private_bfd_data PARAMS ((bfd *, PTR)); -static boolean _bfd_coff_arm_set_private_flags +static bfd_boolean _bfd_coff_arm_set_private_flags PARAMS ((bfd *, flagword)); -static boolean coff_arm_copy_private_bfd_data +static bfd_boolean coff_arm_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean coff_arm_is_local_label_name +static bfd_boolean coff_arm_is_local_label_name PARAMS ((bfd *, const char *)); -static boolean coff_arm_link_output_has_begun +static bfd_boolean coff_arm_link_output_has_begun PARAMS ((bfd *, struct coff_final_link_info *)); -static boolean coff_arm_final_link_postscript +static bfd_boolean coff_arm_final_link_postscript PARAMS ((bfd *, struct coff_final_link_info *)); +static void arm_emit_base_file_entry + PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_vma)); /* The linker script knows the section names for placement. The entry_names are used to do simple name mangling on the stubs. Given a function name, and its type, the stub can be found. The - name can be changed. The only requirement is the %s be present. - */ + name can be changed. The only requirement is the %s be present. */ #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t" #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb" @@ -127,6 +154,7 @@ static boolean coff_arm_final_link_postscript #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm" /* Used by the assembler. */ + static bfd_reloc_status_type coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) @@ -144,8 +172,9 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, diff = reloc_entry->addend; -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) +#define DOIT(x) \ + x = ((x & ~howto->dst_mask) \ + | (((x & howto->src_mask) + diff) & howto->dst_mask)) if (diff != 0) { @@ -166,7 +195,7 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, { short x = bfd_get_16 (abfd, addr); DOIT (x); - bfd_put_16 (abfd, x, addr); + bfd_put_16 (abfd, (bfd_vma) x, addr); } break; @@ -174,7 +203,7 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, { long x = bfd_get_32 (abfd, addr); DOIT (x); - bfd_put_32 (abfd, x, addr); + bfd_put_32 (abfd, (bfd_vma) x, addr); } break; @@ -195,7 +224,7 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, #endif #ifndef PCRELOFFSET -#define PCRELOFFSET true +#define PCRELOFFSET TRUE #endif /* These most certainly belong somewhere else. Just had to get rid of @@ -233,304 +262,304 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, #endif static reloc_howto_type aoutarm_std_reloc_howto[] = -{ - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ + { #ifdef ARM_WINCE - EMPTY_HOWTO (-1), - HOWTO (ARM_32, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), - HOWTO (ARM_RVA32, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_RVA32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), - HOWTO (ARM_26, - 2, - 2, - 24, - true, - 0, - complain_overflow_signed, - aoutarm_fix_pcrel_26 , - "ARM_26", - false, - 0x00ffffff, - 0x00ffffff, - PCRELOFFSET), - HOWTO (ARM_THUMB12, - 1, - 1, - 11, - true, - 0, - complain_overflow_signed, - coff_thumb_pcrel_12 , - "ARM_THUMB12", - false, - 0x000007ff, - 0x000007ff, - PCRELOFFSET), - HOWTO (ARM_26D, - 2, - 2, - 24, - false, - 0, - complain_overflow_dont, - aoutarm_fix_pcrel_26_done, - "ARM_26D", - true, - 0x00ffffff, - 0x0, - false), - EMPTY_HOWTO (-1), - EMPTY_HOWTO (-1), - EMPTY_HOWTO (-1), - EMPTY_HOWTO (-1), - EMPTY_HOWTO (-1), - EMPTY_HOWTO (-1), - EMPTY_HOWTO (-1), - EMPTY_HOWTO (-1), - HOWTO (ARM_SECTION, - 0, - 1, - 16, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_16", - true, - 0x0000ffff, - 0x0000ffff, - PCRELOFFSET), - HOWTO (ARM_SECREL, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), + EMPTY_HOWTO (-1), + HOWTO (ARM_32, + 0, + 2, + 32, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_32", + TRUE, + 0xffffffff, + 0xffffffff, + PCRELOFFSET), + HOWTO (ARM_RVA32, + 0, + 2, + 32, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_RVA32", + TRUE, + 0xffffffff, + 0xffffffff, + PCRELOFFSET), + HOWTO (ARM_26, + 2, + 2, + 24, + TRUE, + 0, + complain_overflow_signed, + aoutarm_fix_pcrel_26 , + "ARM_26", + FALSE, + 0x00ffffff, + 0x00ffffff, + PCRELOFFSET), + HOWTO (ARM_THUMB12, + 1, + 1, + 11, + TRUE, + 0, + complain_overflow_signed, + coff_thumb_pcrel_12 , + "ARM_THUMB12", + FALSE, + 0x000007ff, + 0x000007ff, + PCRELOFFSET), + HOWTO (ARM_26D, + 2, + 2, + 24, + FALSE, + 0, + complain_overflow_dont, + aoutarm_fix_pcrel_26_done, + "ARM_26D", + TRUE, + 0x00ffffff, + 0x0, + FALSE), + EMPTY_HOWTO (-1), + EMPTY_HOWTO (-1), + EMPTY_HOWTO (-1), + EMPTY_HOWTO (-1), + EMPTY_HOWTO (-1), + EMPTY_HOWTO (-1), + EMPTY_HOWTO (-1), + EMPTY_HOWTO (-1), + HOWTO (ARM_SECTION, + 0, + 1, + 16, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_16", + TRUE, + 0x0000ffff, + 0x0000ffff, + PCRELOFFSET), + HOWTO (ARM_SECREL, + 0, + 2, + 32, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_32", + TRUE, + 0xffffffff, + 0xffffffff, + PCRELOFFSET), #else /* not ARM_WINCE */ - HOWTO(ARM_8, /* type */ - 0, /* rightshift */ - 0, /* size */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_arm_reloc, /* special_function */ - "ARM_8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - PCRELOFFSET /* pcrel_offset */), - HOWTO(ARM_16, - 0, - 1, - 16, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_16", - true, - 0x0000ffff, - 0x0000ffff, - PCRELOFFSET), - HOWTO(ARM_32, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), - HOWTO(ARM_26, - 2, - 2, - 24, - true, - 0, - complain_overflow_signed, - aoutarm_fix_pcrel_26 , - "ARM_26", - false, - 0x00ffffff, - 0x00ffffff, - PCRELOFFSET), - HOWTO(ARM_DISP8, - 0, - 0, - 8, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "ARM_DISP8", - true, - 0x000000ff, - 0x000000ff, - true), - HOWTO( ARM_DISP16, - 0, - 1, - 16, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "ARM_DISP16", - true, - 0x0000ffff, - 0x0000ffff, - true), - HOWTO( ARM_DISP32, - 0, - 2, - 32, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "ARM_DISP32", - true, - 0xffffffff, - 0xffffffff, - true), - HOWTO( ARM_26D, - 2, - 2, - 24, - false, - 0, - complain_overflow_dont, - aoutarm_fix_pcrel_26_done, - "ARM_26D", - true, - 0x00ffffff, - 0x0, - false), - /* 8 is unused */ - EMPTY_HOWTO (-1), - HOWTO( ARM_NEG16, - 0, - -1, - 16, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_NEG16", - true, - 0x0000ffff, - 0x0000ffff, - false), - HOWTO( ARM_NEG32, - 0, - -2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_NEG32", - true, - 0xffffffff, - 0xffffffff, - false), - HOWTO( ARM_RVA32, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "ARM_RVA32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), - HOWTO( ARM_THUMB9, - 1, - 1, - 8, - true, - 0, - complain_overflow_signed, - coff_thumb_pcrel_9 , - "ARM_THUMB9", - false, - 0x000000ff, - 0x000000ff, - PCRELOFFSET), - HOWTO( ARM_THUMB12, - 1, - 1, - 11, - true, - 0, - complain_overflow_signed, - coff_thumb_pcrel_12 , - "ARM_THUMB12", - false, - 0x000007ff, - 0x000007ff, - PCRELOFFSET), - HOWTO( ARM_THUMB23, - 1, - 2, - 22, - true, - 0, - complain_overflow_signed, - coff_thumb_pcrel_23 , - "ARM_THUMB23", - false, - 0x07ff07ff, - 0x07ff07ff, - PCRELOFFSET) + HOWTO (ARM_8, /* type */ + 0, /* rightshift */ + 0, /* size */ + 8, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + coff_arm_reloc, /* special_function */ + "ARM_8", /* name */ + TRUE, /* partial_inplace */ + 0x000000ff, /* src_mask */ + 0x000000ff, /* dst_mask */ + PCRELOFFSET /* pcrel_offset */), + HOWTO (ARM_16, + 0, + 1, + 16, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_16", + TRUE, + 0x0000ffff, + 0x0000ffff, + PCRELOFFSET), + HOWTO (ARM_32, + 0, + 2, + 32, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_32", + TRUE, + 0xffffffff, + 0xffffffff, + PCRELOFFSET), + HOWTO (ARM_26, + 2, + 2, + 24, + TRUE, + 0, + complain_overflow_signed, + aoutarm_fix_pcrel_26 , + "ARM_26", + FALSE, + 0x00ffffff, + 0x00ffffff, + PCRELOFFSET), + HOWTO (ARM_DISP8, + 0, + 0, + 8, + TRUE, + 0, + complain_overflow_signed, + coff_arm_reloc, + "ARM_DISP8", + TRUE, + 0x000000ff, + 0x000000ff, + TRUE), + HOWTO (ARM_DISP16, + 0, + 1, + 16, + TRUE, + 0, + complain_overflow_signed, + coff_arm_reloc, + "ARM_DISP16", + TRUE, + 0x0000ffff, + 0x0000ffff, + TRUE), + HOWTO (ARM_DISP32, + 0, + 2, + 32, + TRUE, + 0, + complain_overflow_signed, + coff_arm_reloc, + "ARM_DISP32", + TRUE, + 0xffffffff, + 0xffffffff, + TRUE), + HOWTO (ARM_26D, + 2, + 2, + 24, + FALSE, + 0, + complain_overflow_dont, + aoutarm_fix_pcrel_26_done, + "ARM_26D", + TRUE, + 0x00ffffff, + 0x0, + FALSE), + /* 8 is unused */ + EMPTY_HOWTO (-1), + HOWTO (ARM_NEG16, + 0, + -1, + 16, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_NEG16", + TRUE, + 0x0000ffff, + 0x0000ffff, + FALSE), + HOWTO (ARM_NEG32, + 0, + -2, + 32, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_NEG32", + TRUE, + 0xffffffff, + 0xffffffff, + FALSE), + HOWTO (ARM_RVA32, + 0, + 2, + 32, + FALSE, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "ARM_RVA32", + TRUE, + 0xffffffff, + 0xffffffff, + PCRELOFFSET), + HOWTO (ARM_THUMB9, + 1, + 1, + 8, + TRUE, + 0, + complain_overflow_signed, + coff_thumb_pcrel_9 , + "ARM_THUMB9", + FALSE, + 0x000000ff, + 0x000000ff, + PCRELOFFSET), + HOWTO (ARM_THUMB12, + 1, + 1, + 11, + TRUE, + 0, + complain_overflow_signed, + coff_thumb_pcrel_12 , + "ARM_THUMB12", + FALSE, + 0x000007ff, + 0x000007ff, + PCRELOFFSET), + HOWTO (ARM_THUMB23, + 1, + 2, + 22, + TRUE, + 0, + complain_overflow_signed, + coff_thumb_pcrel_23 , + "ARM_THUMB23", + FALSE, + 0x07ff07ff, + 0x07ff07ff, + PCRELOFFSET) #endif /* not ARM_WINCE */ -}; + }; #define NUM_RELOCS NUM_ELEM (aoutarm_std_reloc_howto) #ifdef COFF_WITH_PE -/* Return true if this relocation should +static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *)); +/* Return TRUE if this relocation should appear in the output .reloc section. */ -static boolean +static bfd_boolean in_reloc_p (abfd, howto) bfd * abfd ATTRIBUTE_UNUSED; reloc_howto_type * howto; @@ -568,6 +597,7 @@ coff_arm_rtype_to_howto (abfd, sec, rel, h, sym, addendp) return howto; } + /* Used by the assembler. */ static bfd_reloc_status_type @@ -603,7 +633,7 @@ aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); bfd_reloc_status_type flag = bfd_reloc_ok; - /* If this is an undefined symbol, return error */ + /* If this is an undefined symbol, return error. */ if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0) return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; @@ -615,7 +645,7 @@ aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, return bfd_reloc_continue; relocation = (target & 0x00ffffff) << 2; - relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ + relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend. */ relocation += symbol->value; relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; @@ -627,18 +657,18 @@ aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, if (relocation & 3) return bfd_reloc_overflow; - /* Check for overflow */ + /* Check for overflow. */ if (relocation & 0x02000000) { if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff) flag = bfd_reloc_overflow; } - else if (relocation & ~0x03ffffff) + else if (relocation & ~(bfd_vma) 0x03ffffff) flag = bfd_reloc_overflow; target &= ~0x00ffffff; target |= (relocation >> 2) & 0x00ffffff; - bfd_put_32 (abfd, target, (bfd_byte *) data + addr); + bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr); /* Now the ARM magic... Change the reloc type so that it is marked as done. Strictly this is only necessary if we are doing a partial relocation. */ @@ -694,7 +724,7 @@ coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section, abort (); } - /* If this is an undefined symbol, return error */ + /* If this is an undefined symbol, return error. */ if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0) return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; @@ -723,7 +753,7 @@ coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section, abort (); } - relocation = (relocation ^ signbit) - signbit; /* Sign extend */ + relocation = (relocation ^ signbit) - signbit; /* Sign extend. */ relocation += symbol->value; relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; @@ -735,7 +765,7 @@ coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section, if (relocation & 1) return bfd_reloc_overflow; - /* Check for overflow */ + /* Check for overflow. */ if (relocation & signbit) { if ((relocation & ~offmsk) != ~offmsk) @@ -754,25 +784,28 @@ coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section, case b23: if (bfd_big_endian (abfd)) - target |= ((relocation & 0xfff) >> 1) | ((relocation << 4) & 0x07ff0000); + target |= (((relocation & 0xfff) >> 1) + | ((relocation << 4) & 0x07ff0000)); else - target |= ((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff); + target |= (((relocation & 0xffe) << 15) + | ((relocation >> 12) & 0x7ff)); break; default: abort (); } - bfd_put_32 (abfd, target, (bfd_byte *) data + addr); + bfd_put_32 (abfd, (bfd_vma) target, (bfd_byte *) data + addr); /* Now the ARM magic... Change the reloc type so that it is marked as done. Strictly this is only necessary if we are doing a partial relocation. */ reloc_entry->howto = & aoutarm_std_reloc_howto [ARM_26D]; - /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations */ + /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations. */ return flag; } +#ifndef ARM_WINCE static bfd_reloc_status_type coff_thumb_pcrel_23 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) @@ -785,11 +818,12 @@ coff_thumb_pcrel_23 (abfd, reloc_entry, symbol, data, input_section, char **error_message; { return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message, b23); + input_section, output_bfd, error_message, + b23); } static bfd_reloc_status_type -coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section, +coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd; arelent *reloc_entry; @@ -800,11 +834,13 @@ coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section, char **error_message; { return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message, b12); + input_section, output_bfd, error_message, + b9); } +#endif /* not ARM_WINCE */ static bfd_reloc_status_type -coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section, +coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd; arelent *reloc_entry; @@ -815,10 +851,11 @@ coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section, char **error_message; { return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message, b9); + input_section, output_bfd, error_message, + b12); } -static CONST struct reloc_howto_struct * +static const struct reloc_howto_struct * coff_arm_reloc_type_lookup (abfd, code) bfd * abfd; bfd_reloc_code_real_type code; @@ -831,7 +868,8 @@ coff_arm_reloc_type_lookup (abfd, code) case 32: code = BFD_RELOC_32; break; - default: return (CONST struct reloc_howto_struct *) 0; + default: + return (const struct reloc_howto_struct *) 0; } switch (code) @@ -856,7 +894,7 @@ coff_arm_reloc_type_lookup (abfd, code) ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23); ASTD (BFD_RELOC_THUMB_PCREL_BLX, ARM_THUMB23); #endif - default: return (CONST struct reloc_howto_struct *) 0; + default: return (const struct reloc_howto_struct *) 0; } } @@ -868,25 +906,32 @@ coff_arm_reloc_type_lookup (abfd, code) #define BADMAG(x) ARMBADMAG(x) #define ARM 1 /* Customize coffcode.h */ +#ifndef ARM_WINCE +/* Make sure that the 'r_offset' field is copied properly + so that identical binaries will compare the same. */ +#define SWAP_IN_RELOC_OFFSET H_GET_32 +#define SWAP_OUT_RELOC_OFFSET H_PUT_32 +#endif + /* Extend the coff_link_hash_table structure with a few ARM specific fields. This allows us to store global data here without actually creating any global variables, which is a no-no in the BFD world. */ struct coff_arm_link_hash_table -{ - /* The original coff_link_hash_table structure. MUST be first field. */ - struct coff_link_hash_table root; + { + /* The original coff_link_hash_table structure. MUST be first field. */ + struct coff_link_hash_table root; - /* The size in bytes of the section containg the Thumb-to-ARM glue. */ - long int thumb_glue_size; + /* The size in bytes of the section containg the Thumb-to-ARM glue. */ + bfd_size_type thumb_glue_size; - /* The size in bytes of the section containg the ARM-to-Thumb glue. */ - long int arm_glue_size; + /* The size in bytes of the section containg the ARM-to-Thumb glue. */ + bfd_size_type arm_glue_size; - /* An arbitary input BFD chosen to hold the glue sections. */ - bfd * bfd_of_glue_owner; + /* An arbitary input BFD chosen to hold the glue sections. */ + bfd * bfd_of_glue_owner; - /* Support interworking with old, non-interworking aware ARM code. */ - int support_old_code; + /* Support interworking with old, non-interworking aware ARM code. */ + int support_old_code; }; /* Get the ARM coff linker hash table from a link_info structure. */ @@ -900,16 +945,16 @@ coff_arm_link_hash_table_create (abfd) bfd * abfd; { struct coff_arm_link_hash_table * ret; + bfd_size_type amt = sizeof (struct coff_arm_link_hash_table); - ret = ((struct coff_arm_link_hash_table *) - bfd_alloc (abfd, sizeof (struct coff_arm_link_hash_table))); + ret = (struct coff_arm_link_hash_table *) bfd_malloc (amt); if (ret == (struct coff_arm_link_hash_table *) NULL) return NULL; if (! _bfd_coff_link_hash_table_init (& ret->root, abfd, _bfd_coff_link_hash_newfunc)) { - bfd_release (abfd, ret); + free (ret); return (struct bfd_link_hash_table *) NULL; } @@ -932,12 +977,13 @@ arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset) + input_section->output_offset + input_section->output_section->vma; - if (coff_data(output_bfd)->pe) - addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; - fwrite (&addr, 1, sizeof (addr), (FILE *) info->base_file); + if (coff_data (output_bfd)->pe) + addr -= pe_data (output_bfd)->pe_opthdr.ImageBase; + fwrite (& addr, 1, sizeof (addr), (FILE *) info->base_file); } +#ifndef ARM_WINCE /* The thumb form of a long branch is a bit finicky, because the offset encoding is split over two fields, each in it's own instruction. They can occur in any order. So given a thumb form of long branch, and an @@ -964,7 +1010,7 @@ arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset) moves the computed address into the PC, so it must be the second one in the sequence. The problem, however is that whilst little endian code stores the instructions in HI then LOW order, big endian code does the - reverse. nickc@cygnus.com */ + reverse. nickc@cygnus.com. */ #define LOW_HI_ORDER 0xF800F000 #define HI_LOW_ORDER 0xF000F800 @@ -988,65 +1034,67 @@ insert_thumb_branch (br_insn, rel_off) else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER) br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits; else - abort (); /* error - not a valid branch instruction form */ - - /* FIXME: abort is probably not the right call. krk@cygnus.com */ + /* FIXME: the BFD library should never abort except for internal errors + - it should return an error status. */ + abort (); /* Error - not a valid branch instruction form. */ return br_insn; } + static struct coff_link_hash_entry * find_thumb_glue (info, name, input_bfd) - struct bfd_link_info * info; - CONST char * name; - bfd * input_bfd; + struct bfd_link_info *info; + const char *name; + bfd *input_bfd; { - char * tmp_name; - struct coff_link_hash_entry * myh; + char *tmp_name; + struct coff_link_hash_entry *myh; + bfd_size_type amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1; - tmp_name = ((char *) - bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1)); + tmp_name = (char *) bfd_malloc (amt); BFD_ASSERT (tmp_name); sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name); myh = coff_link_hash_lookup - (coff_hash_table (info), tmp_name, false, false, true); + (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE); if (myh == NULL) /* xgettext:c-format */ _bfd_error_handler (_("%s: unable to find THUMB glue '%s' for `%s'"), - bfd_get_filename (input_bfd), tmp_name, name); + bfd_archive_filename (input_bfd), tmp_name, name); free (tmp_name); return myh; } +#endif /* not ARM_WINCE */ static struct coff_link_hash_entry * find_arm_glue (info, name, input_bfd) - struct bfd_link_info * info; - CONST char * name; - bfd * input_bfd; + struct bfd_link_info *info; + const char *name; + bfd *input_bfd; { - char * tmp_name; + char *tmp_name; struct coff_link_hash_entry * myh; + bfd_size_type amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1; - tmp_name = ((char *) - bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1)); + tmp_name = (char *) bfd_malloc (amt); BFD_ASSERT (tmp_name); sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name); myh = coff_link_hash_lookup - (coff_hash_table (info), tmp_name, false, false, true); + (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE); if (myh == NULL) /* xgettext:c-format */ _bfd_error_handler (_("%s: unable to find ARM glue '%s' for `%s'"), - bfd_get_filename (input_bfd), tmp_name, name); + bfd_archive_filename (input_bfd), tmp_name, name); free (tmp_name); @@ -1140,7 +1188,7 @@ static const insn32 t2a6_bx_insn = 0xe12fff1e; ARM/Thumb builds. It is only the code marked THUMBEXTENSION that is different from the original. */ -static boolean +static bfd_boolean coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, syms, sections) bfd *output_bfd; @@ -1196,7 +1244,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, howto = coff_rtype_to_howto (input_bfd, input_section, rel, h, sym, &addend); if (howto == NULL) - return false; + return FALSE; /* The relocation_section function will skip pcrel_offset relocs when doing a relocateable link. However, we want to convert @@ -1208,22 +1256,23 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, && info->relocateable && (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) - && h->root.u.def.section->output_section == input_section->output_section) + && (h->root.u.def.section->output_section + == input_section->output_section)) { static reloc_howto_type fake_arm26_reloc = HOWTO (ARM_26, 2, 2, 24, - true, + TRUE, 0, complain_overflow_signed, aoutarm_fix_pcrel_26 , "ARM_26", - false, + FALSE, 0x00ffffff, 0x00ffffff, - false); + FALSE); addend -= rel->r_vaddr - input_section->vma; howto = &fake_arm26_reloc; @@ -1232,9 +1281,12 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, #ifdef ARM_WINCE /* MS ARM-CE makes the reloc relative to the opcode's pc, not the next opcode's pc, so is off by one. */ +#if 0 /* This appears to have been true for WINCE 2.0, but it is not + true for WINCE 3.0. */ if (howto->pc_relative && !info->relocateable) addend -= 8; #endif +#endif /* If we are doing a relocateable link, then we can just ignore a PC relative reloc that is pcrel_offset. It will already @@ -1246,10 +1298,10 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, continue; /* FIXME - it is not clear which targets need this next test and which do not. It is known that it is needed for the - VXworks target (hence the #ifdef), but it is also known - that it was supressed for other (arm) targets. This ought - to be sorted out one day. */ -#ifdef VXWORKS + VxWorks and EPOC-PE targets, but it is also known that it + was supressed for other ARM targets. This ought to be + sorted out one day. */ +#ifdef ARM_COFF_BUGFIX /* We must not ignore the symbol value. If the symbol is within the same section, the relocation should have already been fixed, but if it is not, we'll be handed a reloc into @@ -1306,9 +1358,9 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, if ( h->class == C_THUMBSTATFUNC || h->class == C_THUMBEXTFUNC) { - /* Arm code calling a Thumb function */ + /* Arm code calling a Thumb function. */ unsigned long int tmp; - long int my_offset; + bfd_vma my_offset; asection * s; long int ret_offset; struct coff_link_hash_entry * myh; @@ -1316,7 +1368,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, myh = find_arm_glue (info, name, input_bfd); if (myh == NULL) - return false; + return FALSE; globals = coff_arm_hash_table (info); @@ -1340,20 +1392,20 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, _bfd_error_handler /* xgettext:c-format */ (_("%s(%s): warning: interworking not enabled."), - bfd_get_filename (h_sec->owner), name); + bfd_archive_filename (h_sec->owner), name); _bfd_error_handler /* xgettext:c-format */ (_(" first occurrence: %s: arm call to thumb"), - bfd_get_filename (input_bfd)); + bfd_archive_filename (input_bfd)); } --my_offset; myh->root.u.def.value = my_offset; - bfd_put_32 (output_bfd, a2t1_ldr_insn, + bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn, s->contents + my_offset); - bfd_put_32 (output_bfd, a2t2_bx_r12_insn, + bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn, s->contents + my_offset + 4); /* It's a thumb address. Add the low order bit. */ @@ -1362,7 +1414,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, if (info->base_file) arm_emit_base_file_entry (info, output_bfd, s, - my_offset + 8); + my_offset + 8); } @@ -1385,14 +1437,14 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF); - bfd_put_32 (output_bfd, tmp, contents + rel->r_vaddr - - input_section->vma); + bfd_put_32 (output_bfd, (bfd_vma) tmp, + contents + rel->r_vaddr - input_section->vma); done = 1; } } #ifndef ARM_WINCE - /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12 */ + /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */ else if (howto->type == ARM_THUMB23) { if ( h->class == C_EXT @@ -1401,7 +1453,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, { /* Thumb code calling an ARM function */ asection * s = 0; - long int my_offset; + bfd_vma my_offset; unsigned long int tmp; long int ret_offset; struct coff_link_hash_entry * myh; @@ -1409,7 +1461,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, myh = find_thumb_glue (info, name, input_bfd); if (myh == NULL) - return false; + return FALSE; globals = coff_arm_hash_table (info); @@ -1435,11 +1487,11 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, _bfd_error_handler /* xgettext:c-format */ (_("%s(%s): warning: interworking not enabled."), - bfd_get_filename (h_sec->owner), name); + bfd_archive_filename (h_sec->owner), name); _bfd_error_handler /* xgettext:c-format */ (_(" first occurrence: %s: thumb call to arm"), - bfd_get_filename (input_bfd)); + bfd_archive_filename (input_bfd)); _bfd_error_handler (_(" consider relinking with --support-old-code enabled")); } @@ -1449,22 +1501,22 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, if (globals->support_old_code) { - bfd_put_16 (output_bfd, t2a1_push_insn, + bfd_put_16 (output_bfd, (bfd_vma) t2a1_push_insn, s->contents + my_offset); - bfd_put_16 (output_bfd, t2a2_ldr_insn, + bfd_put_16 (output_bfd, (bfd_vma) t2a2_ldr_insn, s->contents + my_offset + 2); - bfd_put_16 (output_bfd, t2a3_mov_insn, + bfd_put_16 (output_bfd, (bfd_vma) t2a3_mov_insn, s->contents + my_offset + 4); - bfd_put_16 (output_bfd, t2a4_bx_insn, + bfd_put_16 (output_bfd, (bfd_vma) t2a4_bx_insn, s->contents + my_offset + 6); - bfd_put_32 (output_bfd, t2a5_pop_insn, + bfd_put_32 (output_bfd, (bfd_vma) t2a5_pop_insn, s->contents + my_offset + 8); - bfd_put_32 (output_bfd, t2a6_bx_insn, + bfd_put_32 (output_bfd, (bfd_vma) t2a6_bx_insn, s->contents + my_offset + 12); /* Store the address of the function in the last word of the stub. */ @@ -1472,18 +1524,19 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, s->contents + my_offset + 16); if (info->base_file) - arm_emit_base_file_entry (info, output_bfd, s, my_offset + 16); + arm_emit_base_file_entry (info, output_bfd, s, + my_offset + 16); } else { - bfd_put_16 (output_bfd, t2a1_bx_pc_insn, + bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn, s->contents + my_offset); - bfd_put_16 (output_bfd, t2a2_noop_insn, + bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn, s->contents + my_offset + 2); ret_offset = - ((bfd_signed_vma) h_val) /* Address of destination of the stub */ + ((bfd_signed_vma) h_val) /* Address of destination of the stub. */ - ((bfd_signed_vma) (s->output_offset /* Offset from the start of the current section to the start of the stubs. */ + my_offset /* Offset of the start of this stub from the start of the stubs. */ @@ -1492,7 +1545,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, + 8); /* ARM branches work from the pc of the instruction + 8. */ bfd_put_32 (output_bfd, - t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF), + (bfd_vma) t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF), s->contents + my_offset + 4); } @@ -1513,9 +1566,9 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, - input_section->vma); bfd_put_32 (output_bfd, - insert_thumb_branch (tmp, ret_offset), - contents + rel->r_vaddr - - input_section->vma); + (bfd_vma) insert_thumb_branch (tmp, + ret_offset), + contents + rel->r_vaddr - input_section->vma); done = 1; } @@ -1546,8 +1599,8 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, { if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma, true))) - return false; + rel->r_vaddr - input_section->vma, TRUE))) + return FALSE; } } @@ -1555,7 +1608,8 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, { /* Emit a reloc if the backend thinks it needs it. */ if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)) - arm_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr); + arm_emit_base_file_entry (info, output_bfd, input_section, + rel->r_vaddr); } #if 1 /* THUMBEXTENSION */ @@ -1580,18 +1634,18 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, rstat = bfd_reloc_outofrange; else { - bfd_vma relocation = val + addend; - int size = bfd_get_reloc_size (howto); - boolean overflow = false; - bfd_byte * location = contents + address; - bfd_vma x = bfd_get_32 (input_bfd, location); - bfd_vma src_mask = 0x007FFFFE; - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - bfd_vma check; - bfd_signed_vma signed_check; - bfd_vma add; - bfd_signed_vma signed_add; + bfd_vma relocation = val + addend; + int size = bfd_get_reloc_size (howto); + bfd_boolean overflow = FALSE; + bfd_byte *location = contents + address; + bfd_vma x = bfd_get_32 (input_bfd, location); + bfd_vma src_mask = 0x007FFFFE; + bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; + bfd_signed_vma reloc_signed_min = ~reloc_signed_max; + bfd_vma check; + bfd_signed_vma signed_check; + bfd_vma add; + bfd_signed_vma signed_add; BFD_ASSERT (size == 4); @@ -1648,23 +1702,25 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, /* Assumes two's complement. */ if ( signed_check > reloc_signed_max || signed_check < reloc_signed_min) - overflow = true; - - /* For the BLX(1) instruction remove bit 0 of the adjusted offset. - Bit 0 can only be set if the upper insn is at a half-word boundary, - since the destination address, an ARM instruction, must always be - on a word boundary. The semantics of the BLX (1) instruction, - however, are that bit 0 in the offset must always be 0, and the - corresponding bit 1 in the target address will be set from bit - 1 of the source address. */ - if ((x & 0x18000000) == 0x08000000) - relocation &= ~0x2; - - /* Put the relocation into the correct bits. */ + overflow = TRUE; + + /* Put the relocation into the correct bits. + For a BLX instruction, make sure that the relocation is rounded up + to a word boundary. This follows the semantics of the instruction + which specifies that bit 1 of the target address will come from bit + 1 of the base address. */ if (bfd_big_endian (input_bfd)) - relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000)); + { + if ((x & 0x1800) == 0x0800 && (relocation & 0x02)) + relocation += 2; + relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000)); + } else - relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff)); + { + if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02)) + relocation += 2; + relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff)); + } /* Add the relocation to the correct bits of X. */ x = ((x & ~howto->dst_mask) | relocation); @@ -1693,13 +1749,13 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, /* Determine if we need to set the bottom bit of a relocated address because the address is the address of a Thumb code symbol. */ - int patchit = false; + int patchit = FALSE; if (h != NULL && ( h->class == C_THUMBSTATFUNC || h->class == C_THUMBEXTFUNC)) { - patchit = true; + patchit = TRUE; } else if (sym != NULL && sym->n_scnum > N_UNDEF) @@ -1708,7 +1764,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, if ( sym->n_sclass == C_THUMBSTATFUNC || sym->n_sclass == C_THUMBEXTFUNC) - patchit = true; + patchit = TRUE; } if (patchit) @@ -1730,10 +1786,10 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, case bfd_reloc_outofrange: (*_bfd_error_handler) (_("%s: bad reloc address 0x%lx in section `%s'"), - bfd_get_filename (input_bfd), + bfd_archive_filename (input_bfd), (unsigned long) rel->r_vaddr, bfd_get_section_name (input_bfd, input_section)); - return false; + return FALSE; case bfd_reloc_overflow: { const char *name; @@ -1747,23 +1803,23 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section, { name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); if (name == NULL) - return false; + return FALSE; } if (! ((*info->callbacks->reloc_overflow) (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_vaddr - input_section->vma))) - return false; + return FALSE; } } } - return true; + return TRUE; } #ifndef COFF_IMAGE_WITH_PE -boolean +bfd_boolean bfd_arm_allocate_interworking_sections (info) struct bfd_link_info * info; { @@ -1787,10 +1843,10 @@ bfd_arm_allocate_interworking_sections (info) BFD_ASSERT (s != NULL); - foo = (bfd_byte *) bfd_alloc - (globals->bfd_of_glue_owner, globals->arm_glue_size); + foo = (bfd_byte *) bfd_alloc (globals->bfd_of_glue_owner, + globals->arm_glue_size); #if 0 - memset (foo, test_char, globals->arm_glue_size); + memset (foo, test_char, (size_t) globals->arm_glue_size); #endif s->_raw_size = s->_cooked_size = globals->arm_glue_size; @@ -1806,17 +1862,17 @@ bfd_arm_allocate_interworking_sections (info) BFD_ASSERT (s != NULL); - foo = (bfd_byte *) bfd_alloc - (globals->bfd_of_glue_owner, globals->thumb_glue_size); + foo = (bfd_byte *) bfd_alloc (globals->bfd_of_glue_owner, + globals->thumb_glue_size); #if 0 - memset (foo, test_char, globals->thumb_glue_size); + memset (foo, test_char, (size_t) globals->thumb_glue_size); #endif s->_raw_size = s->_cooked_size = globals->thumb_glue_size; s->contents = foo; } - return true; + return TRUE; } static void @@ -1828,7 +1884,10 @@ record_arm_to_thumb_glue (info, h) register asection * s; char * tmp_name; struct coff_link_hash_entry * myh; + struct bfd_link_hash_entry * bh; struct coff_arm_link_hash_table * globals; + bfd_vma val; + bfd_size_type amt; globals = coff_arm_hash_table (info); @@ -1840,15 +1899,15 @@ record_arm_to_thumb_glue (info, h) BFD_ASSERT (s != NULL); - tmp_name = ((char *) - bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1)); + amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1; + tmp_name = (char *) bfd_malloc (amt); BFD_ASSERT (tmp_name); sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name); myh = coff_link_hash_lookup - (coff_hash_table (info), tmp_name, false, false, true); + (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE); if (myh != NULL) { @@ -1860,11 +1919,10 @@ record_arm_to_thumb_glue (info, h) though the section isn't allocated yet, this is where we will be putting it. */ + bh = NULL; + val = globals->arm_glue_size + 1; bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, - BSF_GLOBAL, - s, globals->arm_glue_size + 1, - NULL, true, false, - (struct bfd_link_hash_entry **) & myh); + BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh); free (tmp_name); @@ -1873,6 +1931,7 @@ record_arm_to_thumb_glue (info, h) return; } +#ifndef ARM_WINCE static void record_thumb_to_arm_glue (info, h) struct bfd_link_info * info; @@ -1882,7 +1941,10 @@ record_thumb_to_arm_glue (info, h) register asection * s; char * tmp_name; struct coff_link_hash_entry * myh; + struct bfd_link_hash_entry * bh; struct coff_arm_link_hash_table * globals; + bfd_vma val; + bfd_size_type amt; globals = coff_arm_hash_table (info); @@ -1894,14 +1956,15 @@ record_thumb_to_arm_glue (info, h) BFD_ASSERT (s != NULL); - tmp_name = (char *) bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1); + amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1; + tmp_name = (char *) bfd_malloc (amt); BFD_ASSERT (tmp_name); sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name); myh = coff_link_hash_lookup - (coff_hash_table (info), tmp_name, false, false, true); + (coff_hash_table (info), tmp_name, FALSE, FALSE, TRUE); if (myh != NULL) { @@ -1909,12 +1972,13 @@ record_thumb_to_arm_glue (info, h) return; /* we've already seen this guy */ } + bh = NULL; + val = globals->thumb_glue_size + 1; bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, - BSF_GLOBAL, s, globals->thumb_glue_size + 1, - NULL, true, false, - (struct bfd_link_hash_entry **) & myh); + BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh); /* If we mark it 'thumb', the disassembler will do a better job. */ + myh = (struct coff_link_hash_entry *) bh; myh->class = C_THUMBEXTFUNC; free (tmp_name); @@ -1924,19 +1988,17 @@ record_thumb_to_arm_glue (info, h) #define CHANGE_TO_ARM "__%s_change_to_arm" #define BACK_FROM_ARM "__%s_back_from_arm" - tmp_name = (char *) bfd_malloc (strlen (name) + strlen (CHANGE_TO_ARM) + 1); + amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1; + tmp_name = (char *) bfd_malloc (amt); BFD_ASSERT (tmp_name); sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name); - myh = NULL; - + bh = NULL; + val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4); bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, - BSF_LOCAL, s, globals->thumb_glue_size - + (globals->support_old_code ? 8 : 4), - NULL, true, false, - (struct bfd_link_hash_entry **) & myh); + BSF_LOCAL, s, val, NULL, TRUE, FALSE, &bh); free (tmp_name); @@ -1944,12 +2006,13 @@ record_thumb_to_arm_glue (info, h) return; } +#endif /* not ARM_WINCE */ /* Select a BFD to be used to hold the sections used by the glue code. This function is called from the linker scripts in ld/emultempl/ {armcoff/pe}.em */ -boolean +bfd_boolean bfd_arm_get_bfd_for_interworking (abfd, info) bfd * abfd; struct bfd_link_info * info; @@ -1961,14 +2024,14 @@ bfd_arm_get_bfd_for_interworking (abfd, info) /* If we are only performing a partial link do not bother getting a bfd to hold the glue. */ if (info->relocateable) - return true; + return TRUE; globals = coff_arm_hash_table (info); BFD_ASSERT (globals != NULL); if (globals->bfd_of_glue_owner != NULL) - return true; + return TRUE; sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME); @@ -1981,7 +2044,7 @@ bfd_arm_get_bfd_for_interworking (abfd, info) if (sec == NULL || ! bfd_set_section_flags (abfd, sec, flags) || ! bfd_set_section_alignment (abfd, sec, 2)) - return false; + return FALSE; } sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME); @@ -1995,16 +2058,16 @@ bfd_arm_get_bfd_for_interworking (abfd, info) if (sec == NULL || ! bfd_set_section_flags (abfd, sec, flags) || ! bfd_set_section_alignment (abfd, sec, 2)) - return false; + return FALSE; } /* Save the bfd for later use. */ globals->bfd_of_glue_owner = abfd; - return true; + return TRUE; } -boolean +bfd_boolean bfd_arm_process_before_allocation (abfd, info, support_old_code) bfd * abfd; struct bfd_link_info * info; @@ -2016,7 +2079,7 @@ bfd_arm_process_before_allocation (abfd, info, support_old_code) /* If we are only performing a partial link do not bother to construct any glue. */ if (info->relocateable) - return true; + return TRUE; /* Here we have a bfd that is to be included on the link. We have a hook to do reloc rummaging, before section sizes are nailed down. */ @@ -2034,7 +2097,7 @@ bfd_arm_process_before_allocation (abfd, info, support_old_code) sec = abfd->sections; if (sec == NULL) - return true; + return TRUE; for (; sec != NULL; sec = sec->next) { @@ -2067,7 +2130,7 @@ bfd_arm_process_before_allocation (abfd, info, support_old_code) if (symndx >= obj_conv_table_size (abfd)) { _bfd_error_handler (_("%s: illegal symbol index in reloc: %d"), - bfd_get_filename (abfd), symndx); + bfd_archive_filename (abfd), symndx); continue; } @@ -2118,7 +2181,7 @@ bfd_arm_process_before_allocation (abfd, info, support_old_code) } } - return true; + return TRUE; } #endif /* ! defined (COFF_IMAGE_WITH_PE) */ @@ -2138,14 +2201,14 @@ bfd_arm_process_before_allocation (abfd, info, support_old_code) /* When doing a relocateable link, we want to convert ARM26 relocs into ARM26D relocs. */ -static boolean +static bfd_boolean coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp) bfd *obfd ATTRIBUTE_UNUSED; struct bfd_link_info *info ATTRIBUTE_UNUSED; bfd *ibfd; asection *sec; struct internal_reloc *irel; - boolean *adjustedp; + bfd_boolean *adjustedp; { if (irel->r_type == 3) { @@ -2158,8 +2221,8 @@ coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp) && h->root.u.def.section->output_section == sec->output_section) irel->r_type = 7; } - *adjustedp = false; - return true; + *adjustedp = FALSE; + return TRUE; } /* Called when merging the private data areas of two BFDs. @@ -2167,7 +2230,7 @@ coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp) attempting to merge binaries compiled for different ARM targets, eg different CPUs or differents APCS's. */ -static boolean +static bfd_boolean coff_arm_merge_private_bfd_data (ibfd, obfd) bfd * ibfd; bfd * obfd; @@ -2175,16 +2238,21 @@ coff_arm_merge_private_bfd_data (ibfd, obfd) BFD_ASSERT (ibfd != NULL && obfd != NULL); if (ibfd == obfd) - return true; + return TRUE; /* If the two formats are different we cannot merge anything. This is not an error, since it is permissable to change the input and output formats. */ if ( ibfd->xvec->flavour != bfd_target_coff_flavour || obfd->xvec->flavour != bfd_target_coff_flavour) - return true; + return TRUE; + + /* Determine what should happen if the input ARM architecture + does not match the output ARM architecture. */ + if (! bfd_arm_merge_machines (ibfd, obfd)) + return FALSE; - /* Verify that the APCS is the same for the two BFDs */ + /* Verify that the APCS is the same for the two BFDs. */ if (APCS_SET (ibfd)) { if (APCS_SET (obfd)) @@ -2194,13 +2262,13 @@ coff_arm_merge_private_bfd_data (ibfd, obfd) { _bfd_error_handler /* xgettext: c-format */ - (_("%s: ERROR: compiled for APCS-%d whereas target %s uses APCS-%d"), - bfd_get_filename (ibfd), APCS_26_FLAG (ibfd) ? 26 : 32, + (_("ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"), + bfd_archive_filename (ibfd), APCS_26_FLAG (ibfd) ? 26 : 32, bfd_get_filename (obfd), APCS_26_FLAG (obfd) ? 26 : 32 ); bfd_set_error (bfd_error_wrong_format); - return false; + return FALSE; } if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd)) @@ -2209,16 +2277,16 @@ coff_arm_merge_private_bfd_data (ibfd, obfd) if (APCS_FLOAT_FLAG (ibfd)) /* xgettext: c-format */ - msg = _("%s: ERROR: passes floats in float registers whereas target %s uses integer registers"); + msg = _("ERROR: %s passes floats in float registers, whereas %s passes them in integer registers"); else /* xgettext: c-format */ - msg = _("%s: ERROR: passes floats in integer registers whereas target %s uses float registers"); + msg = _("ERROR: %s passes floats in integer registers, whereas %s passes them in float registers"); - _bfd_error_handler (msg, bfd_get_filename (ibfd), + _bfd_error_handler (msg, bfd_archive_filename (ibfd), bfd_get_filename (obfd)); bfd_set_error (bfd_error_wrong_format); - return false; + return FALSE; } if (PIC_FLAG (obfd) != PIC_FLAG (ibfd)) @@ -2227,15 +2295,15 @@ coff_arm_merge_private_bfd_data (ibfd, obfd) if (PIC_FLAG (ibfd)) /* xgettext: c-format */ - msg = _("%s: ERROR: compiled as position independent code, whereas target %s is absolute position"); + msg = _("ERROR: %s is compiled as position independent code, whereas target %s is absolute position"); else /* xgettext: c-format */ - msg = _("%s: ERROR: compiled as absolute position code, whereas target %s is position independent"); - _bfd_error_handler (msg, bfd_get_filename (ibfd), + msg = _("ERROR: %s is compiled as absolute position code, whereas target %s is position independent"); + _bfd_error_handler (msg, bfd_archive_filename (ibfd), bfd_get_filename (obfd)); bfd_set_error (bfd_error_wrong_format); - return false; + return FALSE; } } else @@ -2259,12 +2327,12 @@ coff_arm_merge_private_bfd_data (ibfd, obfd) if (INTERWORK_FLAG (ibfd)) /* xgettext: c-format */ - msg = _("Warning: input file %s supports interworking, whereas %s does not."); + msg = _("Warning: %s supports interworking, whereas %s does not"); else /* xgettext: c-format */ - msg = _("Warning: input file %s does not support interworking, whereas %s does."); + msg = _("Warning: %s does not support interworking, whereas %s does"); - _bfd_error_handler (msg, bfd_get_filename (ibfd), + _bfd_error_handler (msg, bfd_archive_filename (ibfd), bfd_get_filename (obfd)); } } @@ -2274,12 +2342,12 @@ coff_arm_merge_private_bfd_data (ibfd, obfd) } } - return true; + return TRUE; } /* Display the flags field. */ -static boolean +static bfd_boolean coff_arm_print_private_bfd_data (abfd, ptr) bfd * abfd; PTR ptr; @@ -2316,7 +2384,7 @@ coff_arm_print_private_bfd_data (abfd, ptr) fputc ('\n', file); - return true; + return TRUE; } /* Copies the given flags into the coff_tdata.flags field. @@ -2326,7 +2394,7 @@ coff_arm_print_private_bfd_data (abfd, ptr) Note: Although this function is static, it is explicitly called from both coffcode.h and peicode.h. */ -static boolean +static bfd_boolean _bfd_coff_arm_set_private_flags (abfd, flags) bfd * abfd; flagword flags; @@ -2344,7 +2412,7 @@ _bfd_coff_arm_set_private_flags (abfd, flags) || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT)) || (PIC_FLAG (abfd) != (flags & F_PIC)) )) - return false; + return FALSE; flag |= (flags & (F_APCS_FLOAT | F_PIC)); @@ -2360,24 +2428,24 @@ _bfd_coff_arm_set_private_flags (abfd, flags) { if (flag) /* xgettext: c-format */ - _bfd_error_handler (_("Warning: Not setting interworking flag of %s, since it has already been specified as non-interworking"), - bfd_get_filename (abfd)); + _bfd_error_handler (_("Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"), + bfd_archive_filename (abfd)); else /* xgettext: c-format */ _bfd_error_handler (_("Warning: Clearing the interworking flag of %s due to outside request"), - bfd_get_filename (abfd)); + bfd_archive_filename (abfd)); flag = 0; } SET_INTERWORK_FLAG (abfd, flag); - return true; + return TRUE; } /* Copy the important parts of the target specific data from one instance of a BFD to another. */ -static boolean +static bfd_boolean coff_arm_copy_private_bfd_data (src, dest) bfd * src; bfd * dest; @@ -2385,12 +2453,12 @@ coff_arm_copy_private_bfd_data (src, dest) BFD_ASSERT (src != NULL && dest != NULL); if (src == dest) - return true; + return TRUE; /* If the destination is not in the same format as the source, do not do the copy. */ if (src->xvec != dest->xvec) - return true; + return TRUE; /* copy the flags field */ if (APCS_SET (src)) @@ -2399,13 +2467,13 @@ coff_arm_copy_private_bfd_data (src, dest) { /* If the src and dest have different APCS flag bits set, fail. */ if (APCS_26_FLAG (dest) != APCS_26_FLAG (src)) - return false; + return FALSE; if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src)) - return false; + return FALSE; if (PIC_FLAG (dest) != PIC_FLAG (src)) - return false; + return FALSE; } else SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src) @@ -2423,9 +2491,10 @@ coff_arm_copy_private_bfd_data (src, dest) if (INTERWORK_FLAG (dest)) { /* xgettext:c-format */ - _bfd_error_handler (("Warning: Clearing the interworking bit of %s, because the non-interworking code in %s has been copied into it"), + _bfd_error_handler (("\ +Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"), bfd_get_filename (dest), - bfd_get_filename (src)); + bfd_archive_filename (src)); } SET_INTERWORK_FLAG (dest, 0); @@ -2437,7 +2506,7 @@ coff_arm_copy_private_bfd_data (src, dest) } } - return true; + return TRUE; } /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX @@ -2452,7 +2521,7 @@ coff_arm_copy_private_bfd_data (src, dest) non-local. b) Allow other prefixes than ".", e.g. an empty prefix would cause all labels of the form Lxxx to be stripped. */ -static boolean +static bfd_boolean coff_arm_is_local_label_name (abfd, name) bfd * abfd ATTRIBUTE_UNUSED; const char * name; @@ -2461,7 +2530,7 @@ coff_arm_is_local_label_name (abfd, name) if (USER_LABEL_PREFIX[0] != 0) { if (strncmp (name, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)) == 0) - return false; + return FALSE; } #endif @@ -2471,10 +2540,10 @@ coff_arm_is_local_label_name (abfd, name) if (LOCAL_LABEL_PREFIX[0] != 0) { - int len = strlen (LOCAL_LABEL_PREFIX); + size_t len = strlen (LOCAL_LABEL_PREFIX); if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0) - return false; + return FALSE; /* Perform the checks below for the rest of the name. */ name += len; @@ -2492,7 +2561,7 @@ coff_arm_is_local_label_name (abfd, name) krk@cygnus.com */ -static boolean +static bfd_boolean coff_arm_link_output_has_begun (sub, info) bfd * sub; struct coff_final_link_info * info; @@ -2501,7 +2570,7 @@ coff_arm_link_output_has_begun (sub, info) || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner); } -static boolean +static bfd_boolean coff_arm_final_link_postscript (abfd, pfinfo) bfd * abfd ATTRIBUTE_UNUSED; struct coff_final_link_info * pfinfo; @@ -2515,12 +2584,12 @@ coff_arm_final_link_postscript (abfd, pfinfo) if (globals->bfd_of_glue_owner != NULL) { if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner)) - return false; + return FALSE; - globals->bfd_of_glue_owner->output_has_begun = true; + globals->bfd_of_glue_owner->output_has_begun = TRUE; } - return true; + return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION); } #include "coffcode.h" |