ia64/xen-unstable

view tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c @ 6427:3428d58a85e1

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Aug 25 14:41:52 2005 +0000 (2005-08-25)
parents 4abd299ef2f6 6e899a3840b2
children b54144915ae6
line source
1 /* Low level interface to ptrace, for the remote server for GDB.
2 Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include "server.h"
23 #include "linux-low.h"
25 #include <sys/wait.h>
26 #include <stdio.h>
27 #include <sys/param.h>
28 #include <sys/dir.h>
29 #include <sys/ptrace.h>
30 #include <sys/user.h>
31 #include <signal.h>
32 #include <sys/ioctl.h>
33 #include <fcntl.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <errno.h>
38 #include <xenctrl.h>
39 #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
40 long (*myptrace)(enum __ptrace_request, pid_t, long, long);
41 int (*myxcwait)(int domain, int *status, int options) ;
44 #define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */
45 #define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */
46 #define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */
47 #define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */
48 #define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */
52 struct inferior_list all_processes;
55 static int current_domain;
56 static int expect_signal = 0;
57 static int signal_to_send = 0;
58 static void linux_resume (struct thread_resume *resume_info);
60 int debug_threads;
61 int using_threads;
62 extern int isfile;
64 struct pending_signals
65 {
66 int signal;
67 struct pending_signals *prev;
68 };
70 #define PTRACE_ARG3_TYPE long
71 #define PTRACE_XFER_TYPE long
73 static int use_regsets_p = 1;
76 #define pid_of(proc) ((proc)->head.id)
78 /* FIXME: Delete eventually. */
79 #define inferior_pid (pid_of (get_thread_process (current_inferior)))
81 /* This function should only be called if the process got a SIGTRAP.
82 The SIGTRAP could mean several things.
84 On i386, where decr_pc_after_break is non-zero:
85 If we were single-stepping this process using PTRACE_SINGLESTEP,
86 we will get only the one SIGTRAP (even if the instruction we
87 stepped over was a breakpoint). The value of $eip will be the
88 next instruction.
89 If we continue the process using PTRACE_CONT, we will get a
90 SIGTRAP when we hit a breakpoint. The value of $eip will be
91 the instruction after the breakpoint (i.e. needs to be
92 decremented). If we report the SIGTRAP to GDB, we must also
93 report the undecremented PC. If we cancel the SIGTRAP, we
94 must resume at the decremented PC.
96 (Presumably, not yet tested) On a non-decr_pc_after_break machine
97 with hardware or kernel single-step:
98 If we single-step over a breakpoint instruction, our PC will
99 point at the following instruction. If we continue and hit a
100 breakpoint instruction, our PC will point at the breakpoint
101 instruction. */
102 #if 0
103 static CORE_ADDR
104 get_stop_pc (void)
105 {
106 CORE_ADDR stop_pc = (*the_low_target.get_pc) ();
108 if (get_thread_process (current_inferior)->stepping)
109 return stop_pc;
110 else
111 return stop_pc - the_low_target.decr_pc_after_break;
112 }
113 #endif
114 static void *
115 add_process (int pid)
116 {
117 struct process_info *process;
119 process = (struct process_info *) malloc (sizeof (*process));
120 memset (process, 0, sizeof (*process));
122 process->head.id = pid;
124 /* Default to tid == lwpid == pid. */
125 process->tid = pid;
126 process->lwpid = pid;
128 add_inferior_to_list (&all_processes, &process->head);
130 return process;
131 }
133 /* Start an inferior process and returns its pid.
134 ALLARGS is a vector of program-name and args. */
136 static int
137 linux_create_inferior (char *program, char **allargs)
138 {
140 fprintf (stderr, "Cannot exec %s: %s.\n", program,
141 strerror (errno));
142 fflush (stderr);
143 _exit (0177);
144 /* NOT REACHED */
145 return -1;
146 }
148 int
149 linux_attach (int domain)
150 {
151 struct process_info *new_process;
152 current_domain = domain;
153 if (myptrace (PTRACE_ATTACH, domain, 0, 0) != 0) {
154 fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domain,
155 strerror (errno), errno);
156 fflush (stderr);
157 _exit (0177);
158 }
160 new_process = (struct process_info *) add_process (domain);
161 add_thread (domain, new_process);
163 /* Don't ignore the initial SIGSTOP if we just attached to this process. */
164 new_process->stop_expected = 0;
166 return 0;
167 }
169 /* Kill the inferior process. Make us have no inferior. */
171 static void
172 linux_kill_one_process (struct inferior_list_entry *entry)
173 {
174 struct thread_info *thread = (struct thread_info *) entry;
175 struct process_info *process = get_thread_process (thread);
176 myptrace (PTRACE_KILL, pid_of (process), 0, 0);
178 }
180 static void
181 linux_kill (void)
182 {
183 for_each_inferior (&all_threads, linux_kill_one_process);
184 }
187 static void
188 linux_detach_one_process (struct inferior_list_entry *entry)
189 {
190 struct thread_info *thread = (struct thread_info *) entry;
191 struct process_info *process = get_thread_process (thread);
193 myptrace (PTRACE_DETACH, pid_of (process), 0, 0);
194 }
197 static void
198 linux_detach (void)
199 {
200 for_each_inferior (&all_threads, linux_detach_one_process);
201 }
203 /* Return nonzero if the given thread is still alive. */
204 static int
205 linux_thread_alive (int tid)
206 {
207 if (find_inferior_id (&all_threads, tid) != NULL)
208 return 1;
209 else
210 return 0;
211 }
213 /* Wait for process, returns status. */
215 static unsigned char
216 linux_wait (char *status)
217 {
218 int w;
219 if (myxcwait(current_domain, &w, 0))
220 return -1;
222 if (w & (DOMFLAGS_SHUTDOWN|DOMFLAGS_DYING)) {
223 *status = 'W';
224 return 0;
225 }
228 *status = 'T';
229 if (expect_signal)
230 return expect_signal;
231 else
232 return SIGTRAP;
234 }
236 static void
237 linux_resume (struct thread_resume *resume_info)
238 {
239 int step = resume_info->step;
240 TRACE_ENTER;
241 expect_signal = resume_info->sig;
242 for_each_inferior(&all_threads, regcache_invalidate_one);
244 myptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, current_domain, 0, 0);
246 }
249 static int
250 regsets_fetch_inferior_registers ()
251 {
252 struct regset_info *regset;
253 TRACE_ENTER;
254 regset = target_regsets;
256 while (regset->size >= 0)
257 {
258 void *buf;
259 int res;
261 if (regset->size == 0)
262 {
263 regset ++;
264 continue;
265 }
267 buf = malloc (regset->size);
268 res = myptrace (regset->get_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf);
269 if (res < 0)
270 {
271 if (errno == EIO)
272 {
273 /* If we get EIO on the first regset, do not try regsets again.
274 If we get EIO on a later regset, disable that regset. */
275 if (regset == target_regsets)
276 {
277 use_regsets_p = 0;
278 return -1;
279 }
280 else
281 {
282 regset->size = 0;
283 continue;
284 }
285 }
286 else
287 {
288 char s[256];
289 sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%d",
290 inferior_pid);
291 perror (s);
292 }
293 }
294 regset->store_function (buf);
295 regset ++;
296 }
297 return 0;
298 }
300 static int
301 regsets_store_inferior_registers ()
302 {
303 struct regset_info *regset;
304 TRACE_ENTER;
305 regset = target_regsets;
307 while (regset->size >= 0)
308 {
309 void *buf;
310 int res;
312 if (regset->size == 0)
313 {
314 regset ++;
315 continue;
316 }
318 buf = malloc (regset->size);
319 regset->fill_function (buf);
320 res = myptrace (regset->set_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf);
321 if (res < 0)
322 {
323 if (errno == EIO)
324 {
325 /* If we get EIO on the first regset, do not try regsets again.
326 If we get EIO on a later regset, disable that regset. */
327 if (regset == target_regsets)
328 {
329 use_regsets_p = 0;
330 return -1;
331 }
332 else
333 {
334 regset->size = 0;
335 continue;
336 }
337 }
338 else
339 {
340 #ifdef DEBUG
341 perror ("Warning: ptrace(regsets_store_inferior_registers)");
342 #endif
343 }
344 }
345 regset ++;
346 free (buf);
347 }
348 return 0;
349 }
354 void
355 linux_fetch_registers (int regno)
356 {
357 if (use_regsets_p)
358 {
359 if (regsets_fetch_inferior_registers () == 0)
360 return;
361 }
363 }
365 void
366 linux_store_registers (int regno)
367 {
368 if (use_regsets_p)
369 {
370 if (regsets_store_inferior_registers () == 0)
371 return;
372 }
373 }
376 /* Copy LEN bytes from inferior's memory starting at MEMADDR
377 to debugger memory starting at MYADDR. */
379 static int
380 linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
381 {
382 register int i;
383 /* Round starting address down to longword boundary. */
384 register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
385 /* Round ending address up; get number of longwords that makes. */
386 register int count
387 = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
388 / sizeof (PTRACE_XFER_TYPE);
389 /* Allocate buffer of that many longwords. */
390 register PTRACE_XFER_TYPE *buffer
391 = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
393 TRACE_ENTER;
394 /* Read all the longwords */
395 for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
396 {
397 errno = 0;
398 buffer[i] = myptrace (PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
399 if (errno)
400 return errno;
401 }
403 /* Copy appropriate bytes out of the buffer. */
404 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
406 return 0;
407 }
409 /* Copy LEN bytes of data from debugger memory at MYADDR
410 to inferior's memory at MEMADDR.
411 On failure (cannot write the inferior)
412 returns the value of errno. */
414 static int
415 linux_write_memory (CORE_ADDR memaddr, const char *myaddr, int len)
416 {
417 register int i;
418 /* Round starting address down to longword boundary. */
419 register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
420 /* Round ending address up; get number of longwords that makes. */
421 register int count
422 = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
423 /* Allocate buffer of that many longwords. */
424 register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
425 extern int errno;
427 TRACE_ENTER;
429 /* Fill start and end extra bytes of buffer with existing memory data. */
431 buffer[0] = myptrace (PTRACE_PEEKTEXT, inferior_pid,
432 (PTRACE_ARG3_TYPE) addr, 0);
434 if (count > 1)
435 {
436 buffer[count - 1]
437 = myptrace (PTRACE_PEEKTEXT, inferior_pid,
438 (PTRACE_ARG3_TYPE) (addr + (count - 1)
439 * sizeof (PTRACE_XFER_TYPE)),
440 0);
441 }
443 /* Copy data to be written over corresponding part of buffer */
445 memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
447 /* Write the entire buffer. */
448 for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
449 {
450 errno = 0;
451 myptrace (PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
452 if (errno)
453 return errno;
454 }
456 return 0;
457 }
459 static void
460 linux_look_up_symbols (void)
461 {
462 #if 0
463 using_threads = thread_db_init ();
464 #endif
465 }
467 static void
468 linux_send_signal (int signum)
469 {
470 extern int signal_pid;
472 TRACE_ENTER;
473 signal_to_send = signum;
474 psignal(signum, "need to send ");
475 if (cont_thread > 0)
476 {
477 struct process_info *process;
479 process = get_thread_process (current_inferior);
480 kill (process->lwpid, signum);
481 }
482 else
483 kill (signal_pid, signum);
484 }
486 /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
487 to debugger memory starting at MYADDR. */
489 static int
490 linux_read_auxv (CORE_ADDR offset, char *myaddr, unsigned int len)
491 {
492 char filename[PATH_MAX];
493 int fd, n;
495 TRACE_ENTER;
496 snprintf (filename, sizeof filename, "/proc/%d/auxv", inferior_pid);
498 fd = open (filename, O_RDONLY);
499 if (fd < 0)
500 return -1;
502 if (offset != (CORE_ADDR) 0
503 && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
504 n = -1;
505 else
506 n = read (fd, myaddr, len);
508 close (fd);
510 return n;
511 }
514 static struct target_ops linux_xen_target_ops = {
515 linux_create_inferior,
516 linux_attach,
517 linux_kill,
518 linux_detach,
519 linux_thread_alive,
520 linux_resume,
521 linux_wait,
522 linux_fetch_registers,
523 linux_store_registers,
524 linux_read_memory,
525 linux_write_memory,
526 linux_look_up_symbols,
527 linux_send_signal,
528 linux_read_auxv,
529 };
531 static void
532 linux_init_signals ()
533 {
534 /* FIXME drow/2002-06-09: As above, we should check with LinuxThreads
535 to find what the cancel signal actually is. */
536 signal (__SIGRTMIN+1, SIG_IGN);
537 }
539 void
540 initialize_low (void)
541 {
543 set_target_ops (&linux_xen_target_ops);
544 set_breakpoint_data (the_low_target.breakpoint,
545 the_low_target.breakpoint_len);
546 init_registers ();
547 linux_init_signals ();
548 if (isfile) {
549 myptrace = xc_ptrace_core;
550 myxcwait = xc_waitdomain_core;
551 } else {
552 myptrace = xc_ptrace;
553 myxcwait = xc_waitdomain;
554 }
556 }