Using bisection, it can be deduced that this behavior appears to be caused by this commit:
commit ee94743034bfb443cf246eda4971bdc15d8ee066 (HEAD) Author: Alex Bennée <alex.ben...@linaro.org> Date: Wed May 13 18:51:28 2020 +0100 linux-user: completely re-write init_guest_space First we ensure all guest space initialisation logic comes through probe_guest_base once we understand the nature of the binary we are loading. The convoluted init_guest_space routine is removed and replaced with a number of pgb_* helpers which are called depending on what requirements we have when loading the binary. We first try to do what is requested by the host. Failing that we try and satisfy the guest requested base address. If all those options fail we fall back to finding a space in the memory map using our recently written read_self_maps() helper. There are some additional complications we try and take into account when looking for holes in the address space. We try not to go directly after the system brk() space so there is space for a little growth. We also don't want to have to use negative offsets which would result in slightly less efficient code on x86 when it's unable to use the segment offset register. Less mind-binding gotos and hopefully clearer logic throughout. Signed-off-by: Alex Bennée <alex.ben...@linaro.org> Acked-by: Laurent Vivier <laur...@vivier.eu> Message-Id: <20200513175134.19619-5-alex.ben...@linaro.org> -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1880225 Title: Emulation of some arm programs fail with "Assertion `have_guest_base' failed." Status in QEMU: New Bug description: This issue is observer with QEMU ToT, checked out around May 15th (but I believe it is present in current master too), and wasn't present in QEMU v5.0.0. I am using 32-bit Intel(R) Pentium(R) M processor 1.73GHz host. Arm cross-compiler is a standard cross-compiler that comes with Debian-based distributions, and gcc version is: $ arm-linux-gnueabi-gcc --version arm-linux-gnueabi-gcc (Debian 8.3.0-2) 8.3.0 Compile this program with cross compiler: $ arm-linux-gnueabi-gcc -O2 -static toupper_string.c -o toupper_string-arm Emulation with QEMU v5.0.0 is correct, and gives expected output: $ ~/Build/qemu-5.0.0/build-gcc/arm-linux-user/qemu-arm ./toupper_string-arm CONTROL RESULT: (toupper_string) nwlrbbmqbhcdarz owkkyhiddqscdxr jmowfrxsjybldbe fsarcbynecdyggx xpklorellnmpapq NWLRBBMQBHCDARZ OWKKYHIDDQSCDXR JMOWFRXSJYBLDBE FSARCBYNECDYGGX XPKLORELLNMPAPQ While, in case of QEMU master it fails: $ ~/Build/qemu-master/build-gcc/arm-linux-user/qemu-arm ./toupper_string-arm qemu-arm: /home/rtrk/Build/qemu-master/linux-user/elfload.c:2294: probe_guest_base: Assertion `have_guest_base' failed. Aborted There are many other programs that exibit the same behavior. The failure is arm-sprecific. ----------------------------------------------------- source code: (let's call this file toupper_string.c) (similar file is also in attachment) #include <stdlib.h> #include <string.h> #include <stdio.h> #include <unistd.h> #define MAX_STRING_LENGHT 15 #define NUMBER_OF_RANDOM_STRINGS 100 #define DEFAULT_NUMBER_OF_REPETITIONS 30000 #define MAX_NUMBER_OF_REPETITIONS 1000000000 #define NUMBER_OF_CONTROL_PRINT_ITEMS 5 /* Structure for keeping an array of strings */ struct StringStruct { char chars[MAX_STRING_LENGHT + 1]; }; /** * Sets characters of the given string to random small letters a-z. * @param s String to get random characters. * @len Length of the input string. */ static void gen_random_string(char *chars, const int len) { static const char letters[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t i = 0; i < len; i++) { chars[i] = letters[rand() % (sizeof(letters) - 1)]; } chars[len] = 0; } void main (int argc, char* argv[]) { struct StringStruct random_strings[NUMBER_OF_RANDOM_STRINGS]; struct StringStruct strings_to_be_uppercased[NUMBER_OF_RANDOM_STRINGS]; int32_t number_of_repetitions = DEFAULT_NUMBER_OF_REPETITIONS; int32_t option; /* Parse command line options */ while ((option = getopt(argc, argv, "n:")) != -1) { if (option == 'n') { int32_t user_number_of_repetitions = atoi(optarg); /* Check if the value is a negative number */ if (user_number_of_repetitions < 1) { fprintf(stderr, "Error ... Value for option '-n' cannot be a " "negative number.\n"); exit(EXIT_FAILURE); } /* Check if the value is a string or zero */ if (user_number_of_repetitions == 0) { fprintf(stderr, "Error ... Invalid value for option '-n'.\n"); exit(EXIT_FAILURE); } /* Check if the value is too large */ if (user_number_of_repetitions > MAX_NUMBER_OF_REPETITIONS) { fprintf(stderr, "Error ... Value for option '-n' cannot be " "more than %d.\n", MAX_NUMBER_OF_REPETITIONS); exit(EXIT_FAILURE); } number_of_repetitions = user_number_of_repetitions; } else { exit(EXIT_FAILURE); } } /* Create an array of strings with random content */ srand(1); for (size_t i = 0; i < NUMBER_OF_RANDOM_STRINGS; i++) { gen_random_string(random_strings[i].chars, MAX_STRING_LENGHT); } /* Perform uppercasing of a set of random strings multiple times */ for (size_t j = 0; j < number_of_repetitions; j++) { /* Copy initial set of random strings to the set to be uppercased */ memcpy(strings_to_be_uppercased, random_strings, NUMBER_OF_RANDOM_STRINGS * (MAX_STRING_LENGHT + 1)); /* Do actual changing case to uppercase */ for (size_t i = 0; i < NUMBER_OF_RANDOM_STRINGS; i++) { int k = 0; while (strings_to_be_uppercased[i].chars[k]) { char ch = strings_to_be_uppercased[i].chars[k] - 32; memcpy((void *)strings_to_be_uppercased[i].chars + k, &ch, 1); k++; } } } /* Control printing */ printf("CONTROL RESULT: (toupper_string)\n"); for (size_t i = 0; i < NUMBER_OF_CONTROL_PRINT_ITEMS; i++) { printf(" %s", random_strings[i].chars); } printf("\n"); for (size_t i = 0; i < NUMBER_OF_CONTROL_PRINT_ITEMS; i++) { printf(" %s", strings_to_be_uppercased[i].chars); } printf("\n"); } To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1880225/+subscriptions