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.
This commit is contained in:
Nick Clifton 1997-05-14 17:00:43 +00:00
parent c23cc10a8f
commit 46686c7839
7 changed files with 611 additions and 33 deletions

View 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.

View 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

View 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
/* 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

108
bfd/cpu-arm.c Normal file
View File

@ -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] );

View 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

View 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 */
@ -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\

View 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