Added support for storing ARM Procedure Calling Standard variant, and ARM
authorNick Clifton <nickc@redhat.com>
Wed, 14 May 1997 17:00:43 +0000 (17:00 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 14 May 1997 17:00:43 +0000 (17:00 +0000)
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
bfd/coff-arm.c
bfd/coffcode.h
bfd/cpu-arm.c [new file with mode: 0644]
gas/ChangeLog
gas/config/tc-arm.c
include/ChangeLog

index 28f8bdc..1fd14c4 100644 (file)
@@ -1,3 +1,37 @@
+Fri May  9 10:15:27 1997  Nick Clifton  <nickc@cygnus.com>
+
+       * 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  <ian@cygnus.com>
 
        * config.bfd (i[3456]86-*-gnu*): Don't include Mach support.
index a33bbb2..1f0e348 100644 (file)
@@ -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
index 7679a44..c46c03a 100644 (file)
@@ -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
 \f
 /* 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
+
+#ifndef coff_bfd_merge_private_bfd_data
+#define coff_bfd_merge_private_bfd_data     _bfd_generic_bfd_merge_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_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 (file)
index 0000000..db8282e
--- /dev/null
@@ -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] );
index 83efb5f..7ab2f13 100644 (file)
@@ -1,3 +1,15 @@
+Wed May 14 09:54:53 1997  Nick Clifton  <nickc@cygnus.com>
+
+       * 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
index 644d89b..667fbc7 100644 (file)
@@ -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 */
 #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\
index 22f2fe7..7a2403c 100644 (file)
@@ -1,3 +1,17 @@
+Tue May 13 10:21:14 1997  Nick Clifton  <nickc@cygnus.com>
+
+       * 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  <fnf@cygnus.com>
+
+       * 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  <cagney@b1.cygnus.com>
 
        * remote-sim.h (sim_stop): New interface - asynchronous