summaryrefslogtreecommitdiff
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ecead512a0..c62d8754f0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4737,7 +4737,7 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
abi_ulong target_addr,
struct stat *host_st)
{
-#ifdef TARGET_ARM
+#if defined(TARGET_ARM) && defined(TARGET_ABI32)
if (((CPUARMState *)cpu_env)->eabi) {
struct target_eabi_stat64 *target_st;
@@ -4863,12 +4863,35 @@ int host_to_target_waitstatus(int status)
return status;
}
+static int relstr_to_int(const char *s)
+{
+ /* Convert a uname release string like "2.6.18" to an integer
+ * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
+ */
+ int i, n, tmp;
+
+ tmp = 0;
+ for (i = 0; i < 3; i++) {
+ n = 0;
+ while (*s >= '0' && *s <= '9') {
+ n *= 10;
+ n += *s - '0';
+ s++;
+ }
+ tmp = (tmp << 8) + n;
+ if (*s == '.') {
+ s++;
+ }
+ }
+ return tmp;
+}
+
int get_osversion(void)
{
static int osversion;
struct new_utsname buf;
const char *s;
- int i, n, tmp;
+
if (osversion)
return osversion;
if (qemu_uname_release && *qemu_uname_release) {
@@ -4878,22 +4901,33 @@ int get_osversion(void)
return 0;
s = buf.release;
}
- tmp = 0;
- for (i = 0; i < 3; i++) {
- n = 0;
- while (*s >= '0' && *s <= '9') {
- n *= 10;
- n += *s - '0';
- s++;
- }
- tmp = (tmp << 8) + n;
- if (*s == '.')
- s++;
- }
- osversion = tmp;
+ osversion = relstr_to_int(s);
return osversion;
}
+void init_qemu_uname_release(void)
+{
+ /* Initialize qemu_uname_release for later use.
+ * If the host kernel is too old and the user hasn't asked for
+ * a specific fake version number, we might want to fake a minimum
+ * target kernel version.
+ */
+#ifdef UNAME_MINIMUM_RELEASE
+ struct new_utsname buf;
+
+ if (qemu_uname_release && *qemu_uname_release) {
+ return;
+ }
+
+ if (sys_uname(&buf)) {
+ return;
+ }
+
+ if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
+ qemu_uname_release = UNAME_MINIMUM_RELEASE;
+ }
+#endif
+}
static int open_self_maps(void *cpu_env, int fd)
{
@@ -6381,7 +6415,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif
#ifdef TARGET_NR_mmap
case TARGET_NR_mmap:
-#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
+#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
+ (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
|| defined(TARGET_S390X)
{