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