* x86-64-linux-nat.c (child_resume, child_xfer_memory): Delete.
(PTRACE_XFER_TYPE): Moved to config/i386/nm-x86-64.h. (kernel_u_size): Added. * config/i386/nm-x86-64.h (CHILD_XFER_MEMORY, CHILD_RESUME): Delete. (PTRACE_XFER_TYPE): Moved here from config/i386/nm-x86-64.h.
This commit is contained in:
parent
aa45f76d84
commit
8cfda98c96
|
@ -1,3 +1,11 @@
|
|||
2002-04-10 Michal Ludvig <mludvig@suse.cz>
|
||||
|
||||
* x86-64-linux-nat.c (child_resume, child_xfer_memory): Delete.
|
||||
(PTRACE_XFER_TYPE): Moved to config/i386/nm-x86-64.h.
|
||||
(kernel_u_size): Added.
|
||||
* config/i386/nm-x86-64.h (CHILD_XFER_MEMORY, CHILD_RESUME): Delete.
|
||||
(PTRACE_XFER_TYPE): Moved here from config/i386/nm-x86-64.h.
|
||||
|
||||
2002-04-04 Jim Ingham <jingham@apple.com>
|
||||
|
||||
* valarith.c (find_size_for_pointer_math): New function, either returns
|
||||
|
|
|
@ -65,10 +65,8 @@ extern int kernel_u_size (void);
|
|||
to get the offset in the core file of the register values. */
|
||||
#define KERNEL_U_ADDR 0x0
|
||||
|
||||
/* FIXME use special child_xfer_memory. */
|
||||
#define CHILD_XFER_MEMORY
|
||||
|
||||
#define PTRACE_ARG3_TYPE void*
|
||||
#define PTRACE_XFER_TYPE unsigned long
|
||||
|
||||
|
||||
/* We define this if link.h is available, because with ELF we use SVR4 style
|
||||
|
@ -82,9 +80,6 @@ extern int kernel_u_size (void);
|
|||
/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
|
||||
#define FETCH_INFERIOR_REGISTERS
|
||||
|
||||
/* Override child_resume in `infptrace.c'. */
|
||||
#define CHILD_RESUME
|
||||
|
||||
#undef PREPARE_TO_PROCEED
|
||||
|
||||
#include <signal.h>
|
||||
|
|
|
@ -128,8 +128,6 @@ x86_64_linux_dr_get_status (void)
|
|||
(0 <= (regno) && (regno) < x86_64_num_gregs)
|
||||
#define GETFPREGS_SUPPLIES(regno) \
|
||||
(FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
|
||||
|
||||
#define PTRACE_XFER_TYPE unsigned long
|
||||
|
||||
|
||||
/* Transfering the general-purpose registers between GDB, inferiors
|
||||
|
@ -344,164 +342,7 @@ static const unsigned char linux_syscall[] = { 0x0f, 0x05 };
|
|||
/* Offset to saved processor registers from <asm/ucontext.h> */
|
||||
#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36)
|
||||
|
||||
/* Resume execution of the inferior process.
|
||||
If STEP is nonzero, single-step it.
|
||||
If SIGNAL is nonzero, give it that signal. */
|
||||
|
||||
void
|
||||
child_resume (ptid_t ptid, int step, enum target_signal signal)
|
||||
{
|
||||
int pid = PIDGET (ptid);
|
||||
int request = PTRACE_CONT;
|
||||
|
||||
if (pid == -1)
|
||||
/* Resume all threads. */
|
||||
/* I think this only gets used in the non-threaded case, where "resume
|
||||
all threads" and "resume inferior_ptid" are the same. */
|
||||
pid = PIDGET (inferior_ptid);
|
||||
|
||||
if (step)
|
||||
{
|
||||
CORE_ADDR pc = read_pc_pid (pid_to_ptid (pid));
|
||||
unsigned char buf[LINUX_SYSCALL_LEN];
|
||||
|
||||
request = PTRACE_SINGLESTEP;
|
||||
|
||||
/* Returning from a signal trampoline is done by calling a
|
||||
special system call (sigreturn or rt_sigreturn, see
|
||||
i386-linux-tdep.c for more information). This system call
|
||||
restores the registers that were saved when the signal was
|
||||
raised, including %eflags. That means that single-stepping
|
||||
won't work. Instead, we'll have to modify the signal context
|
||||
that's about to be restored, and set the trace flag there. */
|
||||
|
||||
/* First check if PC is at a system call. */
|
||||
if (read_memory_nobpt (pc, (char *) buf, LINUX_SYSCALL_LEN) == 0
|
||||
&& memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0)
|
||||
{
|
||||
int syscall =
|
||||
read_register_pid (LINUX_SYSCALL_REGNUM, pid_to_ptid (pid));
|
||||
|
||||
/* Then check the system call number. */
|
||||
if (syscall == SYS_rt_sigreturn)
|
||||
{
|
||||
CORE_ADDR sp = read_register (SP_REGNUM);
|
||||
CORE_ADDR addr = sp;
|
||||
unsigned long int eflags;
|
||||
|
||||
addr +=
|
||||
sizeof (struct siginfo) + LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
|
||||
|
||||
/* Set the trace flag in the context that's about to be
|
||||
restored. */
|
||||
addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET;
|
||||
read_memory (addr, (char *) &eflags, 8);
|
||||
eflags |= 0x0100;
|
||||
write_memory (addr, (char *) &eflags, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ptrace (request, pid, 0, target_signal_to_host (signal)) == -1)
|
||||
perror_with_name ("ptrace");
|
||||
}
|
||||
|
||||
|
||||
/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
|
||||
to debugger memory starting at MYADDR. Copy to inferior if
|
||||
WRITE is nonzero. TARGET is ignored.
|
||||
|
||||
Returns the length copied, which is either the LEN argument or zero.
|
||||
This xfer function does not do partial moves, since child_ops
|
||||
doesn't allow memory operations to cross below us in the target stack
|
||||
anyway. */
|
||||
|
||||
int
|
||||
child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
|
||||
struct mem_attrib *attrib, struct target_ops *target)
|
||||
{
|
||||
register int i;
|
||||
/* Round starting address down to longword boundary. */
|
||||
register CORE_ADDR addr = memaddr & -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. */
|
||||
/* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
|
||||
because it uses alloca to allocate a buffer of arbitrary size.
|
||||
For very large xfers, this could crash GDB's stack. */
|
||||
register PTRACE_XFER_TYPE *buffer
|
||||
= (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
|
||||
|
||||
if (write)
|
||||
{
|
||||
/* Fill start and end extra bytes of buffer with existing memory data. */
|
||||
if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE))
|
||||
{
|
||||
/* Need part of initial word -- fetch it. */
|
||||
buffer[0] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) addr, 0);
|
||||
}
|
||||
|
||||
if (count > 1) /* FIXME, avoid if even boundary */
|
||||
{
|
||||
buffer[count - 1] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
|
||||
((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;
|
||||
ptrace (PT_WRITE_D, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) addr, buffer[i]);
|
||||
if (errno)
|
||||
{
|
||||
/* Using the appropriate one (I or D) is necessary for
|
||||
Gould NP1, at least. */
|
||||
errno = 0;
|
||||
ptrace (PT_WRITE_I, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) addr, buffer[i]);
|
||||
}
|
||||
if (errno)
|
||||
return 0;
|
||||
}
|
||||
#ifdef CLEAR_INSN_CACHE
|
||||
CLEAR_INSN_CACHE ();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read all the longwords */
|
||||
for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
|
||||
{
|
||||
errno = 0;
|
||||
buffer[i] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) addr, 0);
|
||||
if (errno)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy appropriate bytes out of the buffer. */
|
||||
memcpy (myaddr,
|
||||
(char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
|
||||
len);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Interpreting register set info found in core files. */
|
||||
|
||||
/* Provide registers to GDB from a core file.
|
||||
|
||||
CORE_REG_SECT points to an array of bytes, which are the contents
|
||||
|
@ -599,3 +440,10 @@ _initialize_x86_64_linux_nat (void)
|
|||
{
|
||||
add_core_fns (&linux_elf_core_fns);
|
||||
}
|
||||
|
||||
int
|
||||
kernel_u_size (void)
|
||||
{
|
||||
return (sizeof (struct user));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue