Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/cpu-riscv.c
Line
Count
Source (jump to first uncovered line)
1
/* BFD backend for RISC-V
2
   Copyright (C) 2011-2025 Free Software Foundation, Inc.
3
4
   Contributed by Andrew Waterman (andrew@sifive.com).
5
   Based on MIPS target.
6
7
   This file is part of BFD, the Binary File Descriptor library.
8
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
19
   You should have received a copy of the GNU General Public License
20
   along with this program; see the file COPYING3. If not,
21
   see <http://www.gnu.org/licenses/>.  */
22
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "cpu-riscv.h"
27
28
static const bfd_arch_info_type *
29
riscv_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
30
0
{
31
0
  if (a->arch != b->arch)
32
0
    return NULL;
33
34
  /* Machine compatibility is checked in
35
     _bfd_riscv_elf_merge_private_bfd_data.  */
36
37
0
  return a;
38
0
}
39
40
/* Return TRUE if STRING matches the architecture described by INFO.  */
41
42
static bool
43
riscv_scan (const struct bfd_arch_info *info, const char *string)
44
0
{
45
0
  if (bfd_default_scan (info, string))
46
0
    return true;
47
48
  /* The incoming STRING might take the form of riscv:rvXXzzz, where XX is
49
     32 or 64, and zzz are one or more extension characters.  As we
50
     currently only have 3 architectures defined, 'riscv', 'riscv:rv32',
51
     and 'riscv:rv64', we would like to ignore the zzz for the purpose of
52
     matching here.
53
54
     However, we don't want the default 'riscv' to match over a more
55
     specific 'riscv:rv32' or 'riscv:rv64', so in the case of the default
56
     architecture (with the shorter 'riscv' name) we don't allow any
57
     special matching, but for the 'riscv:rvXX' cases, we allow a match
58
     with any additional trailing characters being ignored.  */
59
0
  if (!info->the_default
60
0
      && strncasecmp (string, info->printable_name,
61
0
                      strlen (info->printable_name)) == 0)
62
0
    return true;
63
64
0
  return false;
65
0
}
66
67
#define N(BITS, NUMBER, PRINT, DEFAULT, NEXT)     \
68
  {               \
69
    BITS,      /* Bits in a word.  */       \
70
    BITS,      /* Bits in an address.  */     \
71
    8,         /* Bits in a byte.  */       \
72
    bfd_arch_riscv,           \
73
    NUMBER,             \
74
    "riscv",              \
75
    PRINT,              \
76
    3,                \
77
    DEFAULT,              \
78
    riscv_compatible,           \
79
    riscv_scan,             \
80
    bfd_arch_default_fill,          \
81
    NEXT,             \
82
    0 /* Maximum offset of a reloc from the start of an insn.  */\
83
  }
84
85
/* This enum must be kept in the same order as arch_info_struct.  */
86
enum
87
{
88
  I_riscv64,
89
  I_riscv32
90
};
91
92
#define NN(index) (&arch_info_struct[(index) + 1])
93
94
/* This array must be kept in the same order as the anonymous enum above,
95
   and each entry except the last should end with NN (my enum value).  */
96
static const bfd_arch_info_type arch_info_struct[] =
97
{
98
  N (64, bfd_mach_riscv64, "riscv:rv64", false, NN (I_riscv64)),
99
  N (32, bfd_mach_riscv32, "riscv:rv32", false, NULL)
100
};
101
102
/* The default architecture is riscv:rv64.  */
103
const bfd_arch_info_type bfd_riscv_arch =
104
  N (64, 0, "riscv", true, &arch_info_struct[0]);
105
106
/* List for all supported ISA spec versions.  */
107
const struct riscv_spec riscv_isa_specs[] =
108
{
109
  {"2.2",      ISA_SPEC_CLASS_2P2},
110
  {"20190608", ISA_SPEC_CLASS_20190608},
111
  {"20191213", ISA_SPEC_CLASS_20191213},
112
};
113
114
/* List for all supported privileged spec versions.  */
115
const struct riscv_spec riscv_priv_specs[] =
116
{
117
  {"1.9.1", PRIV_SPEC_CLASS_1P9P1},
118
  {"1.10",  PRIV_SPEC_CLASS_1P10},
119
  {"1.11",  PRIV_SPEC_CLASS_1P11},
120
  {"1.12",  PRIV_SPEC_CLASS_1P12},
121
  {"1.13",  PRIV_SPEC_CLASS_1P13},
122
};
123
124
/* Get the corresponding CSR version class by giving privilege
125
   version numbers.  It is usually used to convert the priv
126
   attribute numbers into the corresponding class.  */
127
128
void
129
riscv_get_priv_spec_class_from_numbers (unsigned int major,
130
          unsigned int minor,
131
          unsigned int revision,
132
          enum riscv_spec_class *class)
133
0
{
134
0
  enum riscv_spec_class class_t = *class;
135
0
  char buf[36];
136
137
0
  if (revision != 0)
138
0
    snprintf (buf, sizeof (buf), "%u.%u.%u", major, minor, revision);
139
0
  else
140
0
    snprintf (buf, sizeof (buf), "%u.%u", major, minor);
141
142
0
  RISCV_GET_PRIV_SPEC_CLASS (buf, class_t);
143
0
  *class = class_t;
144
0
}
145
146
/* Define mapping symbols for riscv.  */
147
148
bool
149
riscv_elf_is_mapping_symbols (const char *name)
150
17.6k
{
151
17.6k
  return (!strcmp (name, "$d")
152
17.6k
    || !strcmp (name, "$x")
153
17.6k
    || !strncmp (name, "$xrv", 4));
154
17.6k
}