Browse Source

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.
users/ARM/morello-binutils-gdb-master
Kamil Rytarowski 6 years ago
parent
commit
91e5e8db33
  1. 6
      gdb/ChangeLog
  2. 80
      gdb/nat/netbsd-nat.c
  3. 22
      gdb/nat/netbsd-nat.h
  4. 23
      gdb/nbsd-nat.c
  5. 5
      gdbserver/ChangeLog
  6. 61
      gdbserver/netbsd-low.cc

6
gdb/ChangeLog

@ -1,3 +1,9 @@
2020-10-07 Kamil Rytarowski <n54@gmx.com>
* 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.
2020-10-07 Simon Marchi <simon.marchi@polymtl.ca>
* break-catch-sig.c (signal_catch_counts): Make a static arrray.

80
gdb/nat/netbsd-nat.c

@ -210,4 +210,84 @@ qxfer_siginfo (pid_t pid, const char *annex, unsigned char *readbuf,
return len;
}
/* See netbsd-nat.h. */
int
write_memory (pid_t pid, unsigned const char *writebuf, CORE_ADDR offset,
size_t len, size_t *xfered_len)
{
struct ptrace_io_desc io;
io.piod_op = PIOD_WRITE_D;
io.piod_len = len;
size_t bytes_written = 0;
/* Zero length write always succeeds. */
if (len > 0)
{
do
{
io.piod_addr = (void *)(writebuf + bytes_written);
io.piod_offs = (void *)(offset + bytes_written);
errno = 0;
int rv = ptrace (PT_IO, pid, &io, 0);
if (rv == -1)
{
gdb_assert (errno != 0);
return errno;
}
if (io.piod_len == 0)
return 0;
bytes_written += io.piod_len;
io.piod_len = len - bytes_written;
}
while (bytes_written < len);
}
if (xfered_len != nullptr)
*xfered_len = bytes_written;
return 0;
}
/* See netbsd-nat.h. */
int
read_memory (pid_t pid, unsigned char *readbuf, CORE_ADDR offset,
size_t len, size_t *xfered_len)
{
struct ptrace_io_desc io;
io.piod_op = PIOD_READ_D;
io.piod_len = len;
size_t bytes_read = 0;
/* Zero length read always succeeds. */
if (len > 0)
{
do
{
io.piod_offs = (void *)(offset + bytes_read);
io.piod_addr = readbuf + 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 = len - bytes_read;
}
while (bytes_read < len);
}
if (xfered_len != nullptr)
*xfered_len = bytes_read;
return 0;
}
}

22
gdb/nat/netbsd-nat.h

@ -67,6 +67,28 @@ extern void enable_proc_events (pid_t pid);
extern int qxfer_siginfo (pid_t pid, const char *annex, unsigned char *readbuf,
unsigned const char *writebuf, CORE_ADDR offset,
int len);
/* Write gdb's LEN bytes from WRITEBUF and copy it to OFFSET in inferior
process' address space. The inferior is specified by PID.
Returns 0 on success or errno on failure and the number of bytes
on a successful transfer in XFERED_LEN.
This function assumes internally that the queried process is stopped and
traced. */
extern int write_memory (pid_t pid, unsigned const char *writebuf,
CORE_ADDR offset, size_t len, size_t *xfered_len);
/* Read inferior process's LEN bytes from OFFSET and copy it to WRITEBUF in
gdb's address space.
Returns 0 on success or errno on failure and the number of bytes
on a successful transfer in XFERED_LEN.
This function assumes internally that the queried process is stopped and
traced. */
extern int read_memory (pid_t pid, unsigned char *readbuf, CORE_ADDR offset,
size_t len, size_t *xfered_len);
}
#endif

23
gdb/nbsd-nat.c

@ -764,6 +764,29 @@ nbsd_nat_target::xfer_partial (enum target_object object,
*xfered_len = len;
return TARGET_XFER_OK;
}
case TARGET_OBJECT_MEMORY:
{
size_t xfered;
int res;
if (writebuf != nullptr)
res = netbsd_nat::write_memory (pid, writebuf, offset, len, &xfered);
else
res = netbsd_nat::read_memory (pid, readbuf, offset, len, &xfered);
if (res != 0)
{
if (res == EACCES)
fprintf_unfiltered (gdb_stderr, "Cannot %s process at %s (%s). "
"Is PaX MPROTECT active? See security(7), "
"sysctl(7), paxctl(8)\n",
(writebuf ? "write to" : "read from"),
pulongest (offset), safe_strerror (errno));
return TARGET_XFER_E_IO;
}
if (xfered == 0)
return TARGET_XFER_EOF;
*xfered_len = (ULONGEST) xfered;
return TARGET_XFER_OK;
}
default:
return inf_ptrace_target::xfer_partial (object, annex,
readbuf, writebuf, offset,

5
gdbserver/ChangeLog

@ -1,3 +1,8 @@
2020-10-07 Kamil Rytarowski <n54@gmx.com>
* netbsd-low.cc (netbsd_process_target::read_memory)
(netbsd_process_target::write_memory): Update.
2020-10-07 Kamil Rytarowski <n54@gmx.com>
* netbsd-aarch64-low.cc: Add.

61
gdbserver/netbsd-low.cc

@ -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. */

Loading…
Cancel
Save