diff options
author | Hafiz Abid Qadeer <abidh@codesourcery.com> | 2018-07-25 10:43:22 +0100 |
---|---|---|
committer | Hafiz Abid Qadeer <abidh@codesourcery.com> | 2018-08-28 12:08:11 +0100 |
commit | 9d24df82ece4e87a0328173d6bd31cb9ff558bb4 (patch) | |
tree | 9e4bfa9640b954a23b115ac5416e0d2be7dd38ec /gdb/csky-linux-tdep.c | |
parent | 626887ddc306b336e1406cf661f23398bed8be66 (diff) | |
download | gdb-9d24df82ece4e87a0328173d6bd31cb9ff558bb4.zip gdb-9d24df82ece4e87a0328173d6bd31cb9ff558bb4.tar.gz gdb-9d24df82ece4e87a0328173d6bd31cb9ff558bb4.tar.bz2 |
Add support for new target 'csky'.
2018-08-28 Jiangshuai Li <jiangshuai_li@c-sky.com>
Hafiz Abid Qadeer <abidh@codesourcery.com>
Don Breazeal <donb@codesourcery.com>
* csky-linux-tdep.c: New file.
* csky-tdep.c: Likewise.
* csky-tdep.h: Likewise.
* Makefile.in (ALL_TARGET_OBS): Add csky-linux-tdep.o and
csky-tdep.o.
(HFILES_NO_SRCDIR): Add csky-tdep.h.
(ALLDEPFILES): Add csky-linux-tdep.c and csky-tdep.c
* configure.tgt: Add csky support.
Diffstat (limited to 'gdb/csky-linux-tdep.c')
-rw-r--r-- | gdb/csky-linux-tdep.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c new file mode 100644 index 0000000..663ffe4 --- /dev/null +++ b/gdb/csky-linux-tdep.c @@ -0,0 +1,263 @@ +/* Target-dependent code for GNU/Linux on CSKY. + + Copyright (C) 2012-2018 Free Software Foundation, Inc. + + Contributed by C-SKY Microsystems and Mentor Graphics. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "defs.h" +#include "osabi.h" +#include "glibc-tdep.h" +#include "linux-tdep.h" +#include "gdbarch.h" +#include "solib-svr4.h" +#include "regset.h" +#include "trad-frame.h" +#include "tramp-frame.h" +#include "csky-tdep.h" + +/* Functions, definitions, and data structures for C-Sky core file debug. */ + +/* General regset pc, r1, r0, psr, r2-r31 for CK810. */ +#define SIZEOF_CSKY_GREGSET 34*4 +/* Float regset fesr fsr fr0-fr31 for CK810. */ +#define SIZEOF_CSKY_FREGSET 34*4 + +/* Offset mapping table from core_section to regcache of general + registers for ck810. */ +static const int csky_gregset_offset[] = +{ + 72, 1, 0, 89, 2, /* pc, r1, r0, psr, r2. */ + 3, 4, 5, 6, 7, /* r3 ~ r32. */ + 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, + 28, 29, 30, 31 +}; + +/* Offset mapping table from core_section to regcache of float + registers for ck810. */ + +static const int csky_fregset_offset[] = +{ + 122, 123, 40, 41, 42, /* fcr, fesr, fr0 ~ fr2. */ + 43, 44, 45, 46, 47, /* fr3 ~ fr15. */ + 48, 49, 50, 51, 52, + 53, 54, 55 +}; + +/* Implement the supply_regset hook for GP registers in core files. */ + +static void +csky_supply_gregset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *regs, size_t len) +{ + int i, gregset_num; + const gdb_byte *gregs = (const gdb_byte *) regs ; + + gdb_assert (len >= SIZEOF_CSKY_GREGSET); + gregset_num = ARRAY_SIZE (csky_gregset_offset); + + for (i = 0; i < gregset_num; i++) + { + if ((regnum == csky_gregset_offset[i] || regnum == -1) + && csky_gregset_offset[i] != -1) + regcache->raw_supply (csky_gregset_offset[i], gregs + 4 * i); + } +} + +/* Implement the collect_regset hook for GP registers in core files. */ + +static void +csky_collect_gregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *gregs_buf, size_t len) +{ + int regno, gregset_num; + gdb_byte *gregs = (gdb_byte *) gregs_buf ; + + gdb_assert (len >= SIZEOF_CSKY_GREGSET); + gregset_num = ARRAY_SIZE (csky_gregset_offset); + + for (regno = 0; regno < gregset_num; regno++) + { + if ((regnum == csky_gregset_offset[regno] || regnum == -1) + && csky_gregset_offset[regno] != -1) + regcache->raw_collect (regno, + gregs + 4 + csky_gregset_offset[regno]); + } +} + +/* Implement the supply_regset hook for FP registers in core files. */ + +void +csky_supply_fregset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *regs, size_t len) +{ + int i; + int offset = 0; + struct gdbarch *gdbarch = regcache->arch (); + const gdb_byte *fregs = (const gdb_byte *) regs; + int fregset_num = ARRAY_SIZE (csky_fregset_offset); + + gdb_assert (len >= SIZEOF_CSKY_FREGSET); + for (i = 0; i < fregset_num; i++) + { + if ((regnum == csky_fregset_offset[i] || regnum == -1) + && csky_fregset_offset[i] != -1) + { + int num = csky_fregset_offset[i]; + offset += register_size (gdbarch, num); + regcache->raw_supply (csky_fregset_offset[i], fregs + offset); + } + } +} + +/* Implement the collect_regset hook for FP registers in core files. */ + +static void +csky_collect_fregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *fregs_buf, size_t len) +{ + int regno; + struct gdbarch *gdbarch = regcache->arch (); + gdb_byte *fregs = (gdb_byte *) fregs_buf ; + int fregset_num = ARRAY_SIZE (csky_fregset_offset); + int offset = 0; + + gdb_assert (len >= SIZEOF_CSKY_FREGSET); + for (regno = 0; regno < fregset_num; regno++) + { + if ((regnum == csky_fregset_offset[regno] || regnum == -1) + && csky_fregset_offset[regno] != -1) + { + offset += register_size (gdbarch, csky_fregset_offset[regno]); + regcache->raw_collect (regno, fregs + offset); + } + } +} + +static const struct regset csky_regset_general = +{ + NULL, + csky_supply_gregset, + csky_collect_gregset +}; + +static const struct regset csky_regset_float = +{ + NULL, + csky_supply_fregset, + csky_collect_fregset +}; + +/* Iterate over core file register note sections. */ + +static void +csky_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + iterate_over_regset_sections_cb *cb, + void *cb_data, + const struct regcache *regcache) +{ + cb (".reg", sizeof (csky_gregset_offset), sizeof (csky_gregset_offset), + &csky_regset_general, NULL, cb_data); + cb (".reg2", sizeof (csky_fregset_offset), sizeof (csky_fregset_offset), + &csky_regset_float, NULL, cb_data); +} + +static void +csky_linux_rt_sigreturn_init (const struct tramp_frame *self, + struct frame_info *this_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) +{ + int i; + CORE_ADDR sp = get_frame_register_unsigned (this_frame, 14); + + CORE_ADDR base = sp + CSKY_SIGINFO_OFFSET + CSKY_SIGINFO_SIZE + + CSKY_UCONTEXT_SIGCONTEXT + + CSKY_SIGCONTEXT_SC_USP + + CSKY_SIGCONTEXT_SC_A0; + + /* Set addrs of R0 ~ R13. */ + for (i = 0; i < 14; i++) + trad_frame_set_reg_addr (this_cache, i, base + i * 4); + + /* Set addrs of SP(R14) and R15. */ + trad_frame_set_reg_addr (this_cache, 14, base - 4); + trad_frame_set_reg_addr (this_cache, 15, base + 4 * 14); + + /* Set addrs of R16 ~ R31. */ + for (i = 15; i < 31; i++) + trad_frame_set_reg_addr (this_cache, i, base + i * 4); + + /* Set addrs of PSR and PC. */ + trad_frame_set_reg_addr (this_cache, 89, base + 4 * 33); + trad_frame_set_reg_addr (this_cache, 72, base + 4 * 34); + + trad_frame_set_id (this_cache, frame_id_build (sp, func)); +} + +static struct tramp_frame +csky_linux_rt_sigreturn_tramp_frame = { + SIGTRAMP_FRAME, + 4, + { + { CSKY_MOVI_R7_173, ULONGEST_MAX }, + { CSKY_TRAP_0, ULONGEST_MAX }, + { TRAMP_SENTINEL_INSN } + }, + csky_linux_rt_sigreturn_init +}; + +/* Hook function for gdbarch_register_osabi. */ + +static void +csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + linux_init_abi (info, gdbarch); + + /* Shared library handling. */ + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); + set_solib_svr4_fetch_link_map_offsets (gdbarch, + svr4_ilp32_fetch_link_map_offsets); + + /* Enable TLS support. */ + set_gdbarch_fetch_tls_load_module_address (gdbarch, + svr4_fetch_objfile_link_map); + + /* Core file support. */ + set_gdbarch_iterate_over_regset_sections ( + gdbarch, csky_linux_iterate_over_regset_sections); + + /* Append tramp frame unwinder for SIGNAL. */ + + tramp_frame_prepend_unwinder (gdbarch, + &csky_linux_rt_sigreturn_tramp_frame); +} + +void +_initialize_csky_linux_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_csky, 0, GDB_OSABI_LINUX, + csky_linux_init_abi); +} |