aboutsummaryrefslogtreecommitdiff
path: root/gdb/loongarch-linux-tdep.c
AgeCommit message (Collapse)AuthorFilesLines
2022-07-21gdb: move the type cast into gdbarch_tdepAndrew Burgess1-1/+1
I built GDB for all targets on a x86-64/GNU-Linux system, and then (accidentally) passed GDB a RISC-V binary, and asked GDB to "run" the binary on the native target. I got this error: (gdb) show architecture The target architecture is set to "auto" (currently "i386"). (gdb) file /tmp/hello.rv32.exe Reading symbols from /tmp/hello.rv32.exe... (gdb) show architecture The target architecture is set to "auto" (currently "riscv:rv32"). (gdb) run Starting program: /tmp/hello.rv32.exe ../../src/gdb/i387-tdep.c:596: internal-error: i387_supply_fxsave: Assertion `tdep->st0_regnum >= I386_ST0_REGNUM' failed. What's going on here is this; initially the architecture is i386, this is based on the default architecture, which is set based on the native target. After loading the RISC-V executable the architecture of the current inferior is updated based on the architecture of the executable. When we "run", GDB does a fork & exec, with the inferior being controlled through ptrace. GDB sees an initial stop from the inferior as soon as the inferior comes to life. In response to this stop GDB ends up calling save_stop_reason (linux-nat.c), which ends up trying to read register from the inferior, to do this we end up calling target_ops::fetch_registers, which, for the x86-64 native target, calls amd64_linux_nat_target::fetch_registers. After this I eventually end up in i387_supply_fxsave, different x86 based targets will end in different functions to fetch registers, but it doesn't really matter which function we end up in, the problem is this line, which is repeated in many places: i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (arch); The problem here is that the ARCH in this line comes from the current inferior, which, as we discussed above, will be a RISC-V gdbarch, the tdep field will actually be of type riscv_gdbarch_tdep, not i386_gdbarch_tdep. After this cast we are relying on undefined behaviour, in my case I happen to trigger an assert, but this might not always be the case. The thing I tried that exposed this problem was of course, trying to start an executable of the wrong architecture on a native target. I don't think that the correct solution for this problem is to detect, at the point of cast, that the gdbarch_tdep object is of the wrong type, but, I did wonder, is there a way that we could protect ourselves from incorrectly casting the gdbarch_tdep object? I think that there is something we can do here, and this commit is the first step in that direction, though no actual check is added by this commit. This commit can be split into two parts: (1) In gdbarch.h and arch-utils.c. In these files I have modified gdbarch_tdep (the function) so that it now takes a template argument, like this: template<typename TDepType> static inline TDepType * gdbarch_tdep (struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep_1 (gdbarch); return static_cast<TDepType *> (tdep); } After this change we are no better protected, but the cast is now done within the gdbarch_tdep function rather than at the call sites, this leads to the second, much larger change in this commit, (2) Everywhere gdbarch_tdep is called, we make changes like this: - i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (arch); + i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch); There should be no functional change after this commit. In the next commit I will build on this change to add an assertion in gdbarch_tdep that checks we are casting to the correct type.
2022-07-12gdb: LoongArch: Add floating-point supportTiezhu Yang1-5/+64
This commit adds floating-point support for LoongArch gdb. Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-07-05gdb: LoongArch: add orig_a0 into register setXi Ruoyao1-0/+8
The basic support for LoongArch has been merged into the upstream Linux kernel since 5.19-rc1 on June 5, 2022. This commit adds orig_a0 which is added into struct user_pt_regs [1] to match the upstream kernel, and then the upstream GDB will work with the upstream kernel. Note that orig_a0 was added into struct user_pt_regs in the development cycle for merging LoongArch port into the upstream Linux kernel, so earlier kernels (notably, the product kernel with version 4.19 used in distros like UOS and Loongnix) don't have it. Inspect arch/loongarch/include/uapi/asm/ptrace.h in the kernel tree to make sure. To build upstream GDB for a kernel lacking orig_a0, it's necessary to revert this commit locally. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/include/uapi/asm/ptrace.h#n24 Signed-off-by: Xi Ruoyao <xry111@xry111.site> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-06-25gdb: LoongArch: Implement loongarch_linux_syscall_next_pc()Tiezhu Yang1-0/+26
When FRAME is at a syscall instruction, return the PC of the next instruction to be executed. Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-06-25gdb: LoongArch: Define register numbers and clean up codeTiezhu Yang1-58/+34
This commit defines register numbers of various important registers, we can use them directly in the related code, and also clean up some code to make them more clear and readable. Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-06-02gdb: LoongArch: Remove nonportable #includeRoland McGrath1-1/+0
Don't use gregset.h in *-tdep.c since it's not usable on hosts that don't have <sys/procfs.h>. It's not needed by this file, and should only be needed by *-nat.c files.
2022-05-24gdb: LoongArch: Define LOONGARCH_LINUX_NUM_GREGSET as 45Tiezhu Yang1-2/+2
LOONGARCH_LINUX_NUM_GREGSET should be defined as 45 (32 + 1 + 1 + 11) due to reserved 11 for extension in glibc, otherwise when execute: make check-gdb TESTS="gdb.base/corefile.exp" there exists the following failed testcase: (gdb) core-file /home/loongson/build.git/gdb/testsuite/outputs/gdb.base/corefile/corefile.core [New LWP 7742] warning: Unexpected size of section `.reg/7742' in core file. Core was generated by `/home/loongson/build.git/gdb/testsuite/outputs/gdb.base/corefile/corefile'. Program terminated with signal SIGABRT, Aborted. warning: Unexpected size of section `.reg/7742' in core file. #0 0x000000fff76f4e24 in raise () from /lib/loongarch64-linux-gnu/libc.so.6 (gdb) FAIL: gdb.base/corefile.exp: core-file warning-free Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-05-23Fix loongarch_iterate_over_regset_sections for non-native targets.John Baldwin1-2/+12
Define a constant for the number of registers stored in a register set and use this with register_size to compute the size of the general-purpose register set in core dumps. This also fixes the build on hosts such as FreeBSD that do not define an elf_gregset_t type.
2022-05-23gdb: LoongArch: Implement the iterate_over_regset_sections gdbarch methodTiezhu Yang1-0/+16
When execute the following command on LoongArch: make check-gdb TESTS="gdb.base/auxv.exp" there exist the following unsupported and failed testcases: UNSUPPORTED: gdb.base/auxv.exp: gcore FAIL: gdb.base/auxv.exp: load core file for info auxv on native core dump FAIL: gdb.base/auxv.exp: info auxv on native core dump FAIL: gdb.base/auxv.exp: matching auxv data from live and core UNSUPPORTED: gdb.base/auxv.exp: info auxv on gcore-created dump UNSUPPORTED: gdb.base/auxv.exp: matching auxv data from live and gcore we can see the following messages in gdb/testsuite/gdb.log: gcore /home/loongson/build.git/gdb/testsuite/outputs/gdb.base/auxv/auxv.gcore Target does not support core file generation. (gdb) UNSUPPORTED: gdb.base/auxv.exp: gcore In order to fix the above issues, implement the iterate_over_regset_sections gdbarch method to iterate over core file register note sections on LoongArch. By the way, with this patch, the failed testcases in gdb.base/corefile.exp and gdb.base/gcore.exp can also be fixed. Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-04-06gdb: LoongArch: prepend tramp frame unwinder for signalTiezhu Yang1-0/+50
Implement the "init" method of struct tramp_frame to prepend tramp frame unwinder for signal on LoongArch. With this patch, the following failed testcases can be fixed: FAIL: gdb.base/annota1.exp: backtrace @ signal handler (timeout) FAIL: gdb.base/annota3.exp: backtrace @ signal handler (pattern 2) Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
2022-02-11gdb: LoongArch: Add initial Linux target supportTiezhu Yang1-0/+151
This commit adds initial Linux target support for LoongArch. Signed-off-by: Zhensong Liu <liuzhensong@loongson.cn> Signed-off-by: Qing zhang <zhangqing@loongson.cn> Signed-off-by: Youling Tang <tangyouling@loongson.cn> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>