@@ -146,6 +146,7 @@ static inline void tswap64s(uint64_t *s)
#if defined(CONFIG_USER_ONLY)
#include "exec/user/abitypes.h"
+#include "tcg-target-sa32.h"
/* On some host systems the guest address space is reserved on the host.
* This allows the guest address space to be offset to a convenient location.
@@ -154,6 +155,21 @@ extern uintptr_t guest_base;
extern bool have_guest_base;
extern unsigned long reserved_va;
+#if TCG_TARGET_SIGNED_ADDR32 && TARGET_LONG_BITS == 32
+extern bool guest_base_signed_addr32;
+#else
+#define guest_base_signed_addr32 false
+#endif
+
+static inline void set_guest_base_signed_addr32(void)
+{
+#ifdef guest_base_signed_addr32
+ qemu_build_not_reached();
+#else
+ guest_base_signed_addr32 = true;
+#endif
+}
+
/*
* Limit the guest addresses as best we can.
*
@@ -87,7 +87,8 @@ static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x)
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
static inline void *g2h_untagged(abi_ptr x)
{
- return (void *)((uintptr_t)(x) + guest_base);
+ uintptr_t hx = guest_base_signed_addr32 ? (int32_t)x : (uintptr_t)x;
+ return (void *)(guest_base + hx);
}
static inline void *g2h(CPUState *cs, abi_ptr x)
@@ -54,6 +54,10 @@
int singlestep;
uintptr_t guest_base;
bool have_guest_base;
+#ifndef guest_base_signed_addr32
+bool guest_base_signed_addr32;
+#endif
+
/*
* When running 32-on-64 we should make sure we can fit all of the possible
* guest address space into a contiguous chunk of virtual host memory.
@@ -72,6 +72,9 @@ static const char *seed_optarg;
unsigned long mmap_min_addr;
uintptr_t guest_base;
bool have_guest_base;
+#ifndef guest_base_signed_addr32
+bool guest_base_signed_addr32;
+#endif
/*
* Used to implement backwards-compatibility for the `-strace`, and