libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

qemu-6.0.0.patch (17332B)


      1 Note: incorporates execve patch from here, probably gpl garbage:
      2 https://patchwork.ozlabs.org/project/qemu-devel/patch/20200730160106.16613-1-rj.bcjesus@gmail.com/
      3 
      4 diff --git a/linux-user/main.c b/linux-user/main.c
      5 index f956afccab..f85effddaf 100644
      6 --- a/linux-user/main.c
      7 +++ b/linux-user/main.c
      8 @@ -114,6 +114,7 @@ static void usage(int exitcode);
      9  
     10  static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
     11  const char *qemu_uname_release;
     12 +const char *qemu_execve_path;
     13  
     14  /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
     15     we allocate a bigger stack. Need a better solution, for example
     16 @@ -345,6 +346,11 @@ static void handle_arg_guest_base(const char *arg)
     17      have_guest_base = true;
     18  }
     19  
     20 +static void handle_arg_execve(const char *arg)
     21 +{
     22 +    qemu_execve_path = strdup(arg);
     23 +}
     24 +
     25  static void handle_arg_reserved_va(const char *arg)
     26  {
     27      char *p;
     28 @@ -447,6 +453,8 @@ static const struct qemu_argument arg_table[] = {
     29       "uname",      "set qemu uname release string to 'uname'"},
     30      {"B",          "QEMU_GUEST_BASE",  true,  handle_arg_guest_base,
     31       "address",    "set guest_base address to 'address'"},
     32 +    {"execve",     "QEMU_EXECVE",      true,  handle_arg_execve,
     33 +     "",           "use this interpreter when a process calls execve()"},
     34      {"R",          "QEMU_RESERVED_VA", true,  handle_arg_reserved_va,
     35       "size",       "reserve 'size' bytes for guest virtual address space"},
     36      {"d",          "QEMU_LOG",         true,  handle_arg_log,
     37 diff --git a/linux-user/mmap.c b/linux-user/mmap.c
     38 index 7e3b245036..0b3f7288ac 100644
     39 --- a/linux-user/mmap.c
     40 +++ b/linux-user/mmap.c
     41 @@ -311,7 +311,7 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
     42   * It must be called with mmap_lock() held.
     43   * Return -1 if error.
     44   */
     45 -abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
     46 +abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align, bool map_32bit)
     47  {
     48      void *ptr, *prev;
     49      abi_ulong addr;
     50 @@ -346,7 +346,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
     51           *  - shmat() with SHM_REMAP flag
     52           */
     53          ptr = mmap(g2h_untagged(addr), size, PROT_NONE,
     54 -                   MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
     55 +                   MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE|(map_32bit?MAP_32BIT:0), -1, 0);
     56  
     57          /* ENOMEM, if host address space has no memory */
     58          if (ptr == MAP_FAILED) {
     59 @@ -357,7 +357,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
     60             This is used to modify the search algorithm below.  */
     61          repeat = (ptr == prev ? repeat + 1 : 0);
     62  
     63 -        if (h2g_valid(ptr + size - 1)) {
     64 +        if (map_32bit ? h2g(ptr+size-1) == (uint32_t) (ptrdiff_t) (ptr+size-1): h2g_valid(ptr + size - 1)) {
     65              addr = h2g(ptr);
     66  
     67              if ((addr & (align - 1)) == 0) {
     68 @@ -459,7 +459,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
     69      if (!(flags & MAP_FIXED)) {
     70          host_len = len + offset - host_offset;
     71          host_len = HOST_PAGE_ALIGN(host_len);
     72 -        start = mmap_find_vma(real_start, host_len, TARGET_PAGE_SIZE);
     73 +        start = mmap_find_vma(real_start, host_len, TARGET_PAGE_SIZE, flags & MAP_32BIT);
     74          if (start == (abi_ulong)-1) {
     75              errno = ENOMEM;
     76              goto fail;
     77 @@ -756,7 +756,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
     78      } else if (flags & MREMAP_MAYMOVE) {
     79          abi_ulong mmap_start;
     80  
     81 -        mmap_start = mmap_find_vma(0, new_size, TARGET_PAGE_SIZE);
     82 +        mmap_start = mmap_find_vma(0, new_size, TARGET_PAGE_SIZE, flags & MAP_32BIT);
     83  
     84          if (mmap_start == -1) {
     85              errno = ENOMEM;
     86 diff --git a/linux-user/qemu.h b/linux-user/qemu.h
     87 index 74e06e7121..612c90b2bc 100644
     88 --- a/linux-user/qemu.h
     89 +++ b/linux-user/qemu.h
     90 @@ -164,6 +164,7 @@ void init_task_state(TaskState *ts);
     91  void task_settid(TaskState *);
     92  void stop_all_tasks(void);
     93  extern const char *qemu_uname_release;
     94 +extern const char *qemu_execve_path;
     95  extern unsigned long mmap_min_addr;
     96  
     97  /* ??? See if we can avoid exposing so much of the loader internals.  */
     98 @@ -477,7 +478,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
     99                         abi_ulong new_addr);
    100  extern unsigned long last_brk;
    101  extern abi_ulong mmap_next_start;
    102 -abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong);
    103 +abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong, bool);
    104  void mmap_fork_start(void);
    105  void mmap_fork_end(int child);
    106  
    107 diff --git a/linux-user/strace.c b/linux-user/strace.c
    108 index e969121b6c..278c749bbc 100644
    109 --- a/linux-user/strace.c
    110 +++ b/linux-user/strace.c
    111 @@ -1071,6 +1071,9 @@ UNUSED static struct flags mmap_flags[] = {
    112  #ifdef MAP_POPULATE
    113      FLAG_TARGET(MAP_POPULATE),
    114  #endif
    115 +#ifdef TARGET_MAP_32BIT
    116 +    FLAG_TARGET(MAP_32BIT),
    117 +#endif
    118  #ifdef TARGET_MAP_UNINITIALIZED
    119      FLAG_TARGET(MAP_UNINITIALIZED),
    120  #endif
    121 diff --git a/linux-user/syscall.c b/linux-user/syscall.c
    122 index 95d79ddc43..f8808ad72f 100644
    123 --- a/linux-user/syscall.c
    124 +++ b/linux-user/syscall.c
    125 @@ -123,6 +123,7 @@
    126  #include <libdrm/drm.h>
    127  #include <libdrm/i915_drm.h>
    128  #endif
    129 +#include <linux/binfmts.h>
    130  #include "linux_loop.h"
    131  #include "uname.h"
    132  
    133 @@ -4639,7 +4640,7 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
    134          abi_ulong mmap_start;
    135  
    136          /* In order to use the host shmat, we need to honor host SHMLBA.  */
    137 -        mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba));
    138 +        mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba), false);
    139  
    140          if (mmap_start == -1) {
    141              errno = ENOMEM;
    142 @@ -6063,6 +6064,9 @@ static const StructEntry struct_termios_def = {
    143  };
    144  
    145  static bitmask_transtbl mmap_flags_tbl[] = {
    146 +#ifdef TARGET_MAP_32BIT
    147 +    { TARGET_MAP_32BIT, TARGET_MAP_32BIT, MAP_32BIT, MAP_32BIT },
    148 +#endif
    149      { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
    150      { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
    151      { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
    152 @@ -8178,6 +8182,131 @@ static target_timer_t get_timer_id(abi_long arg)
    153      return timerid;
    154  }
    155  
    156 +/* qemu_execve() Must return target values and target errnos.
    157 + *
    158 + * Although execve() is not an interruptible syscall it is
    159 + * a special case where we must use the safe_syscall wrapper:
    160 + * if we allow a signal to happen before we make the host
    161 + * syscall then we will 'lose' it, because at the point of
    162 + * execve the process leaves QEMU's control. So we use the
    163 + * safe syscall wrapper to ensure that we either take the
    164 + * signal as a guest signal, or else it does not happen
    165 + * before the execve completes and makes it the other
    166 + * program's problem.
    167 + */
    168 +static abi_long qemu_execve(char *filename, char *argv[],
    169 +                  char *envp[])
    170 +{
    171 +    char *i_arg = NULL, *i_name = NULL;
    172 +    char **new_argp;
    173 +    int argc, fd, ret, i, offset = 5;
    174 +    char *cp;
    175 +    char buf[BINPRM_BUF_SIZE];
    176 +
    177 +    /* normal execve case */
    178 +    if (qemu_execve_path == NULL || *qemu_execve_path == 0) {
    179 +        return get_errno(safe_execve(filename, argv, envp));
    180 +    }
    181 +
    182 +    for (argc = 0; argv[argc] != NULL; argc++) {
    183 +        /* nothing */ ;
    184 +    }
    185 +
    186 +    fd = open(filename, O_RDONLY);
    187 +    if (fd == -1) {
    188 +        return get_errno(fd);
    189 +    }
    190 +
    191 +    ret = read(fd, buf, BINPRM_BUF_SIZE);
    192 +    if (ret == -1) {
    193 +        close(fd);
    194 +        return get_errno(ret);
    195 +    }
    196 +
    197 +    /* if we have less than 2 bytes, we can guess it is not executable */
    198 +    if (ret < 2) {
    199 +        close(fd);
    200 +        return -host_to_target_errno(ENOEXEC);
    201 +    }
    202 +
    203 +    close(fd);
    204 +
    205 +    /* adapted from the kernel
    206 +     * https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/binfmt_script.c
    207 +     */
    208 +    if ((buf[0] == '#') && (buf[1] == '!')) {
    209 +        /*
    210 +         * This section does the #! interpretation.
    211 +         * Sorta complicated, but hopefully it will work.  -TYT
    212 +         */
    213 +
    214 +        buf[BINPRM_BUF_SIZE - 1] = '\0';
    215 +        cp = strchr(buf, '\n');
    216 +        if (cp == NULL) {
    217 +            cp = buf + BINPRM_BUF_SIZE - 1;
    218 +        }
    219 +        *cp = '\0';
    220 +        while (cp > buf) {
    221 +            cp--;
    222 +            if ((*cp == ' ') || (*cp == '\t')) {
    223 +                *cp = '\0';
    224 +            } else {
    225 +                break;
    226 +            }
    227 +        }
    228 +        for (cp = buf + 2; (*cp == ' ') || (*cp == '\t'); cp++) {
    229 +            /* nothing */ ;
    230 +        }
    231 +        if (*cp == '\0') {
    232 +            return -ENOEXEC; /* No interpreter name found */
    233 +        }
    234 +        i_name = cp;
    235 +        i_arg = NULL;
    236 +        for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
    237 +            /* nothing */ ;
    238 +        }
    239 +        while ((*cp == ' ') || (*cp == '\t')) {
    240 +            *cp++ = '\0';
    241 +        }
    242 +        if (*cp) {
    243 +            i_arg = cp;
    244 +        }
    245 +
    246 +        if (i_arg) {
    247 +            offset += 2;
    248 +        } else {
    249 +            offset += 1;
    250 +        }
    251 +    }
    252 +
    253 +    new_argp = alloca((argc + offset + 1) * sizeof(void *));
    254 +
    255 +    /* Copy the original arguments with offset */
    256 +    for (i = 0; i < argc; i++) {
    257 +        new_argp[i + offset] = argv[i];
    258 +    }
    259 +
    260 +    new_argp[0] = strdup(qemu_execve_path);
    261 +    new_argp[1] = strdup("--execve");
    262 +    new_argp[2] = strdup(qemu_execve_path);
    263 +    new_argp[3] = strdup("-0");
    264 +    new_argp[offset] = filename;
    265 +    new_argp[argc + offset] = NULL;
    266 +
    267 +    if (i_name) {
    268 +        new_argp[4] = i_name;
    269 +        new_argp[5] = i_name;
    270 +
    271 +        if (i_arg) {
    272 +            new_argp[6] = i_arg;
    273 +        }
    274 +    } else {
    275 +        new_argp[4] = argv[0];
    276 +    }
    277 +
    278 +    return get_errno(safe_execve(qemu_execve_path, new_argp, envp));
    279 +}
    280 +
    281  static int target_to_host_cpu_mask(unsigned long *host_mask,
    282                                     size_t host_size,
    283                                     abi_ulong target_addr,
    284 @@ -8527,17 +8656,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
    285  
    286              if (!(p = lock_user_string(arg1)))
    287                  goto execve_efault;
    288 -            /* Although execve() is not an interruptible syscall it is
    289 -             * a special case where we must use the safe_syscall wrapper:
    290 -             * if we allow a signal to happen before we make the host
    291 -             * syscall then we will 'lose' it, because at the point of
    292 -             * execve the process leaves QEMU's control. So we use the
    293 -             * safe syscall wrapper to ensure that we either take the
    294 -             * signal as a guest signal, or else it does not happen
    295 -             * before the execve completes and makes it the other
    296 -             * program's problem.
    297 -             */
    298 -            ret = get_errno(safe_execve(p, argp, envp));
    299 +            ret = qemu_execve(p, argp, envp);
    300              unlock_user(p, arg1, 0);
    301  
    302              goto execve_end;
    303 diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
    304 index 25be414727..c0772c1ae7 100644
    305 --- a/linux-user/syscall_defs.h
    306 +++ b/linux-user/syscall_defs.h
    307 @@ -1390,6 +1390,7 @@ struct target_winsize {
    308  #else
    309  #define TARGET_MAP_FIXED	0x10		/* Interpret addr exactly */
    310  #define TARGET_MAP_ANONYMOUS	0x20		/* don't use a file */
    311 +#define TARGET_MAP_32BIT	0x40
    312  #define TARGET_MAP_GROWSDOWN	0x0100		/* stack-like segment */
    313  #define TARGET_MAP_DENYWRITE	0x0800		/* ETXTBSY */
    314  #define TARGET_MAP_EXECUTABLE	0x1000		/* mark it as an executable */
    315 diff --git a/target/i386/cpu.c b/target/i386/cpu.c
    316 index ad99cad0e7..8258b92e5b 100644
    317 --- a/target/i386/cpu.c
    318 +++ b/target/i386/cpu.c
    319 @@ -1653,6 +1653,7 @@ typedef struct X86CPUDefinition {
    320      int family;
    321      int model;
    322      int stepping;
    323 +    int brand_id;
    324      FeatureWordArray features;
    325      const char *model_id;
    326      CPUCaches *cache_info;
    327 @@ -2137,6 +2138,54 @@ static X86CPUDefinition builtin_x86_defs[] = {
    328          .xlevel = 0,
    329          .model_id = "",
    330      },
    331 +    {
    332 +        /* http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0000F4A_K8_Clawhammer_CPUID.txt */
    333 +        .name = "athlon-64",
    334 +        .level = 1,
    335 +        .vendor = CPUID_VENDOR_AMD,
    336 +        .family = 15,
    337 +        .model = 4,
    338 +        .stepping = 10,
    339 +        .features[FEAT_1_EDX] =
    340 +            CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE |
    341 +            CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE |
    342 +            CPUID_CX8 | CPUID_APIC | CPUID_SEP |
    343 +            CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
    344 +            CPUID_PAT | CPUID_PSE36 | /*no: CPUID_PN |*/ CPUID_CLFLUSH |
    345 +            /*no: CPUID_DTS | CPUID_ACPI |*/ CPUID_MMX |
    346 +            CPUID_FXSR | CPUID_SSE | CPUID_SSE2,
    347 +        .features[FEAT_8000_0001_EDX] =
    348 +            (CPUID_EXT2_FPU | CPUID_EXT2_VME | CPUID_EXT2_DE | CPUID_EXT2_PSE |
    349 +             CPUID_EXT2_TSC | CPUID_EXT2_MSR | CPUID_EXT2_PAE | CPUID_EXT2_MCE |
    350 +             CPUID_EXT2_CX8 | CPUID_EXT2_APIC | CPUID_EXT2_SYSCALL |
    351 +             CPUID_EXT2_MTRR | CPUID_EXT2_PGE | CPUID_EXT2_MCA | CPUID_EXT2_CMOV |
    352 +             CPUID_EXT2_PAT | CPUID_EXT2_PSE36 | /*no: CPUID_EXT2_MP */
    353 +             CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_MMX |
    354 +             CPUID_EXT2_FXSR | /*no: CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1G | CPUID_EXT2_RTDSCP*/
    355 +             CPUID_EXT2_LM | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_3DNOW) &
    356 +            ~CPUID_EXT2_AMD_ALIASES,
    357 +        /* todo cache info 0x80000005-6 */
    358 +        .features[FEAT_8000_0007_EDX] = 0x0f, /*??*/
    359 +        /*.phys_bits = 0x00003028,*/
    360 +        .xlevel = 0x80000018,
    361 +        .brand_id = 0x106,
    362 +        .model_id = "AMD Athlon(tm) 64 Processor 2800+",
    363 +    },
    364 +    {
    365 +        .name = "u3-64bit-minimal",
    366 +        .level = 1,
    367 +        .vendor = CPUID_VENDOR_AMD,
    368 +        .family = 15,
    369 +        .model = 4,
    370 +        .stepping = 10,
    371 +        .features[FEAT_1_EDX] =
    372 +        PENTIUM2_FEATURES | PPRO_FEATURES | CPUID_CLFLUSH /*sse2?*/,
    373 +        .features[FEAT_8000_0001_EDX] =
    374 +            /* NX: amd: since amd64, intel: P4 Prescott+ */
    375 +            CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_LM,
    376 +        .xlevel = 0x80000018,
    377 +        .model_id = "Fuck off",
    378 +    },
    379      {
    380          .name = "athlon",
    381          .level = 2,
    382 @@ -4657,6 +4706,41 @@ static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
    383      env->cpuid_version |= value & 0xf;
    384  }
    385  
    386 +static void x86_cpuid_version_get_brand_id(Object *obj, Visitor *v,
    387 +                                           const char *name, void *opaque,
    388 +                                           Error **errp)
    389 +{
    390 +    X86CPU *cpu = X86_CPU(obj);
    391 +    CPUX86State *env = &cpu->env;
    392 +    int64_t value;
    393 +
    394 +    value = env->cpuid_brand_id;
    395 +    visit_type_int(v, name, &value, errp);
    396 +}
    397 +
    398 +static void x86_cpuid_version_set_brand_id(Object *obj, Visitor *v,
    399 +                                           const char *name, void *opaque,
    400 +                                           Error **errp)
    401 +{
    402 +    X86CPU *cpu = X86_CPU(obj);
    403 +    CPUX86State *env = &cpu->env;
    404 +    const int64_t min = 0;
    405 +    const int64_t max = 0xffff;
    406 +    int64_t value;
    407 +
    408 +    if (!visit_type_int(v, name, &value, errp)) {
    409 +        return;
    410 +    }
    411 +    if (value < min || value > max) {
    412 +        error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
    413 +                   name ? name : "null", value, min, max);
    414 +        return;
    415 +    }
    416 +
    417 +    env->cpuid_brand_id = value;
    418 +}
    419 +
    420 +
    421  static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
    422  {
    423      X86CPU *cpu = X86_CPU(obj);
    424 @@ -5269,6 +5353,8 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
    425                              &error_abort);
    426      object_property_set_str(OBJECT(cpu), "model-id", def->model_id,
    427                              &error_abort);
    428 +    object_property_set_int(OBJECT(cpu), "brand-id", def->brand_id,
    429 +                            &error_abort);
    430      for (w = 0; w < FEATURE_WORDS; w++) {
    431          env->features[w] = def->features[w];
    432      }
    433 @@ -5936,7 +6022,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
    434          break;
    435      case 0x80000001:
    436          *eax = env->cpuid_version;
    437 -        *ebx = 0;
    438 +        *ebx = env->cpuid_brand_id;
    439          *ecx = env->features[FEAT_8000_0001_ECX];
    440          *edx = env->features[FEAT_8000_0001_EDX];
    441  
    442 @@ -7455,6 +7541,9 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
    443      object_class_property_add(oc, "stepping", "int",
    444                                x86_cpuid_version_get_stepping,
    445                                x86_cpuid_version_set_stepping, NULL, NULL);
    446 +    object_class_property_add(oc, "brand-id", "int",
    447 +                              x86_cpuid_version_get_brand_id,
    448 +                              x86_cpuid_version_set_brand_id, NULL, NULL);
    449      object_class_property_add_str(oc, "vendor",
    450                                    x86_cpuid_get_vendor,
    451                                    x86_cpuid_set_vendor);
    452 diff --git a/target/i386/cpu.h b/target/i386/cpu.h
    453 index 570f916878..2e7b3c838c 100644
    454 --- a/target/i386/cpu.h
    455 +++ b/target/i386/cpu.h
    456 @@ -1591,6 +1591,7 @@ typedef struct CPUX86State {
    457      uint32_t cpuid_vendor2;
    458      uint32_t cpuid_vendor3;
    459      uint32_t cpuid_version;
    460 +    uint32_t cpuid_brand_id;
    461      FeatureWordArray features;
    462      /* Features that were explicitly enabled/disabled */
    463      FeatureWordArray user_features;