diff options
author | Pedro Alves <palves@redhat.com> | 2016-02-11 11:44:35 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2016-02-11 12:20:36 +0000 |
commit | 04956cf9b84b53728e20f0dae1f561ab26714453 (patch) | |
tree | dd8aaeac0a7d0bb0acbc9536295dcd064d3303ec | |
parent | ca47aa93d4a13e676e771041eb7372ff2cdb1487 (diff) | |
download | gdb-users/palves/gdbserver-extract-unsigned-integer.zip gdb-users/palves/gdbserver-extract-unsigned-integer.tar.gz gdb-users/palves/gdbserver-extract-unsigned-integer.tar.bz2 |
Fix gdbserver's regcache_raw_read_unsigned on big endian hostsusers/palves/gdbserver-extract-unsigned-integer
The regcache_raw_read_unsigned function is memcpy'ing a 32-bit value
directly into a 64-bit variable, which doesn't work on big endian
targets.
Fix this by memcpy'ing to a buffer, and then using
extract_unsigned_integer, just like gdb's version.
gdb/gdbserver/ChangeLog:
2016-02-11 Pedro Alves <palves@redhat.com>
* Makefile.in (SFILES): Add $(srcdir)/common/gdb-byteswap.c.
(gdb-byteswap.o): New rule.
* regcache.c: Include "gdb-byteswap.h".
(host_bfd_endian): New function.
(regcache_raw_read_unsigned): Use extract_unsigned_integer and
host_bfd_endian.
-rw-r--r-- | gdb/gdbserver/Makefile.in | 7 | ||||
-rw-r--r-- | gdb/gdbserver/regcache.c | 31 |
2 files changed, 30 insertions, 8 deletions
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 1e874e3..06a6f1b 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -185,7 +185,8 @@ SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \ $(srcdir)/common/btrace-common.c \ $(srcdir)/common/fileio.c $(srcdir)/nat/linux-namespaces.c \ $(srcdir)/arch/arm.c $(srcdir)/common/common-regcache.c \ - $(srcdir)/arch/arm-linux.c $(srcdir)/arch/arm-get-next-pcs.c + $(srcdir)/arch/arm-linux.c $(srcdir)/arch/arm-get-next-pcs.c \ + $(srcdir)/common/gdb-byteswap.c DEPFILES = @GDBSERVER_DEPFILES@ @@ -200,6 +201,7 @@ OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \ common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \ tdesc.o print-utils.o rsp-low.o errors.o common-debug.o cleanups.o \ common-exceptions.o symbol.o btrace-common.o fileio.o common-regcache.o \ + gdb-byteswap.o \ $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS) GDBREPLAY_OBS = gdbreplay.o version.o GDBSERVER_LIBS = @GDBSERVER_LIBS@ @@ -590,6 +592,9 @@ fileio.o: ../common/fileio.c common-regcache.o: ../common/common-regcache.c $(COMPILE) $< $(POSTCOMPILE) +gdb-byteswap.o: ../common/gdb-byteswap.c + $(COMPILE) $< + $(POSTCOMPILE) # Arch object files rules form ../arch diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c index 2af8e24..f875b10 100644 --- a/gdb/gdbserver/regcache.c +++ b/gdb/gdbserver/regcache.c @@ -21,6 +21,9 @@ #include "gdbthread.h" #include "tdesc.h" #include "rsp-low.h" +#include "bfd-types.h" +#include "gdb-byteswap.h" + #ifndef IN_PROCESS_AGENT struct regcache * @@ -424,14 +427,25 @@ collect_register (struct regcache *regcache, int n, void *buf) register_size (regcache->tdesc, n)); } +#ifndef IN_PROCESS_AGENT + +/* Return host endianness as an enum bfd_endian. */ + +static enum bfd_endian +host_bfd_endian (void) +{ + return (__BYTE_ORDER == __LITTLE_ENDIAN + ? BFD_ENDIAN_LITTLE + : BFD_ENDIAN_BIG); +} + enum register_status regcache_raw_read_unsigned (struct regcache *regcache, int regnum, ULONGEST *val) { int size; - - gdb_assert (regcache != NULL); - gdb_assert (regnum >= 0 && regnum < regcache->tdesc->num_registers); + gdb_byte *buf; + enum bfd_endian byteorder; size = register_size (regcache->tdesc, regnum); @@ -440,14 +454,17 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum, "%d bytes."), (int) sizeof (ULONGEST)); - *val = 0; - collect_register (regcache, regnum, val); + buf = (gdb_byte *) alloca (size); + collect_register (regcache, regnum, buf); + + /* Assume the inferior's byte order is the same as gdbserver's (the + host). */ + byteorder = host_bfd_endian (); + *val = extract_unsigned_integer (buf, size, byteorder); return REG_VALID; } -#ifndef IN_PROCESS_AGENT - void collect_register_as_string (struct regcache *regcache, int n, char *buf) { |