From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3328 invoked by alias); 18 Dec 2002 20:31:28 -0000 Mailing-List: contact rda-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: rda-owner@sources.redhat.com Received: (qmail 3260 invoked from network); 18 Dec 2002 20:31:24 -0000 Date: Wed, 18 Dec 2002 12:31:00 -0000 From: Kevin Buettner Message-Id: <1021218203105.ZM8191@localhost.localdomain> X-Mailer: Z-Mail (4.0.1 13Jan97 Caldera) To: rda@sources.redhat.com Subject: [PATCH] unix/ptrace-target.[ch] changes MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-q4/txt/msg00013.txt.bz2 The patch below mostly improves the ability to watch what ptrace() is doing. There are also some changes which handle the case in which sizeof (ptrace_xfer_type) != sizeof (long). Committed. * ptrace-target.h, ptrace-target.c (ptrace_write_user) (ptrace_read_user): Add struct gdbserv argument. * linux-target.c: Fix all callers (and callers of callers). * ptrace-target.c (ptrace_write_user, ptrace_read_user): Add debugging printf()s. (ptrace_xfer_mem): Fix debugging printf()s so that they'll print useful results when sizeof (long long) is the same as sizeof (ptrace_xfer_type). (ptrace_xfer_mem): Decode address using gdbserv_host_bytes_from_reg() instead of gdbserv_reg_to_ulong(). Index: linux-target.c =================================================================== RCS file: /cvs/src/src/rda/unix/linux-target.c,v retrieving revision 1.2 diff -u -p -r1.2 linux-target.c --- linux-target.c 3 Dec 2002 03:22:07 -0000 1.2 +++ linux-target.c 18 Dec 2002 20:22:34 -0000 @@ -982,7 +982,7 @@ is_extended_reg (int regnum) Returns 0 for success, -1 for failure. */ static int -read_reg_bytes (int pid, int regno, void *reg_bytes) +read_reg_bytes (struct gdbserv *serv, int pid, int regno, void *reg_bytes) { ptrace_arg3_type regaddr; int regsize; @@ -993,7 +993,7 @@ read_reg_bytes (int pid, int regno, void regaddr = reginfo[regno].ptrace_offset; regsize = reginfo[regno].ptrace_size; - status = ptrace_read_user (pid, regaddr, regsize, reg_bytes); + status = ptrace_read_user (serv, pid, regaddr, regsize, reg_bytes); /* A non-zero status is the errno value from the ptrace call */ if (status != 0) @@ -1011,7 +1011,8 @@ read_reg_bytes (int pid, int regno, void Returns 0 for success, -1 for failure. */ static int -write_reg_bytes (int pid, int regno, const void *reg_bytes) +write_reg_bytes (struct gdbserv *serv, int pid, int regno, + const void *reg_bytes) { ptrace_arg3_type regaddr; int regsize; @@ -1022,7 +1023,7 @@ write_reg_bytes (int pid, int regno, con regaddr = reginfo[regno].ptrace_offset; regsize = reginfo[regno].ptrace_size; - status = ptrace_write_user (pid, regaddr, regsize, reg_bytes); + status = ptrace_write_user (serv, pid, regaddr, regsize, reg_bytes); /* A non-zero status is the errno value from the ptrace call */ if (status != 0) @@ -1038,11 +1039,11 @@ write_reg_bytes (int pid, int regno, con /* Fetch and return the value of register REGNO. Helper function for debug_get_pc(). This is the PEEKUSER_POKEUSER_REGINFO version. */ static unsigned long -debug_get_reg (pid_t pid, int regno) +debug_get_reg (struct gdbserv *serv, pid_t pid, int regno) { ptrace_xfer_type value; - if (read_reg_bytes (pid, regno, &value) < 0) + if (read_reg_bytes (serv, pid, regno, &value) < 0) return 0; else return (unsigned long) value; @@ -1052,7 +1053,7 @@ debug_get_reg (pid_t pid, int regno) unsigned long debug_get_pc (struct gdbserv *serv, pid_t pid) { - return debug_get_reg (pid, PC_REGNUM); + return debug_get_reg (serv, pid, PC_REGNUM); } /* Function: get_reg @@ -1076,7 +1077,7 @@ linux_get_reg (struct gdbserv *serv, int if (reginfo[regno].whichregs != NOREGS) { /* Get the register value. */ - status = read_reg_bytes (process->pid, regno, tmp_buf); + status = read_reg_bytes (serv, process->pid, regno, tmp_buf); if (status < 0) return -1; /* fail */ } @@ -1116,7 +1117,7 @@ linux_set_reg (struct gdbserv *serv, int reg, sign_extend); /* Write the child's register. */ - status = write_reg_bytes (process->pid, regno, tmp_buf); + status = write_reg_bytes (serv, process->pid, regno, tmp_buf); if (status < 0) return -1; /* Fail */ } @@ -1273,7 +1274,7 @@ get_regset (struct gdbserv *serv, int pi int status; /* Get the register value. */ - status = read_reg_bytes (pid, regno, tmp_buf); + status = read_reg_bytes (serv, pid, regno, tmp_buf); if (status < 0) return -1; /* fail */ @@ -1318,7 +1319,7 @@ put_regset (struct gdbserv *serv, sign_extend); /* Write the child's register. */ - status = write_reg_bytes (pid, regno, tmp_buf); + status = write_reg_bytes (serv, pid, regno, tmp_buf); if (status < 0) return -1; /* Fail */ } @@ -1899,7 +1900,8 @@ enum { U_REGS_OFFSET = 0 }; /* FIXME??? Return -1 for failure, zero for success. */ static int -linux_read_reg (int pid, int regno, ptrace_xfer_type *regval) +linux_read_reg (struct gdbserv *serv, int pid, int regno, + ptrace_xfer_type *regval) { unsigned long u_regs_base = U_REGS_OFFSET; ptrace_arg3_type regaddr; @@ -1909,7 +1911,7 @@ linux_read_reg (int pid, int regno, ptra regaddr += U_REGS_OFFSET; errno = 0; - ptrace_read_user (pid, regaddr, sizeof (*regval), regval); + ptrace_read_user (serv, pid, regaddr, sizeof (*regval), regval); if (errno) { @@ -1925,17 +1927,18 @@ linux_read_reg (int pid, int regno, ptra Return -1 for failure, zero for success. */ static int -linux_write_reg (int pid, int regno, ptrace_xfer_type regval) +linux_write_reg (struct gdbserv *serv, int regno, ptrace_xfer_type regval) { unsigned long u_regs_base = U_REGS_OFFSET; ptrace_arg3_type regaddr; + struct child_process *process = gdbserv_target_data (serv); if ((regaddr = linux_register_offset (regno)) < 0) return -1; /* fail */ regaddr += U_REGS_OFFSET; errno = 0; - ptrace_write_user (pid, regaddr, sizeof (regval), ®val); + ptrace_write_user (serv, process->pid, regaddr, sizeof (regval), ®val); if (errno) { fprintf (stderr, "PT_WRITE_U 0x%08lx from 0x%08lx in process %d\n", @@ -1949,11 +1952,11 @@ linux_write_reg (int pid, int regno, ptr /* Helper function for debug_get_pc(). It fetches and returns the value of REGNO. */ static unsigned long -debug_get_reg (pid_t pid, int regno) +debug_get_reg (struct gdbserv *serv, pid_t pid, int regno) { ptrace_xfer_type value; - if (linux_read_reg (pid, regno, &value) < 0) + if (linux_read_reg (serv, pid, regno, &value) < 0) return 0; else return (unsigned long) value; @@ -1963,7 +1966,7 @@ debug_get_reg (pid_t pid, int regno) unsigned long debug_get_pc (struct gdbserv *serv, pid_t pid) { - return debug_get_reg (pid, PC_REGNUM); + return debug_get_reg (serv, pid, PC_REGNUM); } /* Function: reg_format @@ -2013,7 +2016,7 @@ linux_get_reg (struct gdbserv *serv, int ptrace_xfer_type regval; /* Get the register value. */ - if (linux_read_reg (process->pid, regno, ®val) < 0) + if (linux_read_reg (serv, process->pid, regno, ®val) < 0) { fprintf (stderr, "Error: linux_get_reg: Register %d out of bounds.\n", regno); return -1; @@ -2039,7 +2042,6 @@ linux_get_reg (struct gdbserv *serv, int static int linux_set_reg (struct gdbserv *serv, int regno, struct gdbserv_reg *reg) { - struct child_process *process = gdbserv_target_data (serv); ptrace_xfer_type regval; if (regno < 0 || regno >= NUM_REGS) @@ -2055,7 +2057,7 @@ linux_set_reg (struct gdbserv *serv, int gdbserv_reg_to_ulonglong (serv, reg, (unsigned long long *) ®val); /* Write the child's register. */ - if (linux_write_reg (process->pid, regno, regval) < 0) + if (linux_write_reg (serv, regno, regval) < 0) return -1; /* Fail */ return 0; /* success */ @@ -2187,7 +2189,8 @@ reg_to_xregset (struct gdbserv *serv, static int get_gregset (struct gdbserv *serv, int pid, GREGSET_T gregset) { - if (ptrace_read_user (pid, 0, sizeof (GREGSET_T), (char *) gregset) != 0) + if (ptrace_read_user (serv, pid, 0, sizeof (GREGSET_T), (char *) gregset) + != 0) return -1; return 0; } @@ -2199,7 +2202,7 @@ get_gregset (struct gdbserv *serv, int p static int put_gregset (struct gdbserv *serv, int pid, const GREGSET_T gregset) { - if (ptrace_write_user (pid, 0, sizeof (GREGSET_T), + if (ptrace_write_user (serv, pid, 0, sizeof (GREGSET_T), (char *) gregset) != 0) return -1; return 0; @@ -2495,7 +2498,7 @@ mips_get_reg(struct gdbserv *serv, int r struct child_process *process = gdbserv_target_data (serv); pid_t pid = process->pid; - if (read_reg_bytes (pid, regno, &value) < 0) + if (read_reg_bytes (serv, pid, regno, &value) < 0) return 0; else return value; Index: ptrace-target.c =================================================================== RCS file: /cvs/src/src/rda/unix/ptrace-target.c,v retrieving revision 1.2 diff -u -p -r1.2 ptrace-target.c --- ptrace-target.c 19 Nov 2002 22:24:31 -0000 1.2 +++ ptrace-target.c 18 Dec 2002 20:22:34 -0000 @@ -183,11 +183,13 @@ ptrace_kill_program (struct child_proces */ extern int -ptrace_read_user (int pid, +ptrace_read_user (struct gdbserv *serv, + int pid, ptrace_arg3_type addr, int len, void *buff) { + struct child_process *process = gdbserv_target_data (serv); int i; /* Require: addr is on the proper boundary, and @@ -199,6 +201,12 @@ ptrace_read_user (int pid, errno = 0; *(ptrace_xfer_type *) &((char *)buff)[i] = ptrace (PTRACE_PEEKUSER, pid, addr + i, 0); +#if 0 /* too noisy! */ + if (process->debug_backend) + fprintf (stderr, "PTRACE_PEEKUSER 0x%08llx in %d, 0x%08llx\n", + (long long) addr + i, pid, + (long long) * (ptrace_xfer_type *) &((char *)buff)[i]); +#endif if (errno != 0) return errno; } @@ -211,11 +219,13 @@ ptrace_read_user (int pid, */ extern int -ptrace_write_user (int pid, +ptrace_write_user (struct gdbserv *serv, + int pid, ptrace_arg3_type addr, int len, const void *buff) { + struct child_process *process = gdbserv_target_data (serv); int i; /* Require: addr is on the proper boundary, and @@ -231,6 +241,10 @@ ptrace_write_user (int pid, errno = 0; ptrace (PTRACE_POKEUSER, pid, addr + i, * (ptrace_xfer_type *) &((char *)buff)[i]); + if (process->debug_backend) + fprintf (stderr, "PTRACE_POKEUSER 0x%08llx in %d, 0x%08llx\n", + (long long) addr + i, pid, + (long long) * (ptrace_xfer_type *) &((char *)buff)[i]); #if defined(_MIPSEL) || defined(MIPS_LINUX_TARGET) /* mips linux kernel 2.4 has a bug where PTRACE_POKEUSER returns -ESRCH even when it succeeds */ @@ -956,12 +970,14 @@ ptrace_xfer_mem (struct gdbserv *serv, int i; /* Get request address. */ - gdbserv_reg_to_ulong (serv, addr, &request_base); + gdbserv_host_bytes_from_reg (serv, &request_base, sizeof (request_base), + addr, 0); /* Round down to a PTRACE word boundary. */ xfer_base = request_base & - PTRACE_XFER_SIZE; /* Round length up to a PTRACE word boundary. */ xfer_count = (((request_base + len) - xfer_base) + PTRACE_XFER_SIZE - 1) / PTRACE_XFER_SIZE; + /* Allocate space for xfer. */ buf = (ptrace_xfer_type *) alloca (xfer_count * PTRACE_XFER_SIZE); @@ -976,8 +992,8 @@ ptrace_xfer_mem (struct gdbserv *serv, buf[i] = ptrace (PTRACE_PEEKTEXT, process->pid, temp_addr, 0L); if (process->debug_backend) - fprintf (stderr, "PTRACE_PEEKTEXT-1 0x%08lx in %d, 0x%08lx\n", - (long) temp_addr, process->pid, (long) buf[i]); + fprintf (stderr, "PTRACE_PEEKTEXT-1 0x%08llx in %d, 0x%08llx\n", + (long long) temp_addr, process->pid, (long long) buf[i]); if (errno) { if (errno != EIO) @@ -1004,15 +1020,15 @@ ptrace_xfer_mem (struct gdbserv *serv, buf[0] = ptrace (PTRACE_PEEKTEXT, process->pid, xfer_base, 0L); if (process->debug_backend) - fprintf (stderr, "PTRACE_PEEKTEXT-2 0x%08lx in %d, 0x%08lx\n", - (long) xfer_base, process->pid, (long) buf[0]); + fprintf (stderr, "PTRACE_PEEKTEXT-2 0x%08llx in %d, 0x%08llx\n", + (long long) xfer_base, process->pid, (long long) buf[0]); if (errno) { if (errno != EIO) fprintf (stderr, - "xfer_mem(2): ptrace error at 0x%08lx in %d: %s\n", - (long) xfer_base, process->pid, strerror (errno)); + "xfer_mem(2): ptrace error at 0x%08llx in %d: %s\n", + (long long) xfer_base, process->pid, strerror (errno)); return -1; } } @@ -1025,9 +1041,9 @@ ptrace_xfer_mem (struct gdbserv *serv, buf[xfer_count - 1] = ptrace (PTRACE_PEEKTEXT, process->pid, temp_addr, 0L); if (process->debug_backend) - fprintf (stderr, "PTRACE_PEEKTEXT-3 0x%08lx in %d, 0x%08lx\n", - (long) temp_addr, process->pid, - (long) buf[xfer_count - 1]); + fprintf (stderr, "PTRACE_PEEKTEXT-3 0x%08llx in %d, 0x%08llx\n", + (long long) temp_addr, process->pid, + (long long) buf[xfer_count - 1]); if (errno) { @@ -1050,15 +1066,15 @@ ptrace_xfer_mem (struct gdbserv *serv, ptrace (PTRACE_POKETEXT, process->pid, temp_addr, buf[i]); if (process->debug_backend) - fprintf (stderr, "PTRACE_POKETEXT 0x%08lx in %d, 0x%08lx\n", - (long) temp_addr, process->pid, (long) buf[i]); + fprintf (stderr, "PTRACE_POKETEXT 0x%08llx in %d, 0x%08llx\n", + (long long) temp_addr, process->pid, (long long) buf[i]); if (errno) { if (errno != EIO) fprintf (stderr, - "xfer_mem(4): ptrace error at 0x%08lx in %d: %s\n", - (long) temp_addr, process->pid, strerror (errno)); + "xfer_mem(4): ptrace error at 0x%08llx in %d: %s\n", + (long long) temp_addr, process->pid, strerror (errno)); return -1; } } Index: ptrace-target.h =================================================================== RCS file: /cvs/src/src/rda/unix/ptrace-target.h,v retrieving revision 1.1 diff -u -p -r1.1 ptrace-target.h --- ptrace-target.h 28 Aug 2002 01:22:28 -0000 1.1 +++ ptrace-target.h 18 Dec 2002 20:22:34 -0000 @@ -67,8 +67,10 @@ typedef long ptrace_arg4_type; typedef long long ptrace_arg4_type; #endif -int ptrace_write_user (int, ptrace_arg3_type, int, const void *); -int ptrace_read_user (int, ptrace_arg3_type, int, void *); +int ptrace_write_user (struct gdbserv *serv, int pid, ptrace_arg3_type addr, + int len, const void *buff); +int ptrace_read_user (struct gdbserv *serv, int pid, ptrace_arg3_type addr, + int len, void *buff); int ptrace_get_gregs (struct gdbserv *serv, int alt_pid, void *buff); int ptrace_set_gregs (struct gdbserv *serv, int alt_pid, const void *buff); int ptrace_get_fpregs (struct gdbserv *serv, int alt_pid, void *buff);