18dffb485Schristos /* libthread_db helper functions for the remote server for GDB. 2*64f917f5Schristos Copyright (C) 2002-2024 Free Software Foundation, Inc. 38dffb485Schristos 48dffb485Schristos Contributed by MontaVista Software. 58dffb485Schristos 68dffb485Schristos This file is part of GDB. 78dffb485Schristos 88dffb485Schristos This program is free software; you can redistribute it and/or modify 98dffb485Schristos it under the terms of the GNU General Public License as published by 108dffb485Schristos the Free Software Foundation; either version 3 of the License, or 118dffb485Schristos (at your option) any later version. 128dffb485Schristos 138dffb485Schristos This program is distributed in the hope that it will be useful, 148dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 158dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 168dffb485Schristos GNU General Public License for more details. 178dffb485Schristos 188dffb485Schristos You should have received a copy of the GNU General Public License 198dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 208dffb485Schristos 218dffb485Schristos 228dffb485Schristos /* This file is currently tied to GNU/Linux. It should scale well to 238dffb485Schristos another libthread_db implementation, with the appropriate gdbserver 248dffb485Schristos hooks, but for now this means we can use GNU/Linux's target data. */ 258dffb485Schristos 268dffb485Schristos #include "linux-low.h" 278dffb485Schristos 288dffb485Schristos #include "gdb_proc_service.h" 298dffb485Schristos 308dffb485Schristos typedef struct ps_prochandle *gdb_ps_prochandle_t; 318dffb485Schristos typedef void *gdb_ps_read_buf_t; 328dffb485Schristos typedef const void *gdb_ps_write_buf_t; 338dffb485Schristos typedef size_t gdb_ps_size_t; 348dffb485Schristos 358dffb485Schristos #ifdef HAVE_LINUX_REGSETS 368dffb485Schristos #define HAVE_REGSETS 378dffb485Schristos #endif 388dffb485Schristos 398dffb485Schristos #ifdef HAVE_REGSETS 408dffb485Schristos static struct regset_info * 418dffb485Schristos gregset_info (void) 428dffb485Schristos { 438dffb485Schristos int i = 0; 448dffb485Schristos const regs_info *regs_info = the_linux_target->get_regs_info (); 458dffb485Schristos struct regsets_info *regsets_info = regs_info->regsets_info; 468dffb485Schristos 478dffb485Schristos while (regsets_info->regsets[i].size != -1) 488dffb485Schristos { 498dffb485Schristos if (regsets_info->regsets[i].type == GENERAL_REGS) 508dffb485Schristos break; 518dffb485Schristos i++; 528dffb485Schristos } 538dffb485Schristos 548dffb485Schristos return ®sets_info->regsets[i]; 558dffb485Schristos } 568dffb485Schristos #endif 578dffb485Schristos 588dffb485Schristos /* Search for the symbol named NAME within the object named OBJ within 598dffb485Schristos the target process PH. If the symbol is found the address of the 608dffb485Schristos symbol is stored in SYM_ADDR. */ 618dffb485Schristos 628dffb485Schristos ps_err_e 638dffb485Schristos ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj, 648dffb485Schristos const char *name, psaddr_t *sym_addr) 658dffb485Schristos { 668dffb485Schristos CORE_ADDR addr; 678dffb485Schristos 688dffb485Schristos if (thread_db_look_up_one_symbol (name, &addr) == 0) 698dffb485Schristos return PS_NOSYM; 708dffb485Schristos 718dffb485Schristos *sym_addr = (psaddr_t) (unsigned long) addr; 728dffb485Schristos return PS_OK; 738dffb485Schristos } 748dffb485Schristos 758dffb485Schristos /* Read SIZE bytes from the target process PH at address ADDR and copy 768dffb485Schristos them into BUF. */ 778dffb485Schristos 788dffb485Schristos ps_err_e 798dffb485Schristos ps_pdread (gdb_ps_prochandle_t ph, psaddr_t addr, 808dffb485Schristos gdb_ps_read_buf_t buf, gdb_ps_size_t size) 818dffb485Schristos { 828dffb485Schristos if (read_inferior_memory ((uintptr_t) addr, (gdb_byte *) buf, size) != 0) 838dffb485Schristos return PS_ERR; 848dffb485Schristos return PS_OK; 858dffb485Schristos } 868dffb485Schristos 878dffb485Schristos /* Write SIZE bytes from BUF into the target process PH at address ADDR. */ 888dffb485Schristos 898dffb485Schristos ps_err_e 908dffb485Schristos ps_pdwrite (gdb_ps_prochandle_t ph, psaddr_t addr, 918dffb485Schristos gdb_ps_write_buf_t buf, gdb_ps_size_t size) 928dffb485Schristos { 938dffb485Schristos if (target_write_memory ((uintptr_t) addr, (const gdb_byte *) buf, size) 948dffb485Schristos != 0) 958dffb485Schristos return PS_ERR; 968dffb485Schristos return PS_OK; 978dffb485Schristos } 988dffb485Schristos 998dffb485Schristos /* Get the general registers of LWP LWPID within the target process PH 1008dffb485Schristos and store them in GREGSET. */ 1018dffb485Schristos 1028dffb485Schristos ps_err_e 1038dffb485Schristos ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) 1048dffb485Schristos { 1058dffb485Schristos #ifdef HAVE_REGSETS 1068dffb485Schristos struct lwp_info *lwp; 1078dffb485Schristos struct regcache *regcache; 1088dffb485Schristos 1098dffb485Schristos lwp = find_lwp_pid (ptid_t (lwpid)); 1108dffb485Schristos if (lwp == NULL) 1118dffb485Schristos return PS_ERR; 1128dffb485Schristos 1134b169a6bSchristos scoped_restore_current_thread restore_thread; 1144b169a6bSchristos switch_to_thread (get_lwp_thread (lwp)); 1158dffb485Schristos regcache = get_thread_regcache (current_thread, 1); 1168dffb485Schristos gregset_info ()->fill_function (regcache, gregset); 1178dffb485Schristos 1188dffb485Schristos return PS_OK; 1198dffb485Schristos #else 1208dffb485Schristos return PS_ERR; 1218dffb485Schristos #endif 1228dffb485Schristos } 1238dffb485Schristos 1248dffb485Schristos /* Set the general registers of LWP LWPID within the target process PH 1258dffb485Schristos from GREGSET. */ 1268dffb485Schristos 1278dffb485Schristos ps_err_e 1288dffb485Schristos ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset) 1298dffb485Schristos { 1308dffb485Schristos /* Unneeded. */ 1318dffb485Schristos return PS_ERR; 1328dffb485Schristos } 1338dffb485Schristos 1348dffb485Schristos /* Get the floating-point registers of LWP LWPID within the target 1358dffb485Schristos process PH and store them in FPREGSET. */ 1368dffb485Schristos 1378dffb485Schristos ps_err_e 1388dffb485Schristos ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prfpregset_t *fpregset) 1398dffb485Schristos { 1408dffb485Schristos /* Unneeded. */ 1418dffb485Schristos return PS_ERR; 1428dffb485Schristos } 1438dffb485Schristos 1448dffb485Schristos /* Set the floating-point registers of LWP LWPID within the target 1458dffb485Schristos process PH from FPREGSET. */ 1468dffb485Schristos 1478dffb485Schristos ps_err_e 1488dffb485Schristos ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prfpregset_t *fpregset) 1498dffb485Schristos { 1508dffb485Schristos /* Unneeded. */ 1518dffb485Schristos return PS_ERR; 1528dffb485Schristos } 1538dffb485Schristos 1548dffb485Schristos /* Return overall process id of the target PH. Special for GNU/Linux 1558dffb485Schristos -- not used on Solaris. */ 1568dffb485Schristos 1578dffb485Schristos pid_t 1588dffb485Schristos ps_getpid (gdb_ps_prochandle_t ph) 1598dffb485Schristos { 1604b169a6bSchristos return current_process ()->pid; 1618dffb485Schristos } 162