From 46686c7839c7872d851d9a43df81953dbfc25dc0 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 14 May 1997 17:00:43 +0000 Subject: [PATCH] Added support for storing ARM Procedure Calling Standard variant, and ARM architecture variant in the BFD and COFF structures. This goes towards fixing PRs 11709 and 11326 and will integrate with future updates to LD and GCC. --- bfd/ChangeLog | 34 +++++++ bfd/coff-arm.c | 224 ++++++++++++++++++++++++++++++++++++++++++-- bfd/coffcode.h | 138 +++++++++++++++++++++++---- bfd/cpu-arm.c | 108 +++++++++++++++++++++ gas/ChangeLog | 12 +++ gas/config/tc-arm.c | 114 ++++++++++++++++++++-- include/ChangeLog | 14 +++ 7 files changed, 611 insertions(+), 33 deletions(-) create mode 100644 bfd/cpu-arm.c diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 28f8bdc65f..1fd14c41d8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,37 @@ +Fri May 9 10:15:27 1997 Nick Clifton + + * archures.c (constants): Added new constants to identify the + type of the ARM architecture: bfd_mach_arm_2, bfd_mach_arm_2a, + bfd_mach_arm_3, bfd_mach_arm_3M, bfd_mach_arm_4 and bfd_mach_arm_4T. + + * bfd-in2.h (constants): Added new constants to identify + the type of the ARM architecture: bfd_mach_arm_2, bfd_mach_arm_2a, + bfd_mach_arm_3, bfd_mach_arm_3M, bfd_mach_arm_4 and + bfd_mach_arm_4T. This file is auto-magically generated from the + archures.c file. This update is just to save work. + + * coff-arm.c (coff_arm_bfd_merge_private_bfd_data, + coff_arm_bfd_print_private_bfd_data, + coff_arm_bfd_set_private_flags, + coff_arm_bfd_copy_private_bfd_data): Added these new functions. + (global): Macro redefinitions set up to use these new functions. + + * coffcode.h (coff_mkobject_hook): Added call to + coff_arm_bfd_set_private_flags(). (coff_set_arch_mach_hook): + Added code to set machine type based on bits stored in internal + flags. (coff_set_flags): Added code to set the new bits in the + flags field based on the machine number. + + (function definition macros): Made all function definition macros + conditional so that they can be overridden by target specific + files. + + * cpu-arm.c (compatible): Added this function. (arch_info_struct): + Structure extended to include new types, one each for ARMv2, + ARMv2a, ARMv3, ARMv3M, ARMv4 and ARMv4T. + + * libcoff-in.h (struct coff_tdata): Added flags field. + Fri May 9 17:40:02 1997 Ian Lance Taylor * config.bfd (i[3456]86-*-gnu*): Don't include Mach support. diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index a33bbb229b..1f0e348c00 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -1,5 +1,5 @@ /* BFD back-end for ARM COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" #include "libbfd.h" -#include "obstack.h" #include "coff/arm.h" @@ -44,7 +43,9 @@ aoutarm_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, static bfd_reloc_status_type coff_arm_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - +static boolean coff_arm_adjust_symndx + PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, + struct internal_reloc *, boolean *)); /* Used by the assembler. */ static bfd_reloc_status_type @@ -216,7 +217,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = "ARM26D", true, 0x00ffffff, - 0x00ffffff, + 0x0, false), {-1}, HOWTO( 9, @@ -294,6 +295,37 @@ coff_arm_rtype_to_howto (abfd, sec, rel, h, sym, addendp) { *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; } + + /* The relocation_section function will skip pcrel_offset relocs + when doing a relocateable link. However, we want to convert + ARM26 to ARM26D relocs if possible. We return a fake howto in + this case without pcrel_offset set, and adjust the addend to + compensate. */ + if (rel->r_type == 3 + && h != NULL + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && h->root.u.def.section->output_section == sec->output_section) + { + static reloc_howto_type fake_arm26_reloc = + HOWTO (3, + 2, + 2, + 26, + true, + 0, + complain_overflow_signed, + aoutarm_fix_pcrel_26 , + "ARM26", + false, + 0x00ffffff, + 0x00ffffff, + false); + + *addendp -= rel->r_vaddr - sec->vma; + return &fake_arm26_reloc; + } + return howto; } @@ -419,6 +451,170 @@ arm_reloc_type_lookup(abfd,code) /* We use the special COFF backend linker. */ #define coff_relocate_section _bfd_coff_generic_relocate_section +/* When doing a relocateable link, we want to convert ARM26 relocs + into ARM26D relocs. */ + +static boolean +coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp) + bfd *obfd; + struct bfd_link_info *info; + bfd *ibfd; + asection *sec; + struct internal_reloc *irel; + boolean *adjustedp; +{ + if (irel->r_type == 3) + { + struct coff_link_hash_entry *h; + + h = obj_coff_sym_hashes (ibfd)[irel->r_symndx]; + if (h != NULL + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && h->root.u.def.section->output_section == sec->output_section) + irel->r_type = 7; + } + *adjustedp = false; + return true; +} + + +#define APCS_FLAG( abfd ) (coff_data (abfd)->flags & F_APCS_26) +#define APCS_SET( abfd ) (coff_data (abfd)->flags & F_APCS_SET) +#define SET_APCS_FLAG( abfd, flg ) (coff_data (abfd)->flags = (coff_data (abfd)->flags & ~ F_APCS_26) | (flg | F_APCS_SET)) + +/* Called when merging the private data areas of two BFDs. + This is important as it allows us to detect if we are + attempting to merge binaries compiled for different ARM + targets, eg different CPUs or differents APCS's. */ + +boolean +coff_arm_bfd_merge_private_bfd_data (ibfd, obfd) + bfd * ibfd; + bfd * obfd; +{ + BFD_ASSERT (ibfd != NULL && obfd != NULL) + + if (ibfd == obfd) + return true; + + /* If the two formats are different we cannot check anything */ + if (ibfd->xvec != obfd->xvec) + return true; + + /* Verify that the APCS is the same for the two BFDs */ + if (APCS_SET (ibfd)) + { + if (APCS_SET (obfd)) + { + /* If the src and dest have different APCS flag bits set, fail */ + if (APCS_FLAG (obfd) != APCS_FLAG (ibfd)) + { + _bfd_error_handler + ("%s: ERROR: compiled for APCS-%d whereas target %s uses APCS-%d", + bfd_get_filename (ibfd), APCS_FLAG (ibfd) ? 26 : 32, + bfd_get_filename (obfd), APCS_FLAG (obfd) ? 26 : 32 + ); + + bfd_set_error (bfd_error_wrong_format); + return false; + } + } + else + SET_APCS_FLAG (obfd, APCS_FLAG (ibfd)); + } + + return true; +} + + +/* Display the flags field */ + +boolean +coff_arm_bfd_print_private_bfd_data (abfd, ptr) + bfd * abfd; + PTR ptr; +{ + FILE * file = (FILE *) ptr; + + BFD_ASSERT (abfd != NULL && ptr != NULL) + + fprintf (file, "private flags = %x", coff_data( abfd )->flags); + + if (APCS_SET (abfd)) + fprintf (file, ": [APCS-%d]", APCS_FLAG( abfd ) ? 26 : 32); + + fputc ('\n', file); + + return true; +} + + +/* Copies the given flags into the coff_tdata.flags field. + Typically these flags come from the f_flags[] field of + the COFF filehdr structure, which contains important, + target specific information. */ + +boolean +coff_arm_bfd_set_private_flags (abfd, flags) + bfd * abfd; + flagword flags; +{ + int flag; + + BFD_ASSERT (abfd != NULL); + + flag = (flags & F_APCS26) ? F_APCS_26 : 0; + + /* Make sure that the APCS field has not been initialised to the opposite value */ + if (APCS_SET (abfd) && (APCS_FLAG (abfd) != flag)) + return false; + + SET_APCS_FLAG (abfd, flag); + + return true; +} + + +/* Copy the important parts of the target specific data + from one instance of a BFD to another. */ + +boolean +coff_arm_bfd_copy_private_bfd_data (src, dest) + bfd * src; + bfd * dest; +{ + BFD_ASSERT (src != NULL && dest != NULL) + + if (src == dest) + 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; + + /* copy the flags field */ + if (APCS_SET (src)) + { + if (APCS_SET (dest)) + { + /* If the src and dest have different APCS flag bits set, fail */ + if (APCS_FLAG (dest) != APCS_FLAG (src)) + return false; + } + else + SET_APCS_FLAG (dest, APCS_FLAG (src)); + } + + return true; +} + + +#define coff_adjust_symndx coff_arm_adjust_symndx +#define coff_bfd_merge_private_bfd_data coff_arm_bfd_merge_private_bfd_data +#define coff_bfd_print_private_bfd_data coff_arm_bfd_print_private_bfd_data +#define coff_bfd_set_private_flags coff_arm_bfd_set_private_flags +#define coff_bfd_copy_private_bfd_data coff_arm_bfd_copy_private_bfd_data #include "coffcode.h" @@ -435,14 +631,20 @@ armcoff_little_vec = "coff-arm-little", #endif bfd_target_coff_flavour, - false, /* data byte order is little */ - false, /* header byte order is little */ + BFD_ENDIAN_LITTLE, /* data byte order is little */ + BFD_ENDIAN_LITTLE, /* header byte order is little */ (HAS_RELOC | EXEC_P | /* object flags */ HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), +#ifndef COFF_WITH_PE (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ +#else + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ + | SEC_LINK_ONCE | SEC_LINK_DUPLICATES), +#endif + #ifdef TARGET_UNDERSCORE TARGET_UNDERSCORE, /* leading underscore */ #else @@ -492,14 +694,20 @@ armcoff_big_vec = "coff-arm-big", #endif bfd_target_coff_flavour, - true, /* data byte order is big */ - true, /* header byte order is big */ + 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 | D_PAGED), +#ifndef COFF_WITH_PE (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ +#else + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ + | SEC_LINK_ONCE | SEC_LINK_DUPLICATES), +#endif + #ifdef TARGET_UNDERSCORE TARGET_UNDERSCORE, /* leading underscore */ #else diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 7679a44712..c46c03ae52 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -310,6 +310,30 @@ CODE_FRAGMENT #endif #define STRING_SIZE_SIZE (4) + +static long sec_to_styp_flags PARAMS ((const char *, flagword)); +static flagword styp_to_sec_flags PARAMS ((bfd *, PTR, const char *)); +static boolean coff_bad_format_hook PARAMS ((bfd *, PTR)); +static boolean coff_new_section_hook PARAMS ((bfd *, asection *)); +static boolean coff_set_arch_mach_hook PARAMS ((bfd *, PTR)); +static boolean coff_write_relocs PARAMS ((bfd *, int)); +static boolean coff_set_flags + PARAMS ((bfd *, unsigned int *, unsigned short *)); +static boolean coff_set_arch_mach + PARAMS ((bfd *, enum bfd_architecture, unsigned long)); +static boolean coff_compute_section_file_positions PARAMS ((bfd *)); +static boolean coff_write_object_contents PARAMS ((bfd *)); +static boolean coff_set_section_contents + PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); +static PTR buy_and_read PARAMS ((bfd *, file_ptr, int, size_t)); +static boolean coff_slurp_line_table PARAMS ((bfd *, asection *)); +static boolean coff_slurp_symbol_table PARAMS ((bfd *)); +static boolean coff_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **)); +static long coff_canonicalize_reloc + PARAMS ((bfd *, asection *, arelent **, asymbol **)); +#ifndef coff_mkobject_hook +static PTR coff_mkobject_hook PARAMS ((bfd *, PTR, PTR)); +#endif /* void warning(); */ @@ -727,6 +751,7 @@ dependent COFF routines: . unsigned int _bfd_linesz; . boolean _bfd_coff_long_filenames; . boolean _bfd_coff_long_section_names; +. unsigned int _bfd_coff_default_section_alignment_power; . void (*_bfd_coff_swap_filehdr_in) PARAMS (( . bfd *abfd, . PTR ext, @@ -880,6 +905,8 @@ dependent COFF routines: .#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames) .#define bfd_coff_long_section_names(abfd) \ . (coff_backend_info (abfd)->_bfd_coff_long_section_names) +.#define bfd_coff_default_section_alignment_power(abfd) \ +. (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power) .#define bfd_coff_swap_filehdr_in(abfd, i,o) \ . ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) . @@ -1033,6 +1060,8 @@ coff_new_section_hook (abfd, section) /* Set the alignment of a BFD section. */ +static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR)); + static void coff_set_alignment_hook (abfd, section, scnhdr) bfd * abfd; @@ -1064,6 +1093,8 @@ coff_set_alignment_hook (abfd, section, scnhdr) section->alignment_power = y;\ } +static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR)); + static void coff_set_alignment_hook (abfd, section, scnhdr) bfd * abfd; @@ -1151,6 +1182,8 @@ coff_set_alignment_hook (abfd, section, scnhdr) When we see one, we correct the reloc and line number counts in the real header, and remove the section we just created. */ +static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR)); + static void coff_set_alignment_hook (abfd, section, scnhdr) bfd *abfd; @@ -1192,6 +1225,9 @@ coff_set_alignment_hook (abfd, section, scnhdr) #endif /* ! I960 */ #ifndef coff_mkobject + +static boolean coff_mkobject PARAMS ((bfd *)); + static boolean coff_mkobject (abfd) bfd * abfd; @@ -1270,6 +1306,12 @@ coff_mkobject_hook (abfd, filehdr, aouthdr) } #endif +#ifdef ARM + /* Set the flags field from the COFF header read in */ + if (! coff_arm_bfd_set_private_flags (abfd, internal_f->f_flags)) + coff->flags = 0; +#endif + return (PTR) coff; } #endif @@ -1318,7 +1360,16 @@ coff_set_arch_mach_hook (abfd, filehdr) #ifdef ARMMAGIC case ARMMAGIC: arch = bfd_arch_arm; - machine =0; + switch (internal_f->f_flags & F_ARM_ARCHITECTURE_MASK) + { + case F_ARM_2: machine = bfd_mach_arm_2; break; + case F_ARM_2a: machine = bfd_mach_arm_2a; break; + case F_ARM_3: machine = bfd_mach_arm_3; break; + default: + case F_ARM_3M: machine = bfd_mach_arm_3M; break; + case F_ARM_4: machine = bfd_mach_arm_4; break; + case F_ARM_4T: machine = bfd_mach_arm_4T; break; + } break; #endif #ifdef MC68MAGIC @@ -1550,6 +1601,9 @@ coff_set_arch_mach_hook (abfd, filehdr) #ifdef SYMNAME_IN_DEBUG +static boolean symname_in_debug_hook + PARAMS ((bfd *, struct internal_syment *)); + static boolean symname_in_debug_hook (abfd, sym) bfd * abfd; @@ -1840,7 +1894,7 @@ coff_write_relocs (abfd, first_undef) static boolean coff_set_flags (abfd, magicp, flagsp) bfd * abfd; - unsigned *magicp; + unsigned int *magicp; unsigned short *flagsp; { switch (bfd_get_arch (abfd)) @@ -1915,7 +1969,18 @@ coff_set_flags (abfd, magicp, flagsp) /* end-sanitize-tic80 */ #ifdef ARMMAGIC case bfd_arch_arm: - *magicp = ARMMAGIC; + * magicp = ARMMAGIC; + if (coff_data (abfd)->flags & F_APCS_26) + * flagsp = F_APCS26; + switch (bfd_get_mach (abfd)) + { + case bfd_mach_arm_2: * flagsp |= F_ARM_2; break; + case bfd_mach_arm_2a: * flagsp |= F_ARM_2a; break; + case bfd_mach_arm_3: * flagsp |= F_ARM_3; break; + case bfd_mach_arm_3M: * flagsp |= F_ARM_3M; break; + case bfd_mach_arm_4: * flagsp |= F_ARM_4; break; + case bfd_mach_arm_4T: * flagsp |= F_ARM_4T; break; + } return true; #endif #ifdef PPCMAGIC @@ -2249,6 +2314,14 @@ coff_compute_section_file_positions (abfd) } #endif +#ifdef COFF_IMAGE_WITH_PE + /* For PE we need to make sure we pad out to the aligned + _raw_size, in case the caller only writes out data to the + unaligned _raw_size. */ + if (pei_section_data (abfd, current)->virt_size < current->_raw_size) + align_adjust = true; +#endif + #ifdef _LIB /* Force .lib sections to start at zero. The vma is then incremented in coff_set_section_contents. This is right for @@ -2800,10 +2873,12 @@ coff_write_object_contents (abfd) #define __A_MAGIC_SET__ internal_a.magic = ZMAGIC; #endif + #if defined(PPC_PE) #define __A_MAGIC_SET__ internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; #endif + #if defined(I386) #define __A_MAGIC_SET__ #if defined(LYNXOS) @@ -3544,6 +3619,8 @@ coff_slurp_symbol_table (abfd) #ifdef OTHER_GLOBAL_CLASS +static boolean coff_sym_is_global PARAMS ((bfd *, struct internal_syment *)); + static boolean coff_sym_is_global (abfd, syment) bfd *abfd; @@ -3808,6 +3885,10 @@ coff_sym_filepos (abfd) #ifndef coff_reloc16_estimate #define coff_reloc16_estimate dummy_reloc16_estimate +static int dummy_reloc16_estimate + PARAMS ((bfd *, asection *, arelent *, unsigned int, + struct bfd_link_info *)); + static int dummy_reloc16_estimate (abfd, input_section, reloc, shrink, link_info) bfd *abfd; @@ -3822,8 +3903,15 @@ dummy_reloc16_estimate (abfd, input_section, reloc, shrink, link_info) #endif #ifndef coff_reloc16_extra_cases + #define coff_reloc16_extra_cases dummy_reloc16_extra_cases + /* This works even if abort is not declared in any header file. */ + +static void dummy_reloc16_extra_cases + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, + bfd_byte *, unsigned int *, unsigned int *)); + static void dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr) @@ -3861,6 +3949,7 @@ dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, #endif #define coff_bfd_final_link _bfd_generic_final_link #endif /* ! defined (coff_relocate_section) */ + #define coff_bfd_link_split_section _bfd_generic_link_split_section #ifndef coff_start_final_link @@ -3893,6 +3982,7 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table = #else false, #endif + COFF_DEFAULT_SECTION_ALIGNMENT_POWER, 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, @@ -3903,12 +3993,20 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table = coff_adjust_symndx, coff_link_add_one_symbol }; -#define coff_close_and_cleanup _bfd_generic_close_and_cleanup -#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define coff_get_section_contents _bfd_generic_get_section_contents +#ifndef coff_close_and_cleanup +#define coff_close_and_cleanup _bfd_generic_close_and_cleanup +#endif + +#ifndef coff_bfd_free_cached_info +#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#endif + +#ifndef coff_get_section_contents +#define coff_get_section_contents _bfd_generic_get_section_contents +#endif #ifndef coff_bfd_copy_private_symbol_data -#define coff_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data +#define coff_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data #endif #ifndef coff_bfd_copy_private_section_data @@ -3916,36 +4014,44 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table = #endif #ifndef coff_bfd_copy_private_bfd_data -#define coff_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data +#define coff_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data #endif -#define coff_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data -#define coff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags +#ifndef coff_bfd_merge_private_bfd_data +#define coff_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data +#endif + +#ifndef coff_bfd_set_private_flags +#define coff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags +#endif #ifndef coff_bfd_print_private_bfd_data -#define coff_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data +#define coff_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data #endif #ifndef coff_bfd_is_local_label_name -#define coff_bfd_is_local_label_name _bfd_coff_is_local_label_name +#define coff_bfd_is_local_label_name _bfd_coff_is_local_label_name #endif + #ifndef coff_read_minisymbols -#define coff_read_minisymbols _bfd_generic_read_minisymbols +#define coff_read_minisymbols _bfd_generic_read_minisymbols #endif + #ifndef coff_minisymbol_to_symbol -#define coff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol +#define coff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #endif /* The reloc lookup routine must be supplied by each individual COFF backend. */ #ifndef coff_bfd_reloc_type_lookup -#define coff_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup +#define coff_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup #endif #ifndef coff_bfd_get_relocated_section_contents #define coff_bfd_get_relocated_section_contents \ bfd_generic_get_relocated_section_contents #endif + #ifndef coff_bfd_relax_section -#define coff_bfd_relax_section bfd_generic_relax_section +#define coff_bfd_relax_section bfd_generic_relax_section #endif diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c new file mode 100644 index 0000000000..db8282e31f --- /dev/null +++ b/bfd/cpu-arm.c @@ -0,0 +1,108 @@ +/* BFD support for the ARM processor + Copyright 1994 Free Software Foundation, Inc. + Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) + +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 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. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" + +/* This routine is provided two arch_infos and works out which ARM + machine which would be compatible with both and returns a pointer + to its info structure */ + +static const bfd_arch_info_type * +compatible (a,b) + const bfd_arch_info_type * a; + const bfd_arch_info_type * b; +{ + /* For now keep things real simple - insist on matching architecture types */ + + return (a->arch != b->arch || a->mach != b->mach ) ? NULL : a ; +} + +static struct +{ + enum bfd_architecture arch; + char * name; +} +processors[] = +{ + { bfd_mach_arm_2, "arm2" }, + { bfd_mach_arm_2a, "arm250" }, + { bfd_mach_arm_2a, "arm3" }, + { bfd_mach_arm_3, "arm6" }, + { bfd_mach_arm_3, "arm60" }, + { bfd_mach_arm_3, "arm600" }, + { bfd_mach_arm_3, "arm610" }, + { bfd_mach_arm_3, "arm7" }, + { bfd_mach_arm_3, "arm710" }, + { bfd_mach_arm_3, "arm7500" }, + { bfd_mach_arm_3, "arm7d" }, + { bfd_mach_arm_3, "arm7di" }, + { bfd_mach_arm_3M, "arm7dm" }, + { bfd_mach_arm_3M, "arm7dmi" }, + { bfd_mach_arm_4, "arm8" }, + { bfd_mach_arm_4, "arm810" }, + { bfd_mach_arm_4, "sa1" }, + { bfd_mach_arm_4T, "arm7tdmi" } +}; + +static boolean +scan (info, string) + const struct bfd_arch_info * info; + const char * string; +{ + int i; + + /* First test for an exact match */ + if (strcasecmp (string, info->printable_name) == 0) + return true; + + /* Next check for a processor name instead of an Architecture name */ + for (i = sizeof (processors) / sizeof (processors[0]); i--;) + { + if (strcasecmp (string, processors[ i ].name) == 0) + break; + } + + if (i != -1 && info->arch == processors[ i ].arch) + return true; + + /* Finally check for the default architecture */ + if (strcasecmp (string, "arm") == 0) + return info->the_default; + + return false; +} + + +#define N(number, print, default, next) \ +{ 32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, scan, next } + +static const bfd_arch_info_type arch_info_struct[] = +{ + N( bfd_mach_arm_2, "ARMv2", false, & arch_info_struct[1] ), + N( bfd_mach_arm_2a, "ARMv2a", false, & arch_info_struct[2] ), + N( bfd_mach_arm_3, "ARMv3", false, & arch_info_struct[3] ), + N( bfd_mach_arm_4, "ARMv4", false, & arch_info_struct[4] ), + N( bfd_mach_arm_4T, "ARMv4T", false, NULL ) +}; + +const bfd_arch_info_type bfd_arm_arch = + N( bfd_mach_arm_3M, "ARMv3M", true, & arch_info_struct[0] ); diff --git a/gas/ChangeLog b/gas/ChangeLog index 83efb5f885..7ab2f13a4a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,15 @@ +Wed May 14 09:54:53 1997 Nick Clifton + + * config/tc-arm.c (global variables): Added 'uses_apcs_26' flag to + hold APCS selection. (md_begin): Added code to generate flags to + be set into the COFF header and the calls to the BFD functions to + do this. (md_parse_option, md_show_usage): Added new command line + options -mapcs-32, -mapcs-26, -marmv2, -marmv2a, -marmv3, + -marmv3m, -marmv4, -marmv4t. + + * tc-arm.h (LOCAL_LABEL): Removed the definition of this macro + as it is never used. + Tue May 13 22:26:14 1997 Jeffrey A Law (law@cygnus.com) * config/tc-mn10200.c (md_convert_frag): Prefix temporary diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 644d89b2ce..667fbc7a9f 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -47,6 +47,7 @@ #define ARM_250 ARM_3 #define ARM_6 0x00000008 #define ARM_7 ARM_6 /* same core instruction set */ +#define ARM_CPU_MASK 0x0000000f /* The following bitmasks control CPU extensions (ARM7 onwards): */ #define ARM_LONGMUL 0x00000010 /* allow long multiplies */ @@ -77,7 +78,10 @@ #define FPU_DEFAULT FPU_ALL #endif -unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT; +static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT; + +/* Flags stored in private area of BFD COFF structure */ +static boolean uses_apcs_26 = false; /* This array holds the chars that always start a comment. If the pre-processor is disabled, these aren't very useful */ @@ -958,11 +962,9 @@ symbol_make_empty () /* symbol must be born in some fixed state. This seems as good as any. */ memset (symbolP, 0, sizeof (symbolS)); -#ifdef BFD_ASSEMBLER symbolP->bsym = bfd_make_empty_symbol (stdoutput); assert (symbolP->bsym != 0); symbolP->bsym->udata.p = (PTR) symbolP; -#endif return symbolP; } @@ -4580,6 +4582,43 @@ md_begin () insert_reg (i); set_constant_flonums (); + +#ifdef OBJ_COFF + /* Set the flags in the private structure */ + coff_arm_bfd_set_private_flags (stdoutput, uses_apcs_26 ? F_APCS26 : 0); +#endif + + { + unsigned mach; + + /* Record the CPU type as well */ + switch (cpu_variant & ARM_CPU_MASK) + { + case ARM_2: + mach = bfd_mach_arm_2; + break; + + case ARM_3: /* also ARM_250 */ + mach = bfd_mach_arm_2a; + break; + + default: + case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */ + case ARM_7: /* also ARM_6 */ + mach = bfd_mach_arm_3; + break; + } + + /* Catch special cases */ + if (cpu_variant & ARM_THUMB) + mach = bfd_mach_arm_4T; + else if (cpu_variant & ARM_LONGMUL) + mach = bfd_mach_arm_3M; + else if (cpu_variant & ARM_ARCH4) + mach = bfd_mach_arm_4; + + bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach); + } } /* Turn an integer of n bytes (in val) into a stream of bytes appropriate @@ -5635,10 +5674,14 @@ md_assemble (str) * Run-time endian selection: * -EB big endian cpu * -EL little endian cpu + * ARM Procedure Calling Standard: + * -mapcs-32 32 bit APCS + * -mapcs-26 26 bit APCS */ CONST char *md_shortopts = "m:"; -struct option md_longopts[] = { +struct option md_longopts[] = +{ #ifdef ARM_BI_ENDIAN #define OPTION_EB (OPTION_MD_BASE + 0) {"EB", no_argument, NULL, OPTION_EB}, @@ -5704,7 +5747,17 @@ md_parse_option (c, arg) cpu_variant = ARM_ALL | FPU_ALL; return 1; } - + else if (! strcmp( str, "apcs-32" )) + { + uses_apcs_26 = false; + return 1; + } + else if (! strcmp( str, "apcs-26" )) + { + uses_apcs_26 = true; + return 1; + } + /* Strip off optional "arm" */ if (! strncmp (str, "arm", 3)) str += 3; @@ -5768,9 +5821,50 @@ md_parse_option (c, arg) } break; + case 'v': + /* Select variant based on architecture rather than processor */ + switch (*++str) + { + case '2': + switch (*++str) + { + case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break; + case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break; + default: as_bad( "Invalid architecture variant -m%s", arg ); break; + } + break; + + case '3': + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7; + + switch (*++str) + { + case 'm': cpu_variant |= ARM_LONGMUL; break; + case 0: break; + default: as_bad( "Invalid architecture variant -m%s", arg ); break; + } + break; + + case '4': + cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7; + + switch (*++str) + { + case 't': cpu_variant |= ARM_THUMB; break; + case 0: break; + default: as_bad( "Invalid architecture variant -m%s", arg ); break; + } + break; + + default: + as_bad( "Invalid architecture variant -m%s", arg ); + break; + } + break; + default: bad: - as_bad ("Invalid architecture -m%s", arg); + as_bad ("Invalid processor variant -m%s", arg); return 0; } } @@ -5788,12 +5882,14 @@ md_show_usage (fp) FILE *fp; { fprintf (fp, -"-m[arm]1, -m[arm]2, -m[arm]250,\n-m[arm]3, -m[arm]6, -m[arm]7[t][[d]m]\n\ --mthumb\t\t\tselect processor architecture\n\ +"-m[arm][1|2|250|3|6|7[t][d][m][i]] select processor variant\n\ +-m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\ +-mthumb\t\t\tonly allow Thumb instructions\n\ -mall\t\t\tallow any instruction\n\ -mfpa10, -mfpa11\tselect floating point architecture\n\ -mfpe-old\t\tdon't allow floating-point multiple instructions\n\ --mno-fpu\t\tdon't allow any floating-point instructions.\n"); +-mno-fpu\t\tdon't allow any floating-point instructions.\n\ +-mapcs-32, -mapcs-26\tspecify which ARM Procedure Calling Standard is in use\n"); #ifdef ARM_BI_ENDIAN fprintf (fp, "-EB\t\t\tassemble code for a big endian cpu\n\ diff --git a/include/ChangeLog b/include/ChangeLog index 22f2fe7e55..7a2403c76c 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,17 @@ +Tue May 13 10:21:14 1997 Nick Clifton + + * coff/arm.h (constants): Added new flag bits F_APCS_26 and + F_APCS_SET for the f_flags field of the filehdr structure. Added new + flags: F_APCS26, F_ARM_2, F_ARM_3, F_ARM_7, F_ARM_7T to store + information in the flags field of the internal_f structure used by BFD + routines. + +Tue Apr 22 10:24:34 1997 Fred Fish + + * floatformat.h (floatformat_byteorders): Add comments for previous + formats and add floatformat_littlebyte_bigword, primarily for ARM. + Add declaration for floatformat_ieee_double_littlebyte_bigword. + Fri Apr 18 13:04:49 1997 Andrew Cagney * remote-sim.h (sim_stop): New interface - asynchronous