aboutsummaryrefslogtreecommitdiffstats
path: root/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c')
-rw-r--r--tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c667
1 files changed, 0 insertions, 667 deletions
diff --git a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
deleted file mode 100644
index 8b29135185..0000000000
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/* Low level interface to ptrace, for the remote server for GDB.
- Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
- Free Software Foundation, Inc.
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include "server.h"
-#include "linux-low.h"
-
-#include <sys/wait.h>
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <sys/ptrace.h>
-#include <sys/user.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <xenctrl.h>
-
-#define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
-
-static xc_interface *xc_handle;
-
-static inline int
-curvcpuid()
-{
- struct process_info *process;
- if (current_inferior == NULL)
- return 0;
- process = get_thread_process(current_inferior);
- return (process->thread_known ? process->tid : 0);
-
-}
-
-struct inferior_list all_processes;
-static int current_domid;
-static int expect_signal = 0;
-static int signal_to_send = 0;
-static void linux_resume (struct thread_resume *resume_info);
-static void linux_set_inferior (void);
-
-int debug_threads;
-int using_threads;
-extern int isfile;
-
-struct pending_signals
-{
- int signal;
- struct pending_signals *prev;
-};
-
-#define PTRACE_ARG3_TYPE long
-#define PTRACE_XFER_TYPE long
-
-static int use_regsets_p = 1;
-
-
-#define pid_of(proc) ((proc)->head.id)
-
-/* FIXME: Delete eventually. */
-#define inferior_pid (pid_of (get_thread_process (current_inferior)))
-
-/* This function should only be called if the process got a SIGTRAP.
- The SIGTRAP could mean several things.
-
- On i386, where decr_pc_after_break is non-zero:
- If we were single-stepping this process using PTRACE_SINGLESTEP,
- we will get only the one SIGTRAP (even if the instruction we
- stepped over was a breakpoint). The value of $eip will be the
- next instruction.
- If we continue the process using PTRACE_CONT, we will get a
- SIGTRAP when we hit a breakpoint. The value of $eip will be
- the instruction after the breakpoint (i.e. needs to be
- decremented). If we report the SIGTRAP to GDB, we must also
- report the undecremented PC. If we cancel the SIGTRAP, we
- must resume at the decremented PC.
-
- (Presumably, not yet tested) On a non-decr_pc_after_break machine
- with hardware or kernel single-step:
- If we single-step over a breakpoint instruction, our PC will
- point at the following instruction. If we continue and hit a
- breakpoint instruction, our PC will point at the breakpoint
- instruction. */
-static CORE_ADDR
-get_stop_pc (void)
-{
- CORE_ADDR stop_pc = (*the_low_target.get_pc) ();
-
- if (get_thread_process (current_inferior)->stepping)
- return stop_pc;
- else
- return stop_pc - the_low_target.decr_pc_after_break;
-}
-
-static void *
-add_process (int pid, long tid)
-{
- struct process_info *process;
-
- process = (struct process_info *) malloc (sizeof (*process));
- memset (process, 0, sizeof (*process));
-
- process->head.id = pid;
-
- process->tid = tid;
- process->lwpid = tid;
-
- add_inferior_to_list (&all_processes, &process->head);
-
- return process;
-}
-
-/* Start an inferior process and returns its pid.
- ALLARGS is a vector of program-name and args. */
-
-static int
-linux_create_inferior (char *program, char **allargs)
-{
-
- fprintf (stderr, "Cannot exec %s: %s.\n", program,
- strerror (errno));
- fflush (stderr);
- _exit (0177);
- /* NOT REACHED */
- return -1;
-}
-
-int
-linux_attach (int domid)
-{
- struct process_info *new_process;
- current_domid = domid;
- /* this is handled for all active vcpus in PTRACE_ATTACH via the thread_create_callback */
- new_process = (struct process_info *) add_process (domid, curvcpuid());
- /* Don't ignore the initial SIGSTOP if we just attached to this process. */
- /* vcpuid == 0 */
- add_thread (0, new_process);
- new_process->stop_expected = 0;
-
- if (xc_ptrace (xc_handle, PTRACE_ATTACH, domid, 0, isfile) != 0) {
- fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domid,
- strerror (errno), errno);
- fflush (stderr);
- if (!using_threads)
- _exit (0177);
- }
-
- return 0;
-}
-
-/* Kill the inferior process. Make us have no inferior. */
-
-static void
-linux_kill_one_process (struct inferior_list_entry *entry)
-{
- struct thread_info *thread = (struct thread_info *) entry;
- struct process_info *process = get_thread_process (thread);
- xc_ptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
-}
-
-
-static void
-linux_kill (void)
-{
- for_each_inferior (&all_threads, linux_kill_one_process);
-}
-
-static void
-linux_detach_one_process (struct inferior_list_entry *entry)
-{
-
- xc_ptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
-}
-
-
-static void
-linux_detach (void)
-{
- for_each_inferior (&all_threads, linux_detach_one_process);
-}
-
-/* Return nonzero if the given thread is still alive. */
-static int
-linux_thread_alive (int tid)
-{
- if (find_inferior_id (&all_threads, tid) != NULL)
- return 1;
- else
- return 0;
-}
-
-/* Wait for process, returns status. */
-
-static unsigned char
-linux_wait (char *status)
-{
- int w;
- if (xc_waitdomain(xc_handle, current_domid, &w, 0))
- return -1;
-
- *status = 'T';
- if (expect_signal)
- return expect_signal;
- else
- return SIGTRAP;
-
-}
-
-static void
-linux_resume (struct thread_resume *resume_info)
-{
- int step = resume_info->step;
- TRACE_ENTER;
- expect_signal = resume_info->sig;
- for_each_inferior(&all_threads, regcache_invalidate_one);
- if (debug_threads)
- fprintf(stderr, "step: %d\n", step);
- xc_ptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT,
- resume_info->thread, 0, 0);
-
-}
-
-
-static int
-regsets_fetch_inferior_registers ()
-{
- struct regset_info *regset;
- TRACE_ENTER;
- regset = target_regsets;
-
- while (regset->size >= 0)
- {
- void *buf;
- int res;
-
- if (regset->size == 0)
- {
- regset ++;
- continue;
- }
-
- buf = malloc (regset->size);
- res = xc_ptrace (xc_handle, regset->get_request,
- curvcpuid(),
- 0, (PTRACE_XFER_TYPE)buf);
- if (res < 0)
- {
- if (errno == EIO)
- {
- /* If we get EIO on the first regset, do not try regsets again.
- If we get EIO on a later regset, disable that regset. */
- if (regset == target_regsets)
- {
- use_regsets_p = 0;
- return -1;
- }
- else
- {
- regset->size = 0;
- continue;
- }
- }
- else
- {
- char s[256];
- sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%d",
- inferior_pid);
- perror (s);
- }
- }
- regset->store_function (buf);
- regset ++;
- }
- return 0;
-}
-
-static int
-regsets_store_inferior_registers ()
-{
- struct regset_info *regset;
- TRACE_ENTER;
- regset = target_regsets;
-
- while (regset->size >= 0)
- {
- void *buf;
- int res;
-
- if (regset->size == 0)
- {
- regset ++;
- continue;
- }
-
- buf = malloc (regset->size);
- regset->fill_function (buf);
- res = xc_ptrace (xc_handle, regset->set_request, curvcpuid(), 0, (PTRACE_XFER_TYPE)buf);
- if (res < 0)
- {
- if (errno == EIO)
- {
- /* If we get EIO on the first regset, do not try regsets again.
- If we get EIO on a later regset, disable that regset. */
- if (regset == target_regsets)
- {
- use_regsets_p = 0;
- return -1;
- }
- else
- {
- regset->size = 0;
- continue;
- }
- }
- else
- {
-#ifdef DEBUG
- perror ("Warning: ptrace(regsets_store_inferior_registers)");
-#endif
- }
- }
- regset ++;
- free (buf);
- }
- return 0;
-}
-
-
-
-
-void
-linux_fetch_registers (int regno)
-{
- if (use_regsets_p)
- {
- if (regsets_fetch_inferior_registers () == 0)
- return;
- }
-
-}
-
-void
-linux_store_registers (int regno)
-{
- if (use_regsets_p)
- {
- if (regsets_store_inferior_registers () == 0)
- return;
- }
-}
-
-
-/* Copy LEN bytes from inferior's memory starting at MEMADDR
- to debugger memory starting at MYADDR. */
-
-static int
-linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
-{
- register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
- / sizeof (PTRACE_XFER_TYPE);
- /* Allocate buffer of that many longwords. */
- register PTRACE_XFER_TYPE *buffer
- = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
-
- TRACE_ENTER;
- /* Read all the longwords */
- for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
- {
- errno = 0;
- buffer[i] = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(), (PTRACE_ARG3_TYPE) addr, 0);
- if (errno)
- return errno;
- }
-
- /* Copy appropriate bytes out of the buffer. */
- memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
-
- return 0;
-}
-
-/* Copy LEN bytes of data from debugger memory at MYADDR
- to inferior's memory at MEMADDR.
- On failure (cannot write the inferior)
- returns the value of errno. */
-
-static int
-linux_write_memory (CORE_ADDR memaddr, const char *myaddr, int len)
-{
- register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
- /* Allocate buffer of that many longwords. */
- register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
- extern int errno;
-
- TRACE_ENTER;
-
- /* Fill start and end extra bytes of buffer with existing memory data. */
-
- buffer[0] = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
- (PTRACE_ARG3_TYPE) addr, 0);
-
- if (count > 1)
- {
- buffer[count - 1]
- = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
- (PTRACE_ARG3_TYPE) (addr + (count - 1)
- * sizeof (PTRACE_XFER_TYPE)),
- 0);
- }
-
- /* Copy data to be written over corresponding part of buffer */
-
- memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
-
- /* Write the entire buffer. */
- for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
- {
- errno = 0;
- xc_ptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(),
- (PTRACE_ARG3_TYPE) addr, buffer[i]);
- if (errno)
- return errno;
- }
-
- return 0;
-}
-
-static void
-linux_look_up_symbols (void)
-{
- if (using_threads)
- return;
-
- using_threads = thread_db_init ();
-
-}
-
-static void
-linux_send_signal (int signum)
-{
- extern int signal_pid;
-
- TRACE_ENTER;
- signal_to_send = signum;
- psignal(signum, "need to send ");
- if (cont_thread > 0)
- {
- struct process_info *process;
-
- process = get_thread_process (current_inferior);
- kill (process->lwpid, signum);
- }
- else
- kill (signal_pid, signum);
-}
-
-/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
- to debugger memory starting at MYADDR. */
-
-static int
-linux_read_auxv (CORE_ADDR offset, char *myaddr, unsigned int len)
-{
- char filename[PATH_MAX];
- int fd, n;
-
- TRACE_ENTER;
- snprintf (filename, sizeof filename, "/proc/%d/auxv", inferior_pid);
-
- fd = open (filename, O_RDONLY);
- if (fd < 0)
- return -1;
-
- if (offset != (CORE_ADDR) 0
- && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
- n = -1;
- else
- n = read (fd, myaddr, len);
-
- close (fd);
-
- return n;
-}
-
-
-static struct target_ops linux_xen_target_ops = {
- linux_create_inferior,
- linux_attach,
- linux_kill,
- linux_detach,
- linux_thread_alive,
- linux_resume,
- linux_wait,
- linux_fetch_registers,
- linux_store_registers,
- linux_read_memory,
- linux_write_memory,
- linux_look_up_symbols,
- linux_send_signal,
- linux_read_auxv,
-};
-
-static void
-linux_init_signals ()
-{
- /* FIXME drow/2002-06-09: As above, we should check with LinuxThreads
- to find what the cancel signal actually is. */
- signal (__SIGRTMIN+1, SIG_IGN);
-}
-
-void
-initialize_low (void)
-{
- using_threads = 0;
- xc_handle = xc_interface_open();
- set_target_ops (&linux_xen_target_ops);
- set_breakpoint_data (the_low_target.breakpoint,
- the_low_target.breakpoint_len);
- init_registers ();
- linux_init_signals ();
- using_threads = thread_db_init ();
-
-}
-
-
-static void
-thread_create_callback(long vcpuid)
-{
- struct thread_info *inferior;
- struct process_info *process;
-
- /* If we are attaching to our first thread, things are a little
- * different.
- */
- if (all_threads.head == all_threads.tail)
- {
- inferior = (struct thread_info *) all_threads.head;
- process = get_thread_process (inferior);
- if (process->thread_known == 0)
- {
- /* Switch to indexing the threads list by TID. */
- change_inferior_id (&all_threads, vcpuid);
- goto found;
- }
- }
- if (debug_threads)
- fprintf (stderr, "looking up thread %ld\n",
- vcpuid);
- inferior = (struct thread_info *) find_inferior_id (&all_threads,
- vcpuid);
- /* if vcpu alread registered - do nothing */
- if (inferior != NULL)
- return;
-
- if (debug_threads)
- fprintf (stderr, "Attaching to thread %ld\n",
- vcpuid);
-
- process = add_process(current_domid, vcpuid);
-
- add_thread(vcpuid, process);
- inferior = (struct thread_info *) find_inferior_id (&all_threads,
- vcpuid);
- if (inferior == NULL)
- {
- warning ("Could not attach to thread %ld\n",
- vcpuid);
- return;
- }
-
-
-found:
- if (debug_threads)
- fprintf (stderr, "notifying of new thread %ld\n",
- vcpuid);
- new_thread_notify (vcpuid);
-
- process->tid = vcpuid;
- process->lwpid = vcpuid;
-
- process->thread_known = 1;
-}
-
-static void
-thread_death_callback(long vcpuid)
-{
- if (debug_threads)
- fprintf (stderr, "Buuurp...! CPU down event.\n");
-}
-
-int
-thread_db_init(void)
-{
- debug_threads = 0;
- xc_register_event_handler(thread_create_callback, TD_CREATE);
- xc_register_event_handler(thread_death_callback, TD_DEATH);
- return 1;
-}
-
-/* XXX GAG ME */
-static int breakpoint_found;
-static void
-set_breakpoint_inferior (struct inferior_list_entry *entry)
-{
- struct thread_info *thread = (struct thread_info *) entry;
- struct thread_info *saved_inferior = current_inferior;
- CORE_ADDR eip;
- unsigned char buf[2] = {0, 0};
- current_inferior = thread;
- if (!breakpoint_found) {
- eip = get_stop_pc();
- linux_read_memory(eip, buf, 1);
- if (buf[0] == 0xcc) {
- breakpoint_found = 1;
- return;
- }
- } else if (breakpoint_found == 2) {
- if (get_thread_process (current_inferior)->stepping) {
- printf("stepping\n");
- breakpoint_found = 1;
- return;
- }
- }
- current_inferior = saved_inferior;
-
-
-}
-
-static void
-linux_set_inferior (void)
-{
- breakpoint_found = 0;
- for_each_inferior (&all_threads, set_breakpoint_inferior);
- if (!breakpoint_found) {
- breakpoint_found = 2;
- for_each_inferior (&all_threads, set_breakpoint_inferior);
- }
-}
-