Add common write_memory and read_memory NetBSD routines

Instead of sharing the native-only code with all BSDs with slightly
different semantics of the kernels, share the NetBSD-only behavior beteen
the NetBSD native and gdbserver setup.

NetBSD does not differentiate the address space I and D in the
operations (contrary to OpenBSD). NetBSD handles EACCES that integrates
with NetBSD specific PaX MPROTECT error handling.

Add a verbose message in the native client that an operation could be
cancelled due to PaX MPROTECT setup.

gdb/ChangeLog:

       * nat/netbsd-nat.c (write_memory, read_memory): Add.
       * nat/netbsd-nat.h (write_memory, read_memory): Likewise.
       * nbsd-nat.c (nbsd_nat_target::xfer_partial): Update.

gdbserver/ChangeLog:

       * netbsd-low.cc (netbsd_process_target::read_memory)
       (netbsd_process_target::write_memory): Update.
This commit is contained in:
Kamil Rytarowski
2020-10-07 05:57:52 +02:00
parent 9529c85266
commit 91e5e8db33
6 changed files with 138 additions and 59 deletions

View File

@@ -556,36 +556,8 @@ int
netbsd_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr,
int size)
{
struct ptrace_io_desc io;
io.piod_op = PIOD_READ_D;
io.piod_len = size;
pid_t pid = current_process ()->pid;
int bytes_read = 0;
if (size == 0)
{
/* Zero length write always succeeds. */
return 0;
}
do
{
io.piod_offs = (void *)(memaddr + bytes_read);
io.piod_addr = myaddr + bytes_read;
int rv = ptrace (PT_IO, pid, &io, 0);
if (rv == -1)
return errno;
if (io.piod_len == 0)
return 0;
bytes_read += io.piod_len;
io.piod_len = size - bytes_read;
}
while (bytes_read < size);
return 0;
return netbsd_nat::read_memory (pid, myaddr, memaddr, size, nullptr);
}
/* Implement the write_memory target_ops method. */
@@ -594,37 +566,8 @@ int
netbsd_process_target::write_memory (CORE_ADDR memaddr,
const unsigned char *myaddr, int size)
{
struct ptrace_io_desc io;
io.piod_op = PIOD_WRITE_D;
io.piod_len = size;
pid_t pid = current_process ()->pid;
int bytes_written = 0;
if (size == 0)
{
/* Zero length write always succeeds. */
return 0;
}
do
{
io.piod_addr = (void *)(myaddr + bytes_written);
io.piod_offs = (void *)(memaddr + bytes_written);
int rv = ptrace (PT_IO, pid, &io, 0);
if (rv == -1)
return errno;
if (io.piod_len == 0)
return 0;
bytes_written += io.piod_len;
io.piod_len = size - bytes_written;
}
while (bytes_written < size);
return 0;
return netbsd_nat::write_memory (pid, myaddr, memaddr, size, nullptr);
}
/* Implement the request_interrupt target_ops method. */