xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/proc-service.cc (revision 64f917f5a88990e32dd65fcd4348042fa7f852b9)
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 &regsets_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