Prepare to share probe_guest_base with bsd-user. Create a linux_probe_guest_base wrapper with the portions of probe_guest_base that are linux specific: managing the commpage for various targets.
Signed-off-by: Richard Henderson <[email protected]> --- include/user/probe-guest-base.h | 37 ++++ linux-user/user-internals.h | 10 +- common-user/probe-guest-base.c | 343 ++++++++++++++++++++++++++++++++ linux-user/elfload.c | 337 +------------------------------ linux-user/flatload.c | 2 +- common-user/meson.build | 1 + 6 files changed, 392 insertions(+), 338 deletions(-) create mode 100644 include/user/probe-guest-base.h create mode 100644 common-user/probe-guest-base.c diff --git a/include/user/probe-guest-base.h b/include/user/probe-guest-base.h new file mode 100644 index 0000000000..d7492ef46c --- /dev/null +++ b/include/user/probe-guest-base.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef USER_PROBE_GUEST_BASE_H +#define USER_PROBE_GUEST_BASE_H + +#ifndef CONFIG_USER_ONLY +#error Cannot include this header from system emulation +#endif + +#include "exec/vaddr.h" + +typedef struct PGBRange { + vaddr lo; + vaddr hi; +} PGBRange; + +/** + * probe_guest_base: + * @image_name: the executable being loaded + * @image_range: the fixed addresses within the executable + * + * Creates the initial guest address space in the host memory space. + * + * If @image_range is NULL, then no address in the executable is fixed, + * i.e. it is fully relocatable. + * + * This function will not return if a valid value for guest_base + * cannot be chosen. On return, the executable loader can expect + * + * target_mmap(i->lo, i->hi - i->lo + 1, ...) + * + * to succeed. + */ +void probe_guest_base(const char *image_name, const PGBRange *image_range, + const PGBRange *commpage_range); + +#endif diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h index bc6b9f44e6..71f72002b6 100644 --- a/linux-user/user-internals.h +++ b/linux-user/user-internals.h @@ -22,6 +22,7 @@ #include "qemu/log.h" #include "exec/tb-flush.h" #include "exec/translation-block.h" +#include "user/probe-guest-base.h" extern char *exec_path; extern char real_exec_path[PATH_MAX]; @@ -74,13 +75,8 @@ void clone_fork_end(bool child); void fork_start(void); void fork_end(pid_t pid); -typedef struct PGBRange { - vaddr lo; - vaddr hi; -} PGBRange; - /** - * probe_guest_base: + * linux_probe_guest_base: * @image_name: the executable being loaded * @image_range: the fixed addresses within the executable * @@ -96,7 +92,7 @@ typedef struct PGBRange { * * to succeed. */ -void probe_guest_base(const char *image_name, const PGBRange *image_range); +void linux_probe_guest_base(const char *image_name, const PGBRange *image_range); /* syscall.c */ int host_to_target_waitstatus(int status); diff --git a/common-user/probe-guest-base.c b/common-user/probe-guest-base.c new file mode 100644 index 0000000000..77722fe63f --- /dev/null +++ b/common-user/probe-guest-base.c @@ -0,0 +1,343 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/units.h" +#include "qemu/target-info.h" +#include "qemu/log.h" +#include "user/guest-base.h" +#include "user/mmap-min-addr.h" +#include "user/guest-host.h" +#include "user/probe-guest-base.h" +#include "user/selfmap.h" +#include "exec/target_page.h" +#include <sys/shm.h> + +/* Linux and FreeBSD use different flags to express NOREPLACE. */ +#ifdef __FreeBSD__ +#define MAP_FIXED_NOREPLACE (MAP_FIXED | MAP_EXCL) +#endif + +/** + * pgb_try_mmap: + * @addr: host start address + * @addr_last: host last address + * @keep: do not unmap the probe region + * + * Return 1 if [@addr, @addr_last] is not mapped in the host, + * return 0 if it is not available to map, and -1 on mmap error. + * If @keep, the region is left mapped on success, otherwise unmapped. + */ +static int pgb_try_mmap(uintptr_t addr, uintptr_t addr_last, bool keep) +{ + size_t size = addr_last - addr + 1; + void *p = mmap((void *)addr, size, PROT_NONE, + MAP_ANONYMOUS | MAP_PRIVATE | + MAP_NORESERVE | MAP_FIXED_NOREPLACE, -1, 0); + int ret; + + if (p == MAP_FAILED) { + return errno == EEXIST ? 0 : -1; + } + ret = p == (void *)addr; + if (!keep || !ret) { + munmap(p, size); + } + return ret; +} + +/** + * pgb_try_mmap_skip_brk(uintptr_t addr, uintptr_t size, uintptr_t brk) + * @addr: host address + * @addr_last: host last address + * @brk: host brk + * + * Like pgb_try_mmap, but additionally reserve some memory following brk. + */ +static int pgb_try_mmap_skip_brk(uintptr_t addr, uintptr_t addr_last, + uintptr_t brk, bool keep) +{ + uintptr_t brk_last = brk + 16 * MiB - 1; + + /* Do not map anything close to the host brk. */ + if (addr <= brk_last && brk <= addr_last) { + return 0; + } + return pgb_try_mmap(addr, addr_last, keep); +} + +/** + * pgb_try_mmap_set: + * @ga: set of guest addrs + * @base: guest_base + * @brk: host brk + * + * Return true if all @ga can be mapped by the host at @base. + * On success, retain the mapping at index 0 for reserved_va. + */ + +typedef struct PGBAddrs { + PGBRange bounds[3]; + int nbounds; +} PGBAddrs; + +static bool pgb_try_mmap_set(const PGBAddrs *ga, uintptr_t base, uintptr_t brk) +{ + for (int i = ga->nbounds - 1; i >= 0; --i) { + if (pgb_try_mmap_skip_brk(ga->bounds[i].lo + base, + ga->bounds[i].hi + base, + brk, i == 0 && reserved_va) <= 0) { + return false; + } + } + return true; +} + +/** + * pgb_addr_set: + * @ga: output set of guest addrs + * @image_range: fixed guest image addresses + * @identity: create for identity mapping + * + * Fill in @ga with the image, COMMPAGE and NULL page. + */ +static bool pgb_addr_set(PGBAddrs *ga, const PGBRange *image_range, + const PGBRange *commpage_range, bool try_identity) +{ + int n; + + /* + * With a low commpage, or a guest mapped very low, + * we may not be able to use the identity map. + */ + if (try_identity) { + if (commpage_range && commpage_range->lo < mmap_min_addr) { + return false; + } + if (image_range && image_range->lo < mmap_min_addr) { + return false; + } + } + + memset(ga, 0, sizeof(*ga)); + n = 0; + + if (reserved_va) { + ga->bounds[n].lo = try_identity ? mmap_min_addr : 0; + ga->bounds[n].hi = reserved_va; + n++; + /* Low COMMPAGE and NULL handled by reserving from 0. */ + } else { + /* Add any low COMMPAGE or NULL page. */ + if (!try_identity || (commpage_range && commpage_range->lo == 0)) { + ga->bounds[n].lo = 0; + ga->bounds[n].hi = TARGET_PAGE_SIZE - 1; + n++; + } + + /* Add the guest image for ET_EXEC. */ + if (image_range) { + ga->bounds[n++] = *image_range; + } + } + + /* Add any high COMMPAGE not covered by reserved_va. */ + if (commpage_range && reserved_va < commpage_range->hi) { + ga->bounds[n].lo = commpage_range->lo & qemu_real_host_page_mask(); + ga->bounds[n].hi = commpage_range->hi; + n++; + } + + ga->nbounds = n; + return true; +} + +static void pgb_fail_in_use(const char *image_name) +{ + error_report("%s: requires virtual address space that is in use " + "(omit the -B option or choose a different value)", + image_name); + exit(EXIT_FAILURE); +} + +static void pgb_fixed(const char *image_name, const PGBRange *image_range, + const PGBRange *commpage_range, uintptr_t align) +{ + PGBAddrs ga; + uintptr_t brk = (uintptr_t)sbrk(0); + + if (!QEMU_IS_ALIGNED(guest_base, align)) { + fprintf(stderr, "Requested guest base %p does not satisfy " + "host minimum alignment (0x%" PRIxPTR ")\n", + (void *)guest_base, align); + exit(EXIT_FAILURE); + } + + if (!pgb_addr_set(&ga, image_range, commpage_range, !guest_base) + || !pgb_try_mmap_set(&ga, guest_base, brk)) { + pgb_fail_in_use(image_name); + } +} + +/** + * pgb_find_fallback: + * + * This is a fallback method for finding holes in the host address space + * if we don't have the benefit of being able to access /proc/self/map. + * It can potentially take a very long time as we can only dumbly iterate + * up the host address space seeing if the allocation would work. + */ +static uintptr_t pgb_find_fallback(const PGBAddrs *ga, uintptr_t align, + uintptr_t brk) +{ + /* TODO: come up with a better estimate of how much to skip. */ + uintptr_t skip = sizeof(uintptr_t) == 4 ? MiB : GiB; + + for (uintptr_t base = skip; ; base += skip) { + base = ROUND_UP(base, align); + if (pgb_try_mmap_set(ga, base, brk)) { + return base; + } + if (base >= -skip) { + return -1; + } + } +} + +static uintptr_t pgb_try_itree(const PGBAddrs *ga, uintptr_t base, + IntervalTreeRoot *root) +{ + for (int i = ga->nbounds - 1; i >= 0; --i) { + uintptr_t s = base + ga->bounds[i].lo; + uintptr_t l = base + ga->bounds[i].hi; + IntervalTreeNode *n; + + if (l < s) { + /* Wraparound. Skip to advance S to mmap_min_addr. */ + return mmap_min_addr - s; + } + + n = interval_tree_iter_first(root, s, l); + if (n != NULL) { + /* Conflict. Skip to advance S to LAST + 1. */ + return n->last - s + 1; + } + } + return 0; /* success */ +} + +static uintptr_t pgb_find_itree(const PGBAddrs *ga, IntervalTreeRoot *root, + uintptr_t align, uintptr_t brk) +{ + uintptr_t last = sizeof(uintptr_t) == 4 ? MiB : GiB; + uintptr_t base, skip; + + while (true) { + base = ROUND_UP(last, align); + if (base < last) { + return -1; + } + + skip = pgb_try_itree(ga, base, root); + if (skip == 0) { + break; + } + + last = base + skip; + if (last < base) { + return -1; + } + } + + /* + * We've chosen 'base' based on holes in the interval tree, + * but we don't yet know if it is a valid host address. + * Because it is the first matching hole, if the host addresses + * are invalid we know there are no further matches. + */ + return pgb_try_mmap_set(ga, base, brk) ? base : -1; +} + +static void pgb_dynamic(const char *image_name, const PGBRange *image_range, + const PGBRange *commpage_range, uintptr_t align) +{ + IntervalTreeRoot *root; + uintptr_t brk, ret; + PGBAddrs ga; + + /* Try the identity map first. */ + if (pgb_addr_set(&ga, image_range, commpage_range, true)) { + brk = (uintptr_t)sbrk(0); + if (pgb_try_mmap_set(&ga, 0, brk)) { + guest_base = 0; + return; + } + } + + /* + * Rebuild the address set for non-identity map. + * This differs in the mapping of the guest NULL page. + */ + pgb_addr_set(&ga, image_range, commpage_range, false); + + root = read_self_maps(); + + /* Read brk after we've read the maps, which will malloc. */ + brk = (uintptr_t)sbrk(0); + + if (!root) { + ret = pgb_find_fallback(&ga, align, brk); + } else { + /* + * Reserve the area close to the host brk. + * This will be freed with the rest of the tree. + */ + IntervalTreeNode *b = g_new0(IntervalTreeNode, 1); + b->start = brk; + b->last = brk + 16 * MiB - 1; + interval_tree_insert(b, root); + + ret = pgb_find_itree(&ga, root, align, brk); + free_self_maps(root); + } + + if (ret == -1) { + int w = target_long_bits() / 4; + + error_report("%s: Unable to find a guest_base to satisfy all " + "guest address mapping requirements", image_name); + + for (int i = 0; i < ga.nbounds; ++i) { + error_printf(" %0*" VADDR_PRIx "-%0*" VADDR_PRIx "\n", + w, ga.bounds[i].lo, + w, ga.bounds[i].hi); + } + exit(EXIT_FAILURE); + } + guest_base = ret; +} + +void probe_guest_base(const char *image_name, const PGBRange *image_range, + const PGBRange *commpage_range) +{ + /* In order to use host shmat, we must be able to honor SHMLBA. */ + uintptr_t align = MAX(SHMLBA, TARGET_PAGE_SIZE); + + /* Sanity check the guest binary. */ + if (reserved_va && image_range && image_range->hi > reserved_va) { + error_report("%s: requires more than reserved virtual " + "address space (0x%" VADDR_PRIx " > 0x%lx)", + image_name, image_range->hi, reserved_va); + exit(EXIT_FAILURE); + } + + if (have_guest_base) { + pgb_fixed(image_name, image_range, commpage_range, align); + } else { + pgb_dynamic(image_name, image_range, commpage_range, align); + } + + assert(QEMU_IS_ALIGNED(guest_base, align)); + qemu_log_mask(CPU_LOG_PAGE, "Locating guest address space " + "@ 0x%" PRIx64 "\n", (uint64_t)guest_base); +} diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 0450aa13d8..4ab1a7b78c 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -4,7 +4,6 @@ #include <sys/prctl.h> #include <sys/resource.h> -#include <sys/shm.h> #include "qemu.h" #include "user/tswap-target.h" @@ -13,8 +12,6 @@ #include "exec/mmap-lock.h" #include "exec/translation-block.h" #include "exec/tswap.h" -#include "user/guest-base.h" -#include "user/mmap-min-addr.h" #include "user-internals.h" #include "signal-common.h" #include "loader.h" @@ -25,7 +22,6 @@ #include "qemu/queue.h" #include "qemu/guest-random.h" #include "qemu/units.h" -#include "user/selfmap.h" #include "qemu/lockable.h" #include "qapi/error.h" #include "qemu/error-report.h" @@ -758,310 +754,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, return sp; } -#if !defined(COMMPAGE) && !defined(HAVE_GUEST_COMMPAGE) -bool init_guest_commpage(void) { return true; } -#endif - -/** - * pgb_try_mmap: - * @addr: host start address - * @addr_last: host last address - * @keep: do not unmap the probe region - * - * Return 1 if [@addr, @addr_last] is not mapped in the host, - * return 0 if it is not available to map, and -1 on mmap error. - * If @keep, the region is left mapped on success, otherwise unmapped. - */ -static int pgb_try_mmap(uintptr_t addr, uintptr_t addr_last, bool keep) -{ - size_t size = addr_last - addr + 1; - void *p = mmap((void *)addr, size, PROT_NONE, - MAP_ANONYMOUS | MAP_PRIVATE | - MAP_NORESERVE | MAP_FIXED_NOREPLACE, -1, 0); - int ret; - - if (p == MAP_FAILED) { - return errno == EEXIST ? 0 : -1; - } - ret = p == (void *)addr; - if (!keep || !ret) { - munmap(p, size); - } - return ret; -} - -/** - * pgb_try_mmap_skip_brk(uintptr_t addr, uintptr_t size, uintptr_t brk) - * @addr: host address - * @addr_last: host last address - * @brk: host brk - * - * Like pgb_try_mmap, but additionally reserve some memory following brk. - */ -static int pgb_try_mmap_skip_brk(uintptr_t addr, uintptr_t addr_last, - uintptr_t brk, bool keep) -{ - uintptr_t brk_last = brk + 16 * MiB - 1; - - /* Do not map anything close to the host brk. */ - if (addr <= brk_last && brk <= addr_last) { - return 0; - } - return pgb_try_mmap(addr, addr_last, keep); -} - -/** - * pgb_try_mmap_set: - * @ga: set of guest addrs - * @base: guest_base - * @brk: host brk - * - * Return true if all @ga can be mapped by the host at @base. - * On success, retain the mapping at index 0 for reserved_va. - */ - -typedef struct PGBAddrs { - PGBRange bounds[3]; - int nbounds; -} PGBAddrs; - -static bool pgb_try_mmap_set(const PGBAddrs *ga, uintptr_t base, uintptr_t brk) -{ - for (int i = ga->nbounds - 1; i >= 0; --i) { - if (pgb_try_mmap_skip_brk(ga->bounds[i].lo + base, - ga->bounds[i].hi + base, - brk, i == 0 && reserved_va) <= 0) { - return false; - } - } - return true; -} - -/** - * pgb_addr_set: - * @ga: output set of guest addrs - * @image_range: fixed guest image addresses - * @identity: create for identity mapping - * - * Fill in @ga with the image, COMMPAGE and NULL page. - */ -static bool pgb_addr_set(PGBAddrs *ga, const PGBRange *image_range, - const PGBRange *commpage_range, bool try_identity) -{ - int n; - - /* - * With a low commpage, or a guest mapped very low, - * we may not be able to use the identity map. - */ - if (try_identity) { - if (commpage_range && commpage_range->lo < mmap_min_addr) { - return false; - } - if (image_range && image_range->lo < mmap_min_addr) { - return false; - } - } - - memset(ga, 0, sizeof(*ga)); - n = 0; - - if (reserved_va) { - ga->bounds[n].lo = try_identity ? mmap_min_addr : 0; - ga->bounds[n].hi = reserved_va; - n++; - /* Low COMMPAGE and NULL handled by reserving from 0. */ - } else { - /* Add any low COMMPAGE or NULL page. */ - if (!try_identity || (commpage_range && commpage_range->lo == 0)) { - ga->bounds[n].lo = 0; - ga->bounds[n].hi = TARGET_PAGE_SIZE - 1; - n++; - } - - /* Add the guest image for ET_EXEC. */ - if (image_range) { - ga->bounds[n++] = *image_range; - } - } - - /* Add any high COMMPAGE not covered by reserved_va. */ - if (commpage_range && reserved_va < commpage_range->hi) { - ga->bounds[n].lo = commpage_range->lo & qemu_real_host_page_mask(); - ga->bounds[n].hi = commpage_range->hi; - n++; - } - - ga->nbounds = n; - return true; -} - -static void pgb_fail_in_use(const char *image_name) -{ - error_report("%s: requires virtual address space that is in use " - "(omit the -B option or choose a different value)", - image_name); - exit(EXIT_FAILURE); -} - -static void pgb_fixed(const char *image_name, const PGBRange *image_range, - const PGBRange *commpage_range, uintptr_t align) -{ - PGBAddrs ga; - uintptr_t brk = (uintptr_t)sbrk(0); - - if (!QEMU_IS_ALIGNED(guest_base, align)) { - fprintf(stderr, "Requested guest base %p does not satisfy " - "host minimum alignment (0x%" PRIxPTR ")\n", - (void *)guest_base, align); - exit(EXIT_FAILURE); - } - - if (!pgb_addr_set(&ga, image_range, commpage_range, !guest_base) - || !pgb_try_mmap_set(&ga, guest_base, brk)) { - pgb_fail_in_use(image_name); - } -} - -/** - * pgb_find_fallback: - * - * This is a fallback method for finding holes in the host address space - * if we don't have the benefit of being able to access /proc/self/map. - * It can potentially take a very long time as we can only dumbly iterate - * up the host address space seeing if the allocation would work. - */ -static uintptr_t pgb_find_fallback(const PGBAddrs *ga, uintptr_t align, - uintptr_t brk) -{ - /* TODO: come up with a better estimate of how much to skip. */ - uintptr_t skip = sizeof(uintptr_t) == 4 ? MiB : GiB; - - for (uintptr_t base = skip; ; base += skip) { - base = ROUND_UP(base, align); - if (pgb_try_mmap_set(ga, base, brk)) { - return base; - } - if (base >= -skip) { - return -1; - } - } -} - -static uintptr_t pgb_try_itree(const PGBAddrs *ga, uintptr_t base, - IntervalTreeRoot *root) -{ - for (int i = ga->nbounds - 1; i >= 0; --i) { - uintptr_t s = base + ga->bounds[i].lo; - uintptr_t l = base + ga->bounds[i].hi; - IntervalTreeNode *n; - - if (l < s) { - /* Wraparound. Skip to advance S to mmap_min_addr. */ - return mmap_min_addr - s; - } - - n = interval_tree_iter_first(root, s, l); - if (n != NULL) { - /* Conflict. Skip to advance S to LAST + 1. */ - return n->last - s + 1; - } - } - return 0; /* success */ -} - -static uintptr_t pgb_find_itree(const PGBAddrs *ga, IntervalTreeRoot *root, - uintptr_t align, uintptr_t brk) -{ - uintptr_t last = sizeof(uintptr_t) == 4 ? MiB : GiB; - uintptr_t base, skip; - - while (true) { - base = ROUND_UP(last, align); - if (base < last) { - return -1; - } - - skip = pgb_try_itree(ga, base, root); - if (skip == 0) { - break; - } - - last = base + skip; - if (last < base) { - return -1; - } - } - - /* - * We've chosen 'base' based on holes in the interval tree, - * but we don't yet know if it is a valid host address. - * Because it is the first matching hole, if the host addresses - * are invalid we know there are no further matches. - */ - return pgb_try_mmap_set(ga, base, brk) ? base : -1; -} - -static void pgb_dynamic(const char *image_name, const PGBRange *image_range, - const PGBRange *commpage_range, uintptr_t align) -{ - IntervalTreeRoot *root; - uintptr_t brk, ret; - PGBAddrs ga; - - /* Try the identity map first. */ - if (pgb_addr_set(&ga, image_range, commpage_range, true)) { - brk = (uintptr_t)sbrk(0); - if (pgb_try_mmap_set(&ga, 0, brk)) { - guest_base = 0; - return; - } - } - - /* - * Rebuild the address set for non-identity map. - * This differs in the mapping of the guest NULL page. - */ - pgb_addr_set(&ga, image_range, commpage_range, false); - - root = read_self_maps(); - - /* Read brk after we've read the maps, which will malloc. */ - brk = (uintptr_t)sbrk(0); - - if (!root) { - ret = pgb_find_fallback(&ga, align, brk); - } else { - /* - * Reserve the area close to the host brk. - * This will be freed with the rest of the tree. - */ - IntervalTreeNode *b = g_new0(IntervalTreeNode, 1); - b->start = brk; - b->last = brk + 16 * MiB - 1; - interval_tree_insert(b, root); - - ret = pgb_find_itree(&ga, root, align, brk); - free_self_maps(root); - } - - if (ret == -1) { - int w = TARGET_LONG_BITS / 4; - - error_report("%s: Unable to find a guest_base to satisfy all " - "guest address mapping requirements", image_name); - - for (int i = 0; i < ga.nbounds; ++i) { - error_printf(" %0*" VADDR_PRIx "-%0*" VADDR_PRIx "\n", - w, ga.bounds[i].lo, - w, ga.bounds[i].hi); - } - exit(EXIT_FAILURE); - } - guest_base = ret; -} - -void probe_guest_base(const char *image_name, const PGBRange *image_range) +void linux_probe_guest_base(const char *image_name, + const PGBRange *image_range) { #ifdef COMMPAGE const PGBRange * const commpage_range = &(PGBRange){ @@ -1071,32 +765,15 @@ void probe_guest_base(const char *image_name, const PGBRange *image_range) const PGBRange * const commpage_range = NULL; #endif - /* In order to use host shmat, we must be able to honor SHMLBA. */ - uintptr_t align = MAX(SHMLBA, TARGET_PAGE_SIZE); - - /* Sanity check the guest binary. */ - if (reserved_va && image_range && image_range->hi > reserved_va) { - error_report("%s: requires more than reserved virtual " - "address space (0x%" VADDR_PRIx " > 0x%lx)", - image_name, image_range->hi, reserved_va); - exit(EXIT_FAILURE); - } - - if (have_guest_base) { - pgb_fixed(image_name, image_range, commpage_range, align); - } else { - pgb_dynamic(image_name, image_range, commpage_range, align); - } + probe_guest_base(image_name, image_range, commpage_range); /* Reserve and initialize the commpage. */ +#if defined(COMMPAGE) || defined(HAVE_GUEST_COMMPAGE) if (!init_guest_commpage()) { /* We have already probed for the commpage being free. */ g_assert_not_reached(); } - - assert(QEMU_IS_ALIGNED(guest_base, align)); - qemu_log_mask(CPU_LOG_PAGE, "Locating guest address space " - "@ 0x%" PRIx64 "\n", (uint64_t)guest_base); +#endif } enum { @@ -1345,10 +1022,10 @@ static void load_elf_image(const char *image_name, const ImageSource *src, * Make sure that the low address does not conflict with * MMAP_MIN_ADDR or the QEMU application itself. */ - probe_guest_base(image_name, &range); + linux_probe_guest_base(image_name, &range); } else { /* The binary is dynamic; we still need to select guest_base. */ - probe_guest_base(image_name, NULL); + linux_probe_guest_base(image_name, NULL); /* * Avoid collision with the loader by providing a different diff --git a/linux-user/flatload.c b/linux-user/flatload.c index 45d69040c6..a551f083a4 100644 --- a/linux-user/flatload.c +++ b/linux-user/flatload.c @@ -261,7 +261,7 @@ static int load_flat_file(struct linux_binprm * bprm, /* * Allocate the address space. */ - probe_guest_base(bprm->filename, NULL); + linux_probe_guest_base(bprm->filename, NULL); /* * there are a couple of cases here, the separate code/data diff --git a/common-user/meson.build b/common-user/meson.build index 5e041de55e..2d4ffe07d3 100644 --- a/common-user/meson.build +++ b/common-user/meson.build @@ -6,6 +6,7 @@ common_user_inc += include_directories('host/' / host_arch) user_ss.add(files( 'mmap-min-addr.c', + 'probe-guest-base.c', 'safe-syscall.S', 'safe-syscall-error.c', 'selfmap.c', -- 2.43.0
