Home | History | Annotate | Line # | Download | only in bfd
cpu-aarch64.c revision 1.9.2.1
      1      1.1  christos /* BFD support for AArch64.
      2  1.9.2.1  perseant    Copyright (C) 2009-2022 Free Software Foundation, Inc.
      3      1.1  christos    Contributed by ARM Ltd.
      4      1.1  christos 
      5      1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program; see the file COPYING3. If not,
     19      1.1  christos    see <http://www.gnu.org/licenses/>.  */
     20      1.1  christos 
     21      1.1  christos #include "sysdep.h"
     22      1.1  christos #include "bfd.h"
     23      1.1  christos #include "libbfd.h"
     24      1.1  christos #include "libiberty.h"
     25      1.9  christos #include "cpu-aarch64.h"
     26      1.1  christos 
     27      1.1  christos /* This routine is provided two arch_infos and works out which Aarch64
     28      1.1  christos    machine which would be compatible with both and returns a pointer
     29      1.1  christos    to its info structure.  */
     30      1.1  christos 
     31      1.1  christos static const bfd_arch_info_type *
     32      1.1  christos compatible (const bfd_arch_info_type * a, const bfd_arch_info_type * b)
     33      1.1  christos {
     34      1.1  christos   /* If a & b are for different architecture we can do nothing.  */
     35      1.1  christos   if (a->arch != b->arch)
     36      1.1  christos     return NULL;
     37      1.1  christos 
     38      1.1  christos   /* If a & b are for the same machine then all is well.  */
     39      1.1  christos   if (a->mach == b->mach)
     40      1.1  christos     return a;
     41      1.1  christos 
     42  1.9.2.1  perseant   /* Don't allow mixing data models.  */
     43  1.9.2.1  perseant   if ((a->mach ^ b->mach) & (bfd_mach_aarch64_ilp32 | bfd_mach_aarch64_llp64))
     44      1.1  christos     return NULL;
     45      1.1  christos 
     46      1.1  christos   /* Otherwise if either a or b is the 'default' machine
     47      1.1  christos      then it can be polymorphed into the other.  */
     48      1.1  christos   if (a->the_default)
     49      1.1  christos     return b;
     50      1.1  christos 
     51      1.1  christos   if (b->the_default)
     52      1.1  christos     return a;
     53      1.1  christos 
     54      1.1  christos   /* So far all newer cores are
     55      1.1  christos      supersets of previous cores.  */
     56      1.1  christos   if (a->mach < b->mach)
     57      1.1  christos     return b;
     58      1.1  christos   else if (a->mach > b->mach)
     59      1.1  christos     return a;
     60      1.1  christos 
     61      1.1  christos   /* Never reached!  */
     62      1.1  christos   return NULL;
     63      1.1  christos }
     64      1.1  christos 
     65      1.1  christos static struct
     66      1.1  christos {
     67      1.1  christos   unsigned int mach;
     68      1.1  christos   char *name;
     69      1.1  christos }
     70      1.1  christos processors[] =
     71      1.1  christos {
     72      1.9  christos   { bfd_mach_aarch64,	  "cortex-a34"	    },
     73      1.9  christos   { bfd_mach_aarch64,	  "cortex-a65"	    },
     74      1.9  christos   { bfd_mach_aarch64,	  "cortex-a65ae"    },
     75      1.9  christos   { bfd_mach_aarch64,	  "cortex-a76ae"    },
     76      1.9  christos   { bfd_mach_aarch64,	  "cortex-a77"	    }
     77      1.1  christos };
     78      1.1  christos 
     79  1.9.2.1  perseant static bool
     80      1.1  christos scan (const struct bfd_arch_info *info, const char *string)
     81      1.1  christos {
     82      1.1  christos   int i;
     83      1.1  christos 
     84      1.1  christos   /* First test for an exact match.  */
     85      1.1  christos   if (strcasecmp (string, info->printable_name) == 0)
     86  1.9.2.1  perseant     return true;
     87  1.9.2.1  perseant 
     88  1.9.2.1  perseant   /* If there is a prefix of "aarch64:" then skip it.  */
     89  1.9.2.1  perseant   const char * colon;
     90  1.9.2.1  perseant   if ((colon = strchr (string, ':')) != NULL)
     91  1.9.2.1  perseant     {
     92  1.9.2.1  perseant       if (strncasecmp (string, "aarch64", colon - string) != 0)
     93  1.9.2.1  perseant 	return false;
     94  1.9.2.1  perseant       string = colon + 1;
     95  1.9.2.1  perseant     }
     96      1.1  christos 
     97      1.1  christos   /* Next check for a processor name instead of an Architecture name.  */
     98      1.1  christos   for (i = sizeof (processors) / sizeof (processors[0]); i--;)
     99      1.1  christos     {
    100      1.1  christos       if (strcasecmp (string, processors[i].name) == 0)
    101      1.1  christos 	break;
    102      1.1  christos     }
    103      1.1  christos 
    104      1.1  christos   if (i != -1 && info->mach == processors[i].mach)
    105  1.9.2.1  perseant     return true;
    106      1.1  christos 
    107      1.1  christos   /* Finally check for the default architecture.  */
    108      1.1  christos   if (strcasecmp (string, "aarch64") == 0)
    109      1.1  christos     return info->the_default;
    110      1.1  christos 
    111  1.9.2.1  perseant   return false;
    112      1.1  christos }
    113      1.1  christos 
    114  1.9.2.1  perseant /* Figure out if llp64 is default */
    115  1.9.2.1  perseant #if DEFAULT_VECTOR == aarch64_pe_le_vec
    116  1.9.2.1  perseant #define LLP64_DEFAULT true
    117  1.9.2.1  perseant #define AARCH64_DEFAULT false
    118  1.9.2.1  perseant #else
    119  1.9.2.1  perseant #define LLP64_DEFAULT false
    120  1.9.2.1  perseant #define AARCH64_DEFAULT true
    121  1.9.2.1  perseant #endif
    122  1.9.2.1  perseant 
    123  1.9.2.1  perseant #define N(NUMBER, PRINT, WORDSIZE, ADDRSIZE, DEFAULT, NEXT)		\
    124  1.9.2.1  perseant   { WORDSIZE, ADDRSIZE, 8, bfd_arch_aarch64, NUMBER,		\
    125  1.9.2.1  perseant      "aarch64", PRINT, 4, DEFAULT, compatible, scan,		\
    126  1.9.2.1  perseant        bfd_arch_default_fill, NEXT, 0 }
    127      1.9  christos 
    128  1.9.2.1  perseant  static const bfd_arch_info_type bfd_aarch64_arch_v8_r =
    129  1.9.2.1  perseant   N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, 64, false, NULL);
    130      1.1  christos 
    131      1.1  christos static const bfd_arch_info_type bfd_aarch64_arch_ilp32 =
    132  1.9.2.1  perseant   N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, 32, false,
    133      1.9  christos      &bfd_aarch64_arch_v8_r);
    134      1.1  christos 
    135  1.9.2.1  perseant static const bfd_arch_info_type bfd_aarch64_arch_llp64 =
    136  1.9.2.1  perseant   N (bfd_mach_aarch64_llp64, "aarch64:llp64", 32, 64, LLP64_DEFAULT,
    137  1.9.2.1  perseant      &bfd_aarch64_arch_ilp32);
    138  1.9.2.1  perseant 
    139  1.9.2.1  perseant  const bfd_arch_info_type bfd_aarch64_arch =
    140  1.9.2.1  perseant   N (0, "aarch64", 64, 64, AARCH64_DEFAULT, &bfd_aarch64_arch_llp64);
    141      1.1  christos 
    142  1.9.2.1  perseant bool
    143      1.1  christos bfd_is_aarch64_special_symbol_name (const char *name, int type)
    144      1.1  christos {
    145      1.1  christos   if (!name || name[0] != '$')
    146  1.9.2.1  perseant     return false;
    147      1.1  christos   if (name[1] == 'x' || name[1] == 'd')
    148      1.1  christos     type &= BFD_AARCH64_SPECIAL_SYM_TYPE_MAP;
    149      1.1  christos   else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
    150      1.1  christos     type &= BFD_AARCH64_SPECIAL_SYM_TYPE_TAG;
    151      1.1  christos   else
    152  1.9.2.1  perseant     return false;
    153      1.1  christos 
    154      1.1  christos   return (type != 0 && (name[2] == 0 || name[2] == '.'));
    155      1.1  christos }
    156