+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.
/* 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.
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
-#include "obstack.h"
#include "coff/arm.h"
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
"ARM26D",
true,
0x00ffffff,
- 0x00ffffff,
+ 0x0,
false),
{-1},
HOWTO( 9,
{
*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;
}
/* 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"
"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
"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
#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(); */
. 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,
.#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))
.
/* 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;
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;
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;
#endif /* ! I960 */
#ifndef coff_mkobject
+
+static boolean coff_mkobject PARAMS ((bfd *));
+
static boolean
coff_mkobject (abfd)
bfd * abfd;
}
#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
#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
#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;
static boolean
coff_set_flags (abfd, magicp, flagsp)
bfd * abfd;
- unsigned *magicp;
+ unsigned int *magicp;
unsigned short *flagsp;
{
switch (bfd_get_arch (abfd))
/* 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
}
#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
#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)
#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;
#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;
#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)
#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
#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,
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
#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
--- /dev/null
+/* 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] );
+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
#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 */
/* 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;
}
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
* 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},
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;
}
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;
}
}
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\
+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