diff options
Diffstat (limited to 'backends')
30 files changed, 673 insertions, 38 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog index a66e923e..3fa0f198 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,76 @@ +2018-06-16 Yonghong Song <yhs@fb.com> + + * Makefile.am (bpf_SRCS): Add bpf_symbol.c. + * bpf_init.c (bpf_init): Add reloc_simple_type HOOK. + * bpf_reloc.def: Add RELOC_TYPE 64_64 and 64_32. + * bpf_symbol.c: New file. + +2018-06-21 Mark Wielaard <mark@klomp.org> + + * bpf_reloc.def: Remove MAP_FD. + +2018-06-13 Andreas Schwab <schwab@suse.de> + + * Makefile.am (riscv_SRCS): Add riscv_cfi.c and riscv_regs.c. + * riscv_cfi.c: New file. + * riscv_regs.c: Likewise. + * riscv_init.c (riscv_init): Hook register_info and abi_cfi. + +2018-05-15 Andreas Schwab <schwab@suse.de> + + * riscv_init.c (riscv_init): Hook check_special_symbol. + * riscv_symbol.c (riscv_check_special_symbol): New function. + +2018-04-19 Andreas Schwab <schwab@suse.de> + + * Makefile.am (modules): Add riscv. + * riscv_init.c: New file. + * riscv_reloc.def: New file. + * riscv_symbol.c: New file. + +2018-04-11 Mark Wielaard <mark@klomp.org> + + * aarch64_cfi.c (aarch64_abi_cfi): Add rule for restoring SP from + CFA address. + +2018-02-15 Mark Wielaard <mark@klomp.org> + + * ppc_initreg.c: Include ptrace.h before system.h and sys/user.h. + +2018-02-09 Joshua Watt <JPEWhacker@gmail.com> + + * aarch64_retval.c (aarch64_return_value_location): Use FALLTHROUGH + macro instead of comment. + * alpha_retval.c (alpha_return_value_location): Likewise. + * arm_regs.c (arm_register_info): Likewise. + * arm_retval.c (arm_return_value_location): Likewise. + * i386_regs.c (i386_register_info): Likewise. + * i386_retval.c (i386_return_value_location): Likewise. + * ia64_retval.c (ia64_return_value_location): Likewise. + * linux-core-note.c (core_note): Likewise. + * m68k_retval.c (m68k_return_value_location): Likewise. + * ppc64_retval.c (ppc64_return_value_location): Likewise. + * ppc_regs.c (ppc_register_info): Likewise. + * ppc_retval.c (ppc_return_value_location): Likewise. + * s390_retval.c (s390_return_value_location): Likewise. + * sh_retval.c (sh_return_value_location): Likewise. + * sparc_retval.c (sparc_return_value_location): Likewise. + * tilegx_retval.c (tilegx_return_value_location): Likewise. + * x86_64_regs.c (x86_64_register_info): Likewise. + * x86_64_retval.c (x86_64_return_value_location): Likewise. + +2017-10-24 Mark Wielaard <mark@klomp.org> + + * Makefile.am (m68k_corenote_no_Wpacked_not_aligned): New variable. + +2017-08-18 Ulf Hermann <ulf.hermann@qt.io> + + * linux-core-note.c: Use attribute_packed. + +2017-04-27 Ulf Hermann <ulf.hermann@qt.io> + + * Makefile.am: Use dso_LDFLAGS. + 2017-07-27 Mark Wielaard <mark@klomp.org> * sparc_reloc.def: GOTDATA_OP_HIX22, GOTDATA_OP_LOX10 and diff --git a/backends/Makefile.am b/backends/Makefile.am index 03b9d201..dcf65394 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -33,12 +33,12 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \ modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \ - tilegx m68k bpf + tilegx m68k bpf riscv libebl_pic = libebl_i386_pic.a libebl_sh_pic.a libebl_x86_64_pic.a \ libebl_ia64_pic.a libebl_alpha_pic.a libebl_arm_pic.a \ libebl_aarch64_pic.a libebl_sparc_pic.a libebl_ppc_pic.a \ libebl_ppc64_pic.a libebl_s390_pic.a libebl_tilegx_pic.a \ - libebl_m68k_pic.a libebl_bpf_pic.a + libebl_m68k_pic.a libebl_bpf_pic.a libebl_riscv_pic.a noinst_LIBRARIES = $(libebl_pic) noinst_DATA = $(libebl_pic:_pic.a=.so) lib_LIBRARIES = libebl_static_pic.a @@ -68,7 +68,7 @@ static_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \ ppc64_resolve_sym.c ppc64_unwind.c \ s390_init.c s390_symbol.c s390_regs.c s390_retval.c \ s390_corenote.c s390x_corenote.c s390_cfi.c s390_initreg.c \ - s390_unwind.c bpf_init.c bpf_regs.c + s390_unwind.c bpf_init.c bpf_regs.c bpf_symbol.c libebl_static_pic_a_SOURCES = $(static_SRCS) am_libebl_static_pic_a_OBJECTS = $(static_SRCS:.c=.os) @@ -145,20 +145,31 @@ m68k_SRCS = m68k_init.c m68k_symbol.c m68k_regs.c \ libebl_m68k_pic_a_SOURCES = $(m68k_SRCS) am_libebl_m68k_pic_a_OBJECTS = $(m68k_SRCS:.c=.os) -bpf_SRCS = bpf_init.c bpf_regs.c +# m68k prstatus core notes are described by a packed structure +# which has not naturally aligned fields. Since we don't access +# these fields directly, but take their offset to be used later +# to extract the data through elfxx_xlatetom/memmove, this isn't +# an issue. +m68k_corenote_no_Wpacked_not_aligned = yes + +bpf_SRCS = bpf_init.c bpf_regs.c bpf_symbol.c 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_cfi.c riscv_regs.c +libebl_riscv_pic_a_SOURCES = $(riscv_SRCS) +am_libebl_riscv_pic_a_OBJECTS = $(riscv_SRCS:.c=.os) + libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw) $(libeu) @rm -f $(@:.so=.map) $(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' \ > $(@:.so=.map) - $(AM_V_CCLD)$(LINK) -shared -o $(@:.map=.so) \ + $(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $(@:.map=.so) \ -Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \ -Wl,--version-script,$(@:.so=.map),--no-undefined \ - -Wl,-z,defs,-z,relro -Wl,--as-needed $(libelf) $(libdw) $(libeu) + -Wl,--as-needed $(libelf) $(libdw) $(libeu) @$(textrel_check) libebl_i386.so: $(cpu_i386) diff --git a/backends/aarch64_cfi.c b/backends/aarch64_cfi.c index acbb9b69..a5579ab1 100644 --- a/backends/aarch64_cfi.c +++ b/backends/aarch64_cfi.c @@ -1,5 +1,5 @@ -/* arm ABI-specified defaults for DWARF CFI. - Copyright (C) 2013 Red Hat, Inc. +/* arm64 ABI-specified defaults for DWARF CFI. + Copyright (C) 2013, 2018 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -62,6 +62,9 @@ aarch64_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info) /* The Frame Pointer (FP, r29) and Link Register (LR, r30). */ SV (29), SV (30), + /* The Stack Pointer (r31) is restored from CFA address by default. */ + DW_CFA_val_offset, ULEB128_7 (31), ULEB128_7 (0), + /* Callee-saved fpregs v8-v15. v0 == 64. */ SV (72), SV (73), SV (74), SV (75), SV (76), SV (77), SV (78), SV (79), diff --git a/backends/aarch64_retval.c b/backends/aarch64_retval.c index 68de307e..1308340b 100644 --- a/backends/aarch64_retval.c +++ b/backends/aarch64_retval.c @@ -292,7 +292,7 @@ aarch64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) assert (count > 0); if (count <= 4) return pass_hfa (locp, base_size, count); - /* Fall through. */ + FALLTHROUGH; case 1: /* Not a HFA. */ diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c index 53dbfa45..d9bae3bc 100644 --- a/backends/alpha_retval.c +++ b/backends/alpha_retval.c @@ -85,7 +85,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: @@ -131,7 +131,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) } } - /* Else fall through. */ + FALLTHROUGH; case DW_TAG_structure_type: case DW_TAG_class_type: diff --git a/backends/arm_regs.c b/backends/arm_regs.c index 21c5ad3a..a46a4c99 100644 --- a/backends/arm_regs.c +++ b/backends/arm_regs.c @@ -77,7 +77,7 @@ arm_register_info (Ebl *ebl __attribute__ ((unused)), case 16 + 0 ... 16 + 7: regno += 96 - 16; - /* Fall through. */ + FALLTHROUGH; case 96 + 0 ... 96 + 7: *setname = "FPA"; *type = DW_ATE_float; diff --git a/backends/arm_retval.c b/backends/arm_retval.c index 7aced742..1c28f016 100644 --- a/backends/arm_retval.c +++ b/backends/arm_retval.c @@ -82,7 +82,7 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: diff --git a/backends/bpf_init.c b/backends/bpf_init.c index 8ea1bc1a..a046e069 100644 --- a/backends/bpf_init.c +++ b/backends/bpf_init.c @@ -53,6 +53,7 @@ bpf_init (Elf *elf __attribute__ ((unused)), bpf_init_reloc (eh); HOOK (eh, register_info); HOOK (eh, disasm); + HOOK (eh, reloc_simple_type); return MODVERSION; } diff --git a/backends/bpf_reloc.def b/backends/bpf_reloc.def index a410da97..59f519b5 100644 --- a/backends/bpf_reloc.def +++ b/backends/bpf_reloc.def @@ -28,4 +28,5 @@ /* NAME, REL|EXEC|DYN */ RELOC_TYPE (NONE, EXEC|DYN) -RELOC_TYPE (MAP_FD, REL|EXEC|DYN) +RELOC_TYPE (64_64, REL) +RELOC_TYPE (64_32, REL) diff --git a/backends/bpf_symbol.c b/backends/bpf_symbol.c new file mode 100644 index 00000000..c9856f26 --- /dev/null +++ b/backends/bpf_symbol.c @@ -0,0 +1,54 @@ +/* BPF specific symbolic name handling. + 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 <assert.h> +#include <elf.h> +#include <stddef.h> +#include <string.h> + +#define BACKEND bpf_ +#include "libebl_CPU.h" + + +/* Check for the simple reloc types. */ +Elf_Type +bpf_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type) +{ + switch (type) + { + case R_BPF_64_64: + return ELF_T_XWORD; + case R_BPF_64_32: + return ELF_T_WORD; + default: + return ELF_T_NUM; + } +} diff --git a/backends/i386_regs.c b/backends/i386_regs.c index fd963a62..7ec93bb9 100644 --- a/backends/i386_regs.c +++ b/backends/i386_regs.c @@ -92,7 +92,7 @@ i386_register_info (Ebl *ebl __attribute__ ((unused)), case 5: case 8: *type = DW_ATE_address; - /* Fallthrough */ + FALLTHROUGH; case 0 ... 3: case 6 ... 7: name[0] = 'e'; diff --git a/backends/i386_retval.c b/backends/i386_retval.c index 4aa646fe..32fec728 100644 --- a/backends/i386_retval.c +++ b/backends/i386_retval.c @@ -85,7 +85,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: @@ -123,7 +123,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) if (size <= 8) return nloc_intregpair; } - /* Fallthrough */ + FALLTHROUGH; case DW_TAG_structure_type: case DW_TAG_class_type: diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c index dcd5f28d..03ea4d89 100644 --- a/backends/ia64_retval.c +++ b/backends/ia64_retval.c @@ -260,7 +260,7 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: diff --git a/backends/linux-core-note.c b/backends/linux-core-note.c index 67638d70..9faae4c3 100644 --- a/backends/linux-core-note.c +++ b/backends/linux-core-note.c @@ -111,7 +111,7 @@ struct EBLHOOK(prstatus) FIELD (INT, pr_fpvalid); } #ifdef ALIGN_PRSTATUS - __attribute__ ((packed, aligned (ALIGN_PRSTATUS))) + attribute_packed __attribute__ ((aligned (ALIGN_PRSTATUS))) #endif ; @@ -226,7 +226,7 @@ EBLHOOK(core_note) (const GElf_Nhdr *nhdr, const char *name, if (memcmp (name, "CORE", nhdr->n_namesz) == 0) break; /* Buggy old Linux kernels didn't terminate "LINUX". */ - /* Fall through. */ + FALLTHROUGH; case sizeof "LINUX": if (memcmp (name, "LINUX", nhdr->n_namesz) == 0) diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c index c68ed022..a653ba3a 100644 --- a/backends/m68k_retval.c +++ b/backends/m68k_retval.c @@ -92,7 +92,7 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: @@ -135,7 +135,7 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) if (size <= 8) return nloc_intregpair; } - /* Fallthrough */ + FALLTHROUGH; case DW_TAG_structure_type: case DW_TAG_class_type: case DW_TAG_union_type: diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c index a2519839..eb1c11ec 100644 --- a/backends/ppc64_retval.c +++ b/backends/ppc64_retval.c @@ -96,7 +96,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: @@ -141,7 +141,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) return nloc_intreg; } - /* Else fall through. */ + FALLTHROUGH; case DW_TAG_structure_type: case DW_TAG_class_type: case DW_TAG_union_type: @@ -161,7 +161,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) return nloc_vmxreg; } } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_string_type: if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 8) diff --git a/backends/ppc_initreg.c b/backends/ppc_initreg.c index 69d623b9..3e4432f6 100644 --- a/backends/ppc_initreg.c +++ b/backends/ppc_initreg.c @@ -30,13 +30,14 @@ # include <config.h> #endif -#include "system.h" #include <stdlib.h> #if defined(__powerpc__) && defined(__linux__) -# include <sys/user.h> # include <sys/ptrace.h> +# include <sys/user.h> #endif +#include "system.h" + #define BACKEND ppc_ #include "libebl_CPU.h" diff --git a/backends/ppc_regs.c b/backends/ppc_regs.c index c2d50118..43d2534f 100644 --- a/backends/ppc_regs.c +++ b/backends/ppc_regs.c @@ -140,7 +140,7 @@ ppc_register_info (Ebl *ebl __attribute__ ((unused)), case 100: if (*bits == 32) return stpcpy (name, "mq") + 1 - name; - /* Fallthrough */ + FALLTHROUGH; case 102 ... 107: name[0] = 's'; name[1] = 'p'; diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c index b14a99f1..39b42da1 100644 --- a/backends/ppc_retval.c +++ b/backends/ppc_retval.c @@ -108,7 +108,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: @@ -172,7 +172,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) return nloc_intregquad; } } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_structure_type: case DW_TAG_class_type: diff --git a/backends/riscv_cfi.c b/backends/riscv_cfi.c new file mode 100644 index 00000000..1a84a382 --- /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 new file mode 100644 index 00000000..5588a6b7 --- /dev/null +++ b/backends/riscv_init.c @@ -0,0 +1,62 @@ +/* Initialization of RISC-V specific backend library. + 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 + +#define BACKEND riscv_ +#define RELOC_PREFIX R_RISCV_ +#include "libebl_CPU.h" + +/* This defines the common reloc hooks based on riscv_reloc.def. */ +#include "common-reloc.c" + + +const char * +riscv_init (Elf *elf __attribute__ ((unused)), + GElf_Half machine __attribute__ ((unused)), + Ebl *eh, + size_t ehlen) +{ + /* Check whether the Elf_BH object has a sufficent size. */ + if (ehlen < sizeof (Ebl)) + return NULL; + + /* We handle it. */ + 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); + + return MODVERSION; +} diff --git a/backends/riscv_regs.c b/backends/riscv_regs.c new file mode 100644 index 00000000..7b577ca0 --- /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; +} diff --git a/backends/riscv_reloc.def b/backends/riscv_reloc.def new file mode 100644 index 00000000..2bd3513e --- /dev/null +++ b/backends/riscv_reloc.def @@ -0,0 +1,83 @@ +/* List the relocation types for RISC-V. -*- C -*- + 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/>. */ + +/* NAME, REL|EXEC|DYN */ + +RELOC_TYPE (NONE, EXEC|DYN) +RELOC_TYPE (32, REL|EXEC|DYN) +RELOC_TYPE (64, REL|EXEC|DYN) +RELOC_TYPE (RELATIVE, EXEC|DYN) +RELOC_TYPE (COPY, EXEC|DYN) +RELOC_TYPE (JUMP_SLOT, EXEC|DYN) +RELOC_TYPE (TLS_DTPMOD32, EXEC|DYN) +RELOC_TYPE (TLS_DTPMOD64, EXEC|DYN) +RELOC_TYPE (TLS_DTPREL32, EXEC|DYN) +RELOC_TYPE (TLS_DTPREL64, EXEC|DYN) +RELOC_TYPE (TLS_TPREL32, EXEC|DYN) +RELOC_TYPE (TLS_TPREL64, EXEC|DYN) +RELOC_TYPE (BRANCH, REL) +RELOC_TYPE (JAL, REL) +RELOC_TYPE (CALL, REL) +RELOC_TYPE (CALL_PLT, REL) +RELOC_TYPE (GOT_HI20, REL) +RELOC_TYPE (TLS_GOT_HI20, REL) +RELOC_TYPE (TLS_GD_HI20, REL) +RELOC_TYPE (PCREL_HI20, REL) +RELOC_TYPE (PCREL_LO12_I, REL) +RELOC_TYPE (PCREL_LO12_S, REL) +RELOC_TYPE (HI20, REL) +RELOC_TYPE (LO12_I, REL) +RELOC_TYPE (LO12_S, REL) +RELOC_TYPE (TPREL_HI20, REL) +RELOC_TYPE (TPREL_LO12_I, REL) +RELOC_TYPE (TPREL_LO12_S, REL) +RELOC_TYPE (TPREL_ADD, REL) +RELOC_TYPE (ADD8, REL) +RELOC_TYPE (ADD16, REL) +RELOC_TYPE (ADD32, REL) +RELOC_TYPE (ADD64, REL) +RELOC_TYPE (SUB8, REL) +RELOC_TYPE (SUB16, REL) +RELOC_TYPE (SUB32, REL) +RELOC_TYPE (SUB64, REL) +RELOC_TYPE (GNU_VTINHERIT, REL) +RELOC_TYPE (GNU_VTENTRY, REL) +RELOC_TYPE (ALIGN, REL) +RELOC_TYPE (RVC_BRANCH, REL) +RELOC_TYPE (RVC_JUMP, REL) +RELOC_TYPE (RVC_LUI, REL) +RELOC_TYPE (GPREL_I, REL) +RELOC_TYPE (GPREL_S, REL) +RELOC_TYPE (TPREL_I, REL) +RELOC_TYPE (TPREL_S, REL) +RELOC_TYPE (RELAX, REL) +RELOC_TYPE (SUB6, REL) +RELOC_TYPE (SET6, REL) +RELOC_TYPE (SET8, REL) +RELOC_TYPE (SET16, REL) +RELOC_TYPE (SET32, REL) +RELOC_TYPE (32_PCREL, REL) diff --git a/backends/riscv_symbol.c b/backends/riscv_symbol.c new file mode 100644 index 00000000..dce8e358 --- /dev/null +++ b/backends/riscv_symbol.c @@ -0,0 +1,94 @@ +/* RISC-V specific symbolic name handling. + 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 <assert.h> +#include <elf.h> +#include <stddef.h> +#include <string.h> + +#define BACKEND riscv_ +#include "libebl_CPU.h" + + +/* Check for the simple reloc types. */ +Elf_Type +riscv_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type) +{ + switch (type) + { + case R_RISCV_32: + return ELF_T_WORD; + case R_RISCV_64: + return ELF_T_XWORD; + default: + return ELF_T_NUM; + } +} + +/* Check whether machine flags are valid. */ +bool +riscv_machine_flag_check (GElf_Word flags) +{ + return ((flags &~ (EF_RISCV_RVC + | EF_RISCV_FLOAT_ABI)) == 0); +} + +/* Check whether given symbol's st_value and st_size are OK despite failing + normal checks. */ +bool +riscv_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, + const char *name, const GElf_Shdr *destshdr) +{ + if (name == NULL) + return false; + + const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name); + if (sname == NULL) + return false; + + /* _GLOBAL_OFFSET_TABLE_ points to the start of the .got section, but it + is preceded by the .got.plt section in the output .got section. */ + if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + return (strcmp (sname, ".got") == 0 + && sym->st_value >= destshdr->sh_addr + && sym->st_value < destshdr->sh_addr + destshdr->sh_size); + + /* __global_pointer$ points to the .sdata section with an offset of + 0x800. It might however fall in the .got section, in which case we + cannot check the offset. The size always should be zero. */ + if (strcmp (name, "__global_pointer$") == 0) + return (((strcmp (sname, ".sdata") == 0 + && sym->st_value == destshdr->sh_addr + 0x800) + || strcmp (sname, ".got") == 0) + && sym->st_size == 0); + + return false; +} diff --git a/backends/s390_retval.c b/backends/s390_retval.c index a927d46a..2043f985 100644 --- a/backends/s390_retval.c +++ b/backends/s390_retval.c @@ -87,7 +87,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: @@ -127,7 +127,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) return size <= asize ? nloc_intreg : nloc_intregpair; } } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_structure_type: case DW_TAG_class_type: diff --git a/backends/sh_retval.c b/backends/sh_retval.c index d44f2601..33d7d964 100644 --- a/backends/sh_retval.c +++ b/backends/sh_retval.c @@ -84,7 +84,7 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c index e1b17753..fb81cdce 100644 --- a/backends/sparc_retval.c +++ b/backends/sparc_retval.c @@ -91,7 +91,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: diff --git a/backends/tilegx_retval.c b/backends/tilegx_retval.c index db81a20b..7f7d24b0 100644 --- a/backends/tilegx_retval.c +++ b/backends/tilegx_retval.c @@ -79,7 +79,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: @@ -113,7 +113,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) return nloc_intreg; } - /* Else fall through. */ + FALLTHROUGH; case DW_TAG_structure_type: case DW_TAG_class_type: case DW_TAG_union_type: diff --git a/backends/x86_64_regs.c b/backends/x86_64_regs.c index 84304407..ef987daf 100644 --- a/backends/x86_64_regs.c +++ b/backends/x86_64_regs.c @@ -87,7 +87,7 @@ x86_64_register_info (Ebl *ebl __attribute__ ((unused)), case 6 ... 7: *type = DW_ATE_address; - /* Fallthrough */ + FALLTHROUGH; case 0 ... 5: name[0] = 'r'; name[1] = baseregs[regno][0]; diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c index b3799ae0..f9114cb1 100644 --- a/backends/x86_64_retval.c +++ b/backends/x86_64_retval.c @@ -100,7 +100,7 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) typedie = dwarf_formref_die (attr, &die_mem); tag = DWARF_TAG_OR_RETURN (typedie); } - /* Fall through. */ + FALLTHROUGH; case DW_TAG_base_type: case DW_TAG_enumeration_type: |