RISC-V: Add linux target support.
[external/binutils.git] / gdb / riscv-linux-tdep.c
1 /* Target-dependent code for GNU/Linux on RISC-V processors.
2    Copyright (C) 2018 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #include "defs.h"
20 #include "riscv-tdep.h"
21 #include "osabi.h"
22 #include "glibc-tdep.h"
23 #include "linux-tdep.h"
24 #include "solib-svr4.h"
25 #include "regset.h"
26
27 /* Define the general register mapping.  The kernel puts the PC at offset 0,
28    gdb puts it at offset 32.  Register x0 is always 0 and can be ignored.
29    Registers x1 to x31 are in the same place.  */
30
31 static const struct regcache_map_entry riscv_linux_gregmap[] =
32 {
33   { 1,  RISCV_PC_REGNUM, 0 },
34   { 31, RISCV_RA_REGNUM, 0 }, /* x1 to x31 */
35   { 0 }
36 };
37
38 /* Define the general register regset.  */
39
40 static const struct regset riscv_linux_gregset =
41 {
42   riscv_linux_gregmap, regcache_supply_regset, regcache_collect_regset
43 };
44
45 /* Define hook for core file support.  */
46
47 static void
48 riscv_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
49                                           iterate_over_regset_sections_cb *cb,
50                                           void *cb_data,
51                                           const struct regcache *regcache)
52 {
53   cb (".reg", (32 * riscv_isa_xlen (gdbarch)),
54       &riscv_linux_gregset, NULL, cb_data);
55
56   /* TODO: Add FP register support.  */
57 }
58
59 /* Initialize RISC-V Linux ABI info.  */
60
61 static void
62 riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
63 {
64   linux_init_abi (info, gdbarch);
65
66   set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
67
68   set_solib_svr4_fetch_link_map_offsets (gdbarch,
69                                          (riscv_isa_xlen (gdbarch) == 4
70                                           ? svr4_ilp32_fetch_link_map_offsets
71                                           : svr4_lp64_fetch_link_map_offsets));
72
73   /* GNU/Linux uses SVR4-style shared libraries.  */
74   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
75
76   /* GNU/Linux uses the dynamic linker included in the GNU C Library.  */
77   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
78
79   /* Enable TLS support.  */
80   set_gdbarch_fetch_tls_load_module_address (gdbarch,
81                                              svr4_fetch_objfile_link_map);
82
83   set_gdbarch_iterate_over_regset_sections
84     (gdbarch, riscv_linux_iterate_over_regset_sections);
85 }
86
87 /* Initialize RISC-V Linux target support.  */
88
89 void
90 _initialize_riscv_linux_tdep (void)
91 {
92   gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_LINUX,
93                           riscv_linux_init_abi);
94 }