From: Peter Maydell <peter.maydell@linaro.org>
To: Anthony Liguori <aliguori@us.ibm.com>, Blue Swirl <blauwirbel@gmail.com>
Cc: Riku Voipio <riku.voipio@iki.fi>, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 08/10] linux-user: Factor out guest space probing into a function
Date: Tue, 14 Aug 2012 10:40:34 +0100 [thread overview]
Message-ID: <1344937236-611-9-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1344937236-611-1-git-send-email-peter.maydell@linaro.org>
From: Meador Inge <meadori@codesourcery.com>
Signed-off-by: Meador Inge <meadori@codesourcery.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
linux-user/elfload.c | 110 +++++++++++++++++++++++++++++++++++---------------
linux-user/qemu.h | 13 ++++++
2 files changed, 90 insertions(+), 33 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 6b622d4..cbc7617 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1426,6 +1426,73 @@ bool guest_validate_base(unsigned long guest_base)
}
#endif
+unsigned long init_guest_space(unsigned long host_start,
+ unsigned long host_size,
+ unsigned long guest_start,
+ bool fixed)
+{
+ unsigned long current_start, real_start;
+ int flags;
+
+ assert(host_start || host_size);
+
+ /* If just a starting address is given, then just verify that
+ * address. */
+ if (host_start && !host_size) {
+ if (guest_validate_base(host_start)) {
+ return host_start;
+ } else {
+ return (unsigned long)-1;
+ }
+ }
+
+ /* Setup the initial flags and start address. */
+ current_start = host_start & qemu_host_page_mask;
+ flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;
+ if (fixed) {
+ flags |= MAP_FIXED;
+ }
+
+ /* Otherwise, a non-zero size region of memory needs to be mapped
+ * and validated. */
+ while (1) {
+ /* Do not use mmap_find_vma here because that is limited to the
+ * guest address space. We are going to make the
+ * guest address space fit whatever we're given.
+ */
+ real_start = (unsigned long)
+ mmap((void *)current_start, host_size, PROT_NONE, flags, -1, 0);
+ if (real_start == (unsigned long)-1) {
+ return (unsigned long)-1;
+ }
+
+ if ((real_start == current_start)
+ && guest_validate_base(real_start - guest_start)) {
+ break;
+ }
+
+ /* That address didn't work. Unmap and try a different one.
+ * The address the host picked because is typically right at
+ * the top of the host address space and leaves the guest with
+ * no usable address space. Resort to a linear search. We
+ * already compensated for mmap_min_addr, so this should not
+ * happen often. Probably means we got unlucky and host
+ * address space randomization put a shared library somewhere
+ * inconvenient.
+ */
+ munmap((void *)real_start, host_size);
+ current_start += qemu_host_page_size;
+ if (host_start == current_start) {
+ /* Theoretically possible if host doesn't have any suitably
+ * aligned areas. Normally the first mmap will fail.
+ */
+ return (unsigned long)-1;
+ }
+ }
+
+ return real_start;
+}
+
static void probe_guest_base(const char *image_name,
abi_ulong loaddr, abi_ulong hiaddr)
{
@@ -1452,46 +1519,23 @@ static void probe_guest_base(const char *image_name,
}
}
host_size = hiaddr - loaddr;
- while (1) {
- /* Do not use mmap_find_vma here because that is limited to the
- guest address space. We are going to make the
- guest address space fit whatever we're given. */
- real_start = (unsigned long)
- mmap((void *)host_start, host_size, PROT_NONE,
- MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
- if (real_start == (unsigned long)-1) {
- goto exit_perror;
- }
- guest_base = real_start - loaddr;
- if ((real_start == host_start) &&
- guest_validate_base(guest_base)) {
- break;
- }
- /* That address didn't work. Unmap and try a different one.
- The address the host picked because is typically right at
- the top of the host address space and leaves the guest with
- no usable address space. Resort to a linear search. We
- already compensated for mmap_min_addr, so this should not
- happen often. Probably means we got unlucky and host
- address space randomization put a shared library somewhere
- inconvenient. */
- munmap((void *)real_start, host_size);
- host_start += qemu_host_page_size;
- if (host_start == loaddr) {
- /* Theoretically possible if host doesn't have any suitably
- aligned areas. Normally the first mmap will fail. */
- errmsg = "Unable to find space for application";
- goto exit_errmsg;
- }
+
+ /* Setup the initial guest memory space with ranges gleaned from
+ * the ELF image that is being loaded.
+ */
+ real_start = init_guest_space(host_start, host_size, loaddr, false);
+ if (real_start == (unsigned long)-1) {
+ errmsg = "Unable to find space for application";
+ goto exit_errmsg;
}
+ guest_base = real_start - loaddr;
+
qemu_log("Relocating guest address space from 0x"
TARGET_ABI_FMT_lx " to 0x%lx\n",
loaddr, real_start);
}
return;
-exit_perror:
- errmsg = strerror(errno);
exit_errmsg:
fprintf(stderr, "%s: %s\n", image_name, errmsg);
exit(-1);
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 7b299b7..7d4e23e 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -210,6 +210,19 @@ void fork_end(int child);
*/
bool guest_validate_base(unsigned long guest_base);
+/* Creates the initial guest address space in the host memory space using
+ * the given host start address hint and size. The guest_start parameter
+ * specifies the start address of the guest space. guest_base will be the
+ * difference between the host start address computed by this function and
+ * guest_start. If fixed is specified, then the mapped address space must
+ * start at host_start. The real start address of the mapped memory space is
+ * returned or -1 if there was an error.
+ */
+unsigned long init_guest_space(unsigned long host_start,
+ unsigned long host_size,
+ unsigned long guest_start,
+ bool fixed);
+
#include "qemu-log.h"
/* strace.c */
--
1.7.9.5
next prev parent reply other threads:[~2012-08-14 9:56 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-14 9:40 [Qemu-devel] [PULL for-1.2 00/10] linux-user queue Peter Maydell
2012-08-14 9:40 ` [Qemu-devel] [PATCH 01/10] linux-user: Fix incorrect TARGET_BLKBSZGET, TARGET_BLKBSZSET Peter Maydell
2012-08-14 9:40 ` [Qemu-devel] [PATCH 02/10] linux-user: Fix SNDCTL_DSP_MAP{IN, OUT}BUF ioctl definitions Peter Maydell
2012-08-14 9:40 ` [Qemu-devel] [PATCH 03/10] linux-user: Move target_to_host_errno_table[] setup out of ioctl loop Peter Maydell
2012-08-14 18:27 ` Blue Swirl
2012-08-14 18:38 ` Peter Maydell
2012-08-14 18:58 ` Blue Swirl
2012-08-14 19:35 ` Peter Maydell
2012-08-14 9:40 ` [Qemu-devel] [PATCH 04/10] linux-user: pass sockaddr from host to target Peter Maydell
2012-08-14 9:40 ` [Qemu-devel] [PATCH 05/10] linux-user: make do_setsockopt support SOL_RAW ICMP_FILTER socket option Peter Maydell
2012-08-14 9:40 ` [Qemu-devel] [PATCH 06/10] linux-user: make host_to_target_cmsg support SO_TIMESTAMP cmsg_type Peter Maydell
2012-08-14 9:40 ` [Qemu-devel] [PATCH 07/10] flatload: fix bss clearing Peter Maydell
2012-08-14 9:40 ` Peter Maydell [this message]
2012-08-14 9:40 ` [Qemu-devel] [PATCH 09/10] linux-user: Use init_guest_space when -R and -B are specified Peter Maydell
2012-08-14 9:40 ` [Qemu-devel] [PATCH 10/10] linux-user: ARM: Ignore immediate value for svc in thumb mode Peter Maydell
2012-08-14 19:56 ` [Qemu-devel] [PULL for-1.2 00/10] linux-user queue Blue Swirl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1344937236-611-9-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=aliguori@us.ibm.com \
--cc=blauwirbel@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=riku.voipio@iki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).