From de857968a715d1317b1686d2416b28ffe402dc09 Mon Sep 17 00:00:00 2001 From: Youling Tang Date: Fri, 7 Apr 2023 10:59:24 +0800 Subject: backends: Add abi_cfi and register_info callbacks for LoongArch LoongArch Reference Manual - Volume 1: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html LoongArch ELF ABI: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html Signed-off-by: Liwei Ge Signed-off-by: Youling Tang --- backends/ChangeLog | 9 ++- backends/Makefile.am | 3 +- backends/loongarch_cfi.c | 83 +++++++++++++++++++++++++++ backends/loongarch_init.c | 4 ++ backends/loongarch_regs.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 backends/loongarch_cfi.c create mode 100644 backends/loongarch_regs.c diff --git a/backends/ChangeLog b/backends/ChangeLog index 7bde2919..926c76ed 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,4 +1,11 @@ -2023-04-01 Youling Tang +2023-04-07 Youling Tang + + * Makefile.am (loongarch_SRCS): Add loongarch_cfi.c and loongarch_regs.c. + * loongarch_cfi.c: New file. + * loongarch_regs.c: Likewise. + * loongarch_init.c (loongarch_init): Hook register_info and abi_cfi. + +2023-04-01 Youling Tang * loongarch_init.c (loongarch_init): Hook check_special_symbol. * loongarch_symbol.c (loongarch_check_special_symbol): New function. diff --git a/backends/Makefile.am b/backends/Makefile.am index f373e5fb..2b6f08ce 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -96,7 +96,8 @@ riscv_SRCS = riscv_init.c riscv_symbol.c riscv_cfi.c riscv_regs.c \ csky_SRCS = csky_attrs.c csky_init.c csky_symbol.c csky_cfi.c \ csky_regs.c csky_initreg.c csky_corenote.c -loongarch_SRCS = loongarch_init.c loongarch_symbol.c +loongarch_SRCS = loongarch_init.c loongarch_symbol.c loongarch_cfi.c \ + loongarch_regs.c arc_SRCS = arc_init.c arc_symbol.c diff --git a/backends/loongarch_cfi.c b/backends/loongarch_cfi.c new file mode 100644 index 00000000..5f3cd2c7 --- /dev/null +++ b/backends/loongarch_cfi.c @@ -0,0 +1,83 @@ +/* LoongArch ABI-specified defaults for DWARF CFI. + Copyright (C) 2023 OpenAnolis community LoongArch SIG. + Copyright (C) 2023 Loongson Technology Corporation Limted. + 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define BACKEND loongarch_ +#include "libebl_CPU.h" + +/* LoongArch ELF ABI specification: +https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_register_convention +*/ +int +loongarch_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 ($r3) as setup in the previous frame. */ + DW_CFA_def_cfa, ULEB128_7 (3), ULEB128_7 (0), + + /* The Stack Pointer ($r3) is restored from CFA address by default. */ + DW_CFA_val_offset, ULEB128_7 (3), 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-$s7. */ + SV (23), SV (24), SV (25), SV (26), SV (27), SV (28), + SV (29), SV (30), SV (31), + + /* The Frame Pointer ($fp, $r22) */ + SV(22), + + /* Callee-saved registers $fs0-$fs7. */ + SV (56), SV (57), SV (58), SV (59), SV (60), SV (61), + SV (62), SV (63), +#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/loongarch_init.c b/backends/loongarch_init.c index b641b07f..7bfaaa7f 100644 --- a/backends/loongarch_init.c +++ b/backends/loongarch_init.c @@ -46,6 +46,10 @@ loongarch_init (Elf *elf __attribute__ ((unused)), loongarch_init_reloc (eh); HOOK (eh, reloc_simple_type); HOOK (eh, machine_flag_check); + HOOK (eh, register_info); + HOOK (eh, abi_cfi); + /* gcc/config/ #define DWARF_FRAME_REGISTERS. */ + eh->frame_nregs = 74; HOOK (eh, check_special_symbol); return eh; diff --git a/backends/loongarch_regs.c b/backends/loongarch_regs.c new file mode 100644 index 00000000..4a4b2052 --- /dev/null +++ b/backends/loongarch_regs.c @@ -0,0 +1,141 @@ +/* Register names and numbers for LoongArch DWARF. + Copyright (C) 2023 OpenAnolis community LoongArch SIG. + Copyright (C) 2023 Loongson Technology Corporation Limted. + 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define BACKEND loongarch_ +#include "libebl_CPU.h" + +ssize_t +loongarch_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, "tp") + 1 - name; + + case 3: + *type = DW_ATE_address; + return stpcpy (name, "sp") + 1 - name; + + case 4 ... 11: + name[0] = 'a'; + name[1] = regno - 4 + '0'; + namelen = 2; + break; + + case 12 ... 20: + name[0] = 't'; + name[1] = regno - 12 + '0'; + namelen = 2; + break; + + case 21: + return stpcpy (name, "u0") + 1 - name; + + case 22: + *type = DW_ATE_address; + return stpcpy (name, "fp") + 1 - name; + + case 23 ... 31: + name[0] = 's'; + name[1] = regno - 23 + '0'; + namelen = 2; + break; + + case 32 ... 39: + name[0] = 'f'; + name[1] = 'a'; + name[2] = regno - 32 + '0'; + namelen = 3; + break; + + case 40 ... 49: + name[0] = 'f'; + name[1] = 't'; + name[2] = regno - 40 + '0'; + namelen = 3; + break; + + case 50 ... 55: + name[0] = 'f'; + name[1] = 't'; + name[2] = '1'; + name[3] = regno - 50 + '0'; + namelen = 4; + break; + + case 56 ... 63: + name[0] = 'f'; + name[1] = 's'; + name[2] = regno - 56 + '0'; + namelen = 3; + break; + + default: + *setname = NULL; + return 0; + } + + name[namelen++] = '\0'; + return namelen; +} -- cgit v1.2.1