[PATCH] backends: add abi_cfi and register_info callbacks for RISC-V

Andreas Schwab schwab@suse.de
Wed Jun 13 10:28:00 GMT 2018


From
<https://github.com/riscv/riscv-isa-manual/raw/master/release/riscv-spec-v2.2.pdf>
and GCC source.

Signed-off-by: Andreas Schwab <schwab@suse.de>
---
 backends/Makefile.am  |   2 +-
 backends/riscv_cfi.c  |  75 ++++++++++++++++++
 backends/riscv_init.c |   4 +
 backends/riscv_regs.c | 177 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 257 insertions(+), 1 deletion(-)
 create mode 100644 backends/riscv_cfi.c
 create mode 100644 backends/riscv_regs.c

diff --git a/backends/Makefile.am b/backends/Makefile.am
index 80aa00e752..0c14ec86b5 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -131,7 +131,7 @@ cpu_bpf = ../libcpu/libcpu_bpf.a
 libebl_bpf_pic_a_SOURCES = $(bpf_SRCS)
 am_libebl_bpf_pic_a_OBJECTS = $(bpf_SRCS:.c=.os)
 
-riscv_SRCS = riscv_init.c riscv_symbol.c
+riscv_SRCS = riscv_init.c riscv_symbol.c riscv_cfi.c riscv_regs.c
 libebl_riscv_pic_a_SOURCES = $(riscv_SRCS)
 am_libebl_riscv_pic_a_OBJECTS = $(riscv_SRCS:.c=.os)
 
diff --git a/backends/riscv_cfi.c b/backends/riscv_cfi.c
new file mode 100644
index 0000000000..1a84a38237
--- /dev/null
+++ b/backends/riscv_cfi.c
@@ -0,0 +1,75 @@
+/* RISC-V ABI-specified defaults for DWARF CFI.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+
+int
+riscv_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* The initial Canonical Frame Address is the value of the
+         Stack Pointer (r2) as setup in the previous frame. */
+      DW_CFA_def_cfa, ULEB128_7 (2), ULEB128_7 (0),
+
+      /* The Stack Pointer (r2) is restored from CFA address by default.  */
+      DW_CFA_val_offset, ULEB128_7 (2), ULEB128_7 (0),
+
+#define SV(n) DW_CFA_same_value, ULEB128_7 (n)
+      /* The return address register contains the return address setup by
+	 caller.  */
+      SV (1),
+
+      /* Callee-saved registers s0-s11, fs0-fs11.  */
+      SV(8), SV (9), SV (18), SV (19), SV (20), SV (21),
+      SV (22), SV (23), SV (24), SV (25), SV (26), SV (27),
+
+      SV (40), SV (41),  SV (50),  SV (51), SV (52),  SV (53),
+      SV (54), SV (55),  SV (56),  SV (57), SV (58),  SV (59),
+#undef SV
+
+      /* XXX Note: registers intentionally unused by the program,
+	 for example as a consequence of the procedure call standard
+	 should be initialized as if by DW_CFA_same_value.  */
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = -4;
+
+  abi_info->return_address_register = 1; /* ra.  */
+
+  return 0;
+}
diff --git a/backends/riscv_init.c b/backends/riscv_init.c
index 80be86d3c5..5588a6b7f0 100644
--- a/backends/riscv_init.c
+++ b/backends/riscv_init.c
@@ -51,6 +51,10 @@ riscv_init (Elf *elf __attribute__ ((unused)),
   eh->name = "RISC-V";
   riscv_init_reloc (eh);
   HOOK (eh, reloc_simple_type);
+  HOOK (eh, register_info);
+  HOOK (eh, abi_cfi);
+  /* gcc/config/ #define DWARF_FRAME_REGISTERS.  */
+  eh->frame_nregs = 66;
   HOOK (eh, check_special_symbol);
   HOOK (eh, machine_flag_check);
 
diff --git a/backends/riscv_regs.c b/backends/riscv_regs.c
new file mode 100644
index 0000000000..7b577ca0cb
--- /dev/null
+++ b/backends/riscv_regs.c
@@ -0,0 +1,177 @@
+/* Register names and numbers for RISC-V DWARF.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND riscv_
+#include "libebl_CPU.h"
+
+ssize_t
+riscv_register_info (Ebl *ebl, int regno, char *name, size_t namelen,
+		     const char **prefix, const char **setname,
+		     int *bits, int *type)
+{
+  if (name == NULL)
+    return 64;
+
+  *prefix = "";
+
+  if (regno < 32)
+    {
+      *setname = "integer";
+      *type = DW_ATE_signed;
+      *bits = ebl->class == ELFCLASS64 ? 64 : 32;
+    }
+  else
+    {
+      *setname = "FPU";
+      *type = DW_ATE_float;
+      *bits = 64;
+    }
+
+  switch (regno)
+    {
+    case 0:
+      return stpcpy (name, "zero") + 1 - name;
+
+    case 1:
+      *type = DW_ATE_address;
+      return stpcpy (name, "ra") + 1 - name;
+
+    case 2:
+      *type = DW_ATE_address;
+      return stpcpy (name, "sp") + 1 - name;
+
+    case 3:
+      *type = DW_ATE_address;
+      return stpcpy (name, "gp") + 1 - name;
+
+    case 4:
+      *type = DW_ATE_address;
+      return stpcpy (name, "tp") + 1 - name;
+
+    case 5 ... 7:
+      name[0] = 't';
+      name[1] = regno - 5 + '0';
+      namelen = 2;
+      break;
+
+    case 8 ... 9:
+      name[0] = 's';
+      name[1] = regno - 8 + '0';
+      namelen = 2;
+      break;
+
+    case 10 ... 17:
+      name[0] = 'a';
+      name[1] = regno - 10 + '0';
+      namelen = 2;
+      break;
+
+    case 18 ... 25:
+      name[0] = 's';
+      name[1] = regno - 18 + '2';
+      namelen = 2;
+      break;
+
+    case 26 ... 27:
+      name[0] = 's';
+      name[1] = '1';
+      name[1] = regno - 26 + '0';
+      namelen = 3;
+      break;
+
+    case 28 ... 31:
+      name[0] = 't';
+      name[1] = regno - 28 + '3';
+      namelen = 2;
+      break;
+
+    case 32 ... 39:
+      name[0] = 'f';
+      name[1] = 't';
+      name[2] = regno - 32 + '0';
+      namelen = 3;
+      break;
+
+    case 40 ... 41:
+      name[0] = 'f';
+      name[1] = 's';
+      name[2] = regno - 40 + '0';
+      namelen = 3;
+      break;
+
+    case 42 ... 49:
+      name[0] = 'f';
+      name[1] = 'a';
+      name[2] = regno - 42 + '0';
+      namelen = 3;
+      break;
+
+    case 50 ... 57:
+      name[0] = 'f';
+      name[1] = 's';
+      name[2] = regno - 50 + '2';
+      namelen = 3;
+      break;
+
+    case 58 ... 59:
+      name[0] = 'f';
+      name[1] = 's';
+      name[2] = '1';
+      name[3] = regno - 58 + '0';
+      namelen = 4;
+      break;
+
+    case 60 ... 61:
+      name[0] = 'f';
+      name[1] = 't';
+      name[2] = regno - 60 + '8';
+      namelen = 3;
+      break;
+
+    case 62 ... 63:
+      name[0] = 'f';
+      name[1] = 't';
+      name[2] = '1';
+      name[3] = regno - 62 + '0';
+      namelen = 4;
+      break;
+
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
-- 
2.17.1

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."



More information about the Elfutils-devel mailing list