[PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-03-30 Thread Lirong Yuan
This allows gdb to access the target’s auxiliary vector,
which can be helpful for telling system libraries important details
about the hardware, operating system, and process.

Signed-off-by: Lirong Yuan 
---
 gdbstub.c | 56 +++
 1 file changed, 56 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 013fb1ac0f..f7a08263c6 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2125,6 +2125,12 @@ static void handle_query_supported(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
 }
 
+#ifdef CONFIG_USER_ONLY
+if (gdbserver_state.c_cpu->opaque) {
+g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
+}
+#endif
+
 if (gdb_ctx->num_params &&
 strstr(gdb_ctx->params[0].data, "multiprocess+")) {
 gdbserver_state.multiprocess = true;
@@ -2186,6 +2192,48 @@ static void handle_query_xfer_features(GdbCmdContext 
*gdb_ctx, void *user_ctx)
   gdbserver_state.str_buf->len, true);
 }
 
+#ifdef CONFIG_USER_ONLY
+static void handle_query_xfer_auxv(GdbCmdContext *gdb_ctx, void *user_ctx)
+{
+TaskState *ts;
+unsigned long offset, len, saved_auxv, auxv_len;
+const char *mem;
+
+if (gdb_ctx->num_params < 2) {
+put_packet("E22");
+return;
+}
+
+offset = gdb_ctx->params[0].val_ul;
+len = gdb_ctx->params[1].val_ul;
+
+ts = gdbserver_state.c_cpu->opaque;
+saved_auxv = ts->info->saved_auxv;
+auxv_len = ts->info->auxv_len;
+mem = (const char *)(saved_auxv + offset);
+
+if (offset >= auxv_len) {
+put_packet("E22");
+return;
+}
+
+if (len > (MAX_PACKET_LENGTH - 5) / 2) {
+len = (MAX_PACKET_LENGTH - 5) / 2;
+}
+
+if (len < auxv_len - offset) {
+g_string_assign(gdbserver_state.str_buf, "m");
+memtox(gdbserver_state.str_buf, mem, len);
+} else {
+g_string_assign(gdbserver_state.str_buf, "l");
+memtox(gdbserver_state.str_buf, mem, auxv_len - offset);
+}
+
+put_packet_binary(gdbserver_state.str_buf->str,
+  gdbserver_state.str_buf->len, true);
+}
+#endif
+
 static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
 {
 put_packet(GDB_ATTACHED);
@@ -2291,6 +2339,14 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
 .cmd_startswith = 1,
 .schema = "s:l,l0"
 },
+#ifdef CONFIG_USER_ONLY
+{
+.handler = handle_query_xfer_auxv,
+.cmd = "Xfer:auxv:read:",
+.cmd_startswith = 1,
+.schema = "l,l0"
+},
+#endif
 {
 .handler = handle_query_attached,
 .cmd = "Attached:",
-- 
2.26.0.rc2.310.g2932bb562d-goog




Re: [PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-03-30 Thread Lirong Yuan
On Sat, Mar 21, 2020 at 6:56 AM Alex Bennée  wrote:

>
> Lirong Yuan  writes:
>
> > On Fri, Mar 20, 2020 at 2:17 AM Alex Bennée 
> wrote:
> 
> >>
> >> Sorry I missed this on my radar. There was a minor re-factor of gdbstub
> >> that was just merged which will mean this patch needs a re-base to use
> >> g_string_* functions to expand stings.
> >>
> >> Also we have some simple gdbstub tests now - could we come up with a
> >> multiarch gdbstub test to verify this is working properly?
> >>
> 
> > For sure, I will re-base this patch to use g_string_* functions.
> >
> > Currently we are using qemu aarch64. I am not sure how to do this yet,
> but
> > I could try to add something to
> > https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub
>
> If the auxv support is appropriate to all linux-user targets you can
> plumb it into the multiarch tests - you can even use the existing
> binaries.
>
> So you need:
>
>   - a stanza in the makefiles to launch the test (see
> tests/tcg/aarch64/Makefile.target)
>
>   - a .py test script that manipulates gdbstub to check things are working
>
> So something like:
>
> .PHONY: gdbstub-foo-binary
> run-gdbstub-foo-binary: foo-binary
> $(call run-test, $@, $(GDB_SCRIPT) \
> --gdb $(HAVE_GDB_BIN) \
> --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
> --bin $< --test $(MULTIARCH_SRC)/gdbstub/test-foo.py, \
> "basic gdbstub FOO support")
>
>
> >
> > Does this sound good?
>
> Hope that helps.
>
> >
> > Thanks!
> > Lirong
>
>
> --
> Alex Bennée
>

Hi Alex,

Thanks for the instructions, very helpful!

I rebased this patch to use g_string_* functions, and the link to patchwork
is:
http://patchwork.ozlabs.org/patch/1264125/
Could you help take another look?

Regarding testing, I looked at some instructions for running tests, e.g.
https://github.com/qemu/qemu/blob/master/docs/devel/testing.rst
https://wiki.qemu.org/Testing
However I still could not get the tests for aarch64 to run. Do you know how
to run the aarch64 or multi-arch tests?

Also there aren't any existing gdb stub tests that try to read
uninterpreted bytes from the target’s special data area identified by a
keyword:
https://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html#qXfer-auxiliary-vector-read
I looked at some other gdb stub tests, but they did not seem to send any
queries:
https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub
So I am not sure how to set up one for "Xfer:auxv:read:" packets...
Are there plans to add more tests for other packets like
"Xfer:features:read:"?
I'd be happy to add a test if there is an example of how to do it. :)

Thanks,
Lirong


Re: [PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-03-30 Thread Lirong Yuan
On Mon, Mar 30, 2020 at 12:47 PM Alex Bennée  wrote:

>
> Lirong Yuan  writes:
>
> > On Sat, Mar 21, 2020 at 6:56 AM Alex Bennée 
> wrote:
> >
> >>
> >> Lirong Yuan  writes:
> >>
> >> > On Fri, Mar 20, 2020 at 2:17 AM Alex Bennée 
> >> wrote:
> >> 
> >> >>
> >> >> Sorry I missed this on my radar. There was a minor re-factor of
> gdbstub
> >> >> that was just merged which will mean this patch needs a re-base to
> use
> >> >> g_string_* functions to expand stings.
> >> >>
> >> >> Also we have some simple gdbstub tests now - could we come up with a
> >> >> multiarch gdbstub test to verify this is working properly?
> >> >>
> >> 
> >> > For sure, I will re-base this patch to use g_string_* functions.
> >> >
> >> > Currently we are using qemu aarch64. I am not sure how to do this yet,
> >> but
> >> > I could try to add something to
> >> > https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub
> >>
> >> If the auxv support is appropriate to all linux-user targets you can
> >> plumb it into the multiarch tests - you can even use the existing
> >> binaries.
> >>
> >> So you need:
> >>
> >>   - a stanza in the makefiles to launch the test (see
> >> tests/tcg/aarch64/Makefile.target)
> >>
> >>   - a .py test script that manipulates gdbstub to check things are
> working
> >>
> >> So something like:
> >>
> >> .PHONY: gdbstub-foo-binary
> >> run-gdbstub-foo-binary: foo-binary
> >> $(call run-test, $@, $(GDB_SCRIPT) \
> >> --gdb $(HAVE_GDB_BIN) \
> >> --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
> >> --bin $< --test $(MULTIARCH_SRC)/gdbstub/test-foo.py, \
> >> "basic gdbstub FOO support")
> >>
> >>
> >> >
> >> > Does this sound good?
> >>
> >> Hope that helps.
> >>
> >> >
> >> > Thanks!
> >> > Lirong
> >>
> >>
> >> --
> >> Alex Bennée
> >>
> >
> > Hi Alex,
> >
> > Thanks for the instructions, very helpful!
> >
> > I rebased this patch to use g_string_* functions, and the link to
> patchwork
> > is:
> > http://patchwork.ozlabs.org/patch/1264125/
> > Could you help take another look?
> >
> > Regarding testing, I looked at some instructions for running tests, e.g.
> > https://github.com/qemu/qemu/blob/master/docs/devel/testing.rst
> > https://wiki.qemu.org/Testing
> > However I still could not get the tests for aarch64 to run. Do you know
> how
> > to run the aarch64 or multi-arch tests?
>
> The aarch64 ones run with "make run-tcg-tests-aarch64-linux-user" add
> V=1 to see the details.
>
> > Also there aren't any existing gdb stub tests that try to read
> > uninterpreted bytes from the target’s special data area identified by a
> > keyword:
> >
> https://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html#qXfer-auxiliary-vector-read
> > I looked at some other gdb stub tests, but they did not seem to send any
> > queries:
> > https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub
> > So I am not sure how to set up one for "Xfer:auxv:read:" packets...
> > Are there plans to add more tests for other packets like
> > "Xfer:features:read:"?
> > I'd be happy to add a test if there is an example of how to do it. :)
>
> What would you do from a normal gdb command line. At the very least you
> run the same command with gdb.execute(), e.g.:
>
>   gdb.execute("set confirm off")
>
> is the same as typing
>
>   set confirm off
>
> at the gdb command prompt.
>
> >
> > Thanks,
> > Lirong
>
>
> --
> Alex Bennée
>

Hey Alex,

I tried to run the test but they were skipped. Do you know if there's any
other flag that needs to be set?

$ make run-tcg-tests-aarch64-linux-user
make[1]: Entering directory '/usr/local/google/home/yuanzi/qemu/slirp'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/usr/local/google/home/yuanzi/qemu/slirp'
  BUILD   TCG tests for aarch64-linux-user
  BUILD   aarch64-linux-user guest-tests SKIPPED
  RUN TCG tests for aarch64-linux-user
  RUN tests for aarch64-linux-user SKIPPED

I don't think any command needs to be run. It should just send the query
automatically.
Could we assume that it will work the same in the test?


Re: [PATCH] linux-user: Add AT_EXECFN and AT_EXECFD auxval

2020-02-28 Thread Lirong Yuan
On Fri, Feb 21, 2020 at 12:29 PM Lirong Yuan  wrote:
>
> This change adds the support for AT_EXECFN and AT_EXECFD auxval.
>
> Signed-off-by: Lirong Yuan 
> ---
>  linux-user/elfload.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index f3080a1635..7e0f3042f1 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -1568,7 +1568,7 @@ struct exec
>   ~(abi_ulong)(TARGET_ELF_EXEC_PAGESIZE-1))
>  #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
>
> -#define DLINFO_ITEMS 15
> +#define DLINFO_ITEMS 17
>
>  static inline void memcpy_fromfs(void * to, const void * from, unsigned long 
> n)
>  {
> @@ -1888,11 +1888,14 @@ static abi_ulong loader_build_fdpic_loadmap(struct 
> image_info *info, abi_ulong s
>  return sp;
>  }
>
> -static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
> +static abi_ulong create_elf_tables(struct linux_binprm *bprm,
> struct elfhdr *exec,
> struct image_info *info,
> struct image_info *interp_info)
>  {
> +abi_ulong p = bprm->p;
> +int argc = bprm->argc;
> +int envc = bprm->envc;
>  abi_ulong sp;
>  abi_ulong u_argc, u_argv, u_envp, u_auxv;
>  int size;
> @@ -2032,6 +2035,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int 
> argc, int envc,
>  NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
>  NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
>  NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
> +NEW_AUX_ENT(AT_EXECFN, info->file_string);
> +NEW_AUX_ENT(AT_EXECFD, bprm->fd);
>
>  #ifdef ELF_HWCAP2
>  NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
> @@ -2870,8 +2875,8 @@ int load_elf_binary(struct linux_binprm *bprm, struct 
> image_info *info)
>  #endif
>  }
>
> -bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex,
> -info, (elf_interpreter ? &interp_info : 
> NULL));
> +bprm->p = create_elf_tables(bprm, &elf_ex, info,
> +(elf_interpreter ? &interp_info : NULL));
>  info->start_stack = bprm->p;
>
>  /* If we have an interpreter, set that as the program's entry point.
> --
> 2.25.0.265.gbab2e86ba0-goog
>

Friendly ping~

Link to the page for the patch on patchwork:
http://patchwork.ozlabs.org/patch/1242331/



Re: [PATCH] linux-user: Add an argument QEMU_MMAP_BASE to set custom mmap base address in qemu user mode

2020-02-28 Thread Lirong Yuan
On Fri, Feb 21, 2020 at 5:09 PM Lirong Yuan  wrote:
>
> This change allows us to set custom base address for guest programs. It is 
> needed to allow qemu to work with Thread Sanitizer (TSan), which has specific 
> boundary definitions for memory mappings on different platforms:
> https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h
>
> Signed-off-by: Lirong Yuan 
> ---
>  linux-user/main.c | 12 
>  linux-user/mmap.c |  3 ++-
>  linux-user/qemu.h |  5 +
>  3 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/linux-user/main.c b/linux-user/main.c
> index fba833aac9..c01af6bfee 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -336,6 +336,16 @@ static void handle_arg_guest_base(const char *arg)
>  have_guest_base = 1;
>  }
>
> +static void handle_arg_mmap_base(const char *arg)
> +{
> +int err = qemu_strtoul(arg, NULL, 0, &mmap_base);
> +if (err) {
> +fprintf(stderr, "Invalid mmap_base: %s, err: %d\n", arg, err);
> +exit(EXIT_FAILURE);
> +}
> +mmap_next_start = mmap_base;
> +}
> +
>  static void handle_arg_reserved_va(const char *arg)
>  {
>  char *p;
> @@ -440,6 +450,8 @@ static const struct qemu_argument arg_table[] = {
>   "uname",  "set qemu uname release string to 'uname'"},
>  {"B",  "QEMU_GUEST_BASE",  true,  handle_arg_guest_base,
>   "address","set guest_base address to 'address'"},
> +{"mmap_base",  "QEMU_MMAP_BASE",   true,  handle_arg_mmap_base,
> + "",   "begin allocating guest pages at this host address"},
>  {"R",  "QEMU_RESERVED_VA", true,  handle_arg_reserved_va,
>   "size",   "reserve 'size' bytes for guest virtual address space"},
>  {"d",  "QEMU_LOG", true,  handle_arg_log,
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index 8685f02e7e..3f35543acf 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -189,6 +189,7 @@ static int mmap_frag(abi_ulong real_start,
>  # define TASK_UNMAPPED_BASE  0x4000
>  #endif
>  abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
> +abi_ulong mmap_base = TASK_UNMAPPED_BASE;
>
>  unsigned long last_brk;
>
> @@ -299,7 +300,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, 
> abi_ulong align)
>
>  if ((addr & (align - 1)) == 0) {
>  /* Success.  */
> -if (start == mmap_next_start && addr >= TASK_UNMAPPED_BASE) {
> +if (start == mmap_next_start && addr >= mmap_base) {
>  mmap_next_start = addr + size;
>  }
>  return addr;
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 560a68090e..83c00cfea2 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -161,6 +161,11 @@ void task_settid(TaskState *);
>  void stop_all_tasks(void);
>  extern const char *qemu_uname_release;
>  extern unsigned long mmap_min_addr;
> +/*
> + * mmap_base is minimum address to use when allocating guest pages. All guest
> + * pages will be allocated at this (guest) address or higher addresses.
> + */
> +extern abi_ulong mmap_base;
>
>  /* ??? See if we can avoid exposing so much of the loader internals.  */
>
> --
> 2.25.0.265.gbab2e86ba0-goog
>

Friendly ping~

Link to the page for the patch on patchwork:
http://patchwork.ozlabs.org/patch/1242370/



Re: [PATCH] linux-user: Add an argument QEMU_MMAP_BASE to set custom mmap base address in qemu user mode

2020-03-02 Thread Lirong Yuan
On Mon, Mar 2, 2020 at 6:56 AM Laurent Vivier  wrote:
>
> Le 29/02/2020 à 01:43, Lirong Yuan a écrit :
> > On Fri, Feb 21, 2020 at 5:09 PM Lirong Yuan  wrote:
> >>
> >> This change allows us to set custom base address for guest programs. It is 
> >> needed to allow qemu to work with Thread Sanitizer (TSan), which has 
> >> specific boundary definitions for memory mappings on different platforms:
> >> https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h
>
> Could you give more details and some examples?
>
> Thanks,
> Laurent
>
> >> Signed-off-by: Lirong Yuan 
> >> ---
> >>  linux-user/main.c | 12 
> >>  linux-user/mmap.c |  3 ++-
> >>  linux-user/qemu.h |  5 +
> >>  3 files changed, 19 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/linux-user/main.c b/linux-user/main.c
> >> index fba833aac9..c01af6bfee 100644
> >> --- a/linux-user/main.c
> >> +++ b/linux-user/main.c
> >> @@ -336,6 +336,16 @@ static void handle_arg_guest_base(const char *arg)
> >>  have_guest_base = 1;
> >>  }
> >>
> >> +static void handle_arg_mmap_base(const char *arg)
> >> +{
> >> +int err = qemu_strtoul(arg, NULL, 0, &mmap_base);
> >> +if (err) {
> >> +fprintf(stderr, "Invalid mmap_base: %s, err: %d\n", arg, err);
> >> +exit(EXIT_FAILURE);
> >> +}
> >> +mmap_next_start = mmap_base;
> >> +}
> >> +
> >>  static void handle_arg_reserved_va(const char *arg)
> >>  {
> >>  char *p;
> >> @@ -440,6 +450,8 @@ static const struct qemu_argument arg_table[] = {
> >>   "uname",  "set qemu uname release string to 'uname'"},
> >>  {"B",  "QEMU_GUEST_BASE",  true,  handle_arg_guest_base,
> >>   "address","set guest_base address to 'address'"},
> >> +{"mmap_base",  "QEMU_MMAP_BASE",   true,  handle_arg_mmap_base,
> >> + "",   "begin allocating guest pages at this host address"},
> >>  {"R",  "QEMU_RESERVED_VA", true,  handle_arg_reserved_va,
> >>   "size",   "reserve 'size' bytes for guest virtual address 
> >> space"},
> >>  {"d",  "QEMU_LOG", true,  handle_arg_log,
> >> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> >> index 8685f02e7e..3f35543acf 100644
> >> --- a/linux-user/mmap.c
> >> +++ b/linux-user/mmap.c
> >> @@ -189,6 +189,7 @@ static int mmap_frag(abi_ulong real_start,
> >>  # define TASK_UNMAPPED_BASE  0x4000
> >>  #endif
> >>  abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
> >> +abi_ulong mmap_base = TASK_UNMAPPED_BASE;
> >>
> >>  unsigned long last_brk;
> >>
> >> @@ -299,7 +300,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong 
> >> size, abi_ulong align)
> >>
> >>  if ((addr & (align - 1)) == 0) {
> >>  /* Success.  */
> >> -if (start == mmap_next_start && addr >= 
> >> TASK_UNMAPPED_BASE) {
> >> +if (start == mmap_next_start && addr >= mmap_base) {
> >>  mmap_next_start = addr + size;
> >>  }
> >>  return addr;
> >> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> >> index 560a68090e..83c00cfea2 100644
> >> --- a/linux-user/qemu.h
> >> +++ b/linux-user/qemu.h
> >> @@ -161,6 +161,11 @@ void task_settid(TaskState *);
> >>  void stop_all_tasks(void);
> >>  extern const char *qemu_uname_release;
> >>  extern unsigned long mmap_min_addr;
> >> +/*
> >> + * mmap_base is minimum address to use when allocating guest pages. All 
> >> guest
> >> + * pages will be allocated at this (guest) address or higher addresses.
> >> + */
> >> +extern abi_ulong mmap_base;
> >>
> >>  /* ??? See if we can avoid exposing so much of the loader internals.  */
> >>
> >> --
> >> 2.25.0.265.gbab2e86ba0-goog
> >>
> >
> > Friendly ping~
> >
> > Link to the page for the patch on patchwork:
> > http://patchwork.ozlabs.org/patch/1242370/
> >
>

Hi Laurent,

Sure! We tried to run a program with TSAN enabled
(h

Re: [PATCH] linux-user: Add AT_EXECFN and AT_EXECFD auxval

2020-03-02 Thread Lirong Yuan
On Mon, Mar 2, 2020 at 6:39 AM Laurent Vivier  wrote:
>
> Le 21/02/2020 à 21:28, Lirong Yuan a écrit :
> > This change adds the support for AT_EXECFN and AT_EXECFD auxval.
>
> Why do we need AT_EXECFD?
>
> AT_EXECFD is normally only used with binfmt_misc so I don't see any use
> cases for it with QEMU.
>
> For AT_EXECFN, according to kernel commit
>
>   651910874633 execve filename: document and export via auxiliary vector
>
> It sould be like readlink("/proc/self/exe",), and thus I think we should
> use realpath() like we have in syscall.c for TARGET_NR_readlink:
>
>  8843 case TARGET_NR_readlink:
> ...
>  8854 char real[PATH_MAX], *temp;
>  8855 temp = realpath(exec_path, real);
> ...
>
> Thanks,
> Laurent
>
> >
> > Signed-off-by: Lirong Yuan 
> > ---
> >  linux-user/elfload.c | 13 +
> >  1 file changed, 9 insertions(+), 4 deletions(-)
> >
> > diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> > index f3080a1635..7e0f3042f1 100644
> > --- a/linux-user/elfload.c
> > +++ b/linux-user/elfload.c
> > @@ -1568,7 +1568,7 @@ struct exec
> >   ~(abi_ulong)(TARGET_ELF_EXEC_PAGESIZE-1))
> >  #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
> >
> > -#define DLINFO_ITEMS 15
> > +#define DLINFO_ITEMS 17
> >
> >  static inline void memcpy_fromfs(void * to, const void * from, unsigned 
> > long n)
> >  {
> > @@ -1888,11 +1888,14 @@ static abi_ulong loader_build_fdpic_loadmap(struct 
> > image_info *info, abi_ulong s
> >  return sp;
> >  }
> >
> > -static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
> > +static abi_ulong create_elf_tables(struct linux_binprm *bprm,
> > struct elfhdr *exec,
> > struct image_info *info,
> > struct image_info *interp_info)
> >  {
> > +abi_ulong p = bprm->p;
> > +int argc = bprm->argc;
> > +int envc = bprm->envc;
> >  abi_ulong sp;
> >  abi_ulong u_argc, u_argv, u_envp, u_auxv;
> >  int size;
> > @@ -2032,6 +2035,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int 
> > argc, int envc,
> >  NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
> >  NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
> >  NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
> > +NEW_AUX_ENT(AT_EXECFN, info->file_string);
> > +NEW_AUX_ENT(AT_EXECFD, bprm->fd);
> >
> >  #ifdef ELF_HWCAP2
> >  NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
> > @@ -2870,8 +2875,8 @@ int load_elf_binary(struct linux_binprm *bprm, struct 
> > image_info *info)
> >  #endif
> >  }
> >
> > -bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex,
> > -info, (elf_interpreter ? &interp_info : 
> > NULL));
> > +bprm->p = create_elf_tables(bprm, &elf_ex, info,
> > +(elf_interpreter ? &interp_info : NULL));
> >  info->start_stack = bprm->p;
> >
> >  /* If we have an interpreter, set that as the program's entry point.
> >
>

Hi Laurent,

I added support for AT_EXECFD because I thought it might be useful to
implement all types that getauxval could take as an argument.
Would you prefer that it be removed?

For AT_EXECFN, there are two questions that we considered:
1) What should it return?
Since QEMU is emulating running the guest program, the function should
return the file name of the guest program (info->file_string), rather
than the QEMU program itself, which we get from
qemu_getauxval(AT_EXECFN).

2) Should it return the full path or as is?
We tested the behavior of getauxval with a simple test program on
Linux, and it turned out that it returned file path as is. For
example,
$ ./test
getauxval(AT_EXECFN): ./test
$ /usr/local/home/tmp/test
getauxval(AT_EXECFN): /usr/local/home/tmp/test

It would seem that the current solution is working as intended.

Thanks,
Lirong



[PATCH v2] linux-user: Add AT_EXECFN auxval

2020-03-02 Thread Lirong Yuan
This change adds the support for AT_EXECFN auxval.

Signed-off-by: Lirong Yuan 
---
Changelog since v1:
- remove implementation for AT_EXECFD auxval.

 linux-user/elfload.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index db748c5877..8198be0446 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1573,7 +1573,7 @@ struct exec
  ~(abi_ulong)(TARGET_ELF_EXEC_PAGESIZE-1))
 #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
 
-#define DLINFO_ITEMS 15
+#define DLINFO_ITEMS 16
 
 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
 {
@@ -2037,6 +2037,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
 NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
 NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
 NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
+NEW_AUX_ENT(AT_EXECFN, info->file_string);
 
 #ifdef ELF_HWCAP2
 NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
-- 
2.25.0.265.gbab2e86ba0-goog




Re: [PATCH] linux-user: Add an argument QEMU_MMAP_BASE to set custom mmap base address in qemu user mode

2020-03-02 Thread Lirong Yuan
On Mon, Mar 2, 2020 at 10:39 AM Laurent Vivier  wrote:
>
> Le 02/03/2020 à 18:53, Lirong Yuan a écrit :
> > On Mon, Mar 2, 2020 at 6:56 AM Laurent Vivier  wrote:
> >>
> >> Le 29/02/2020 à 01:43, Lirong Yuan a écrit :
> >>> On Fri, Feb 21, 2020 at 5:09 PM Lirong Yuan  wrote:
> >>>>
> >>>> This change allows us to set custom base address for guest programs. It 
> >>>> is needed to allow qemu to work with Thread Sanitizer (TSan), which has 
> >>>> specific boundary definitions for memory mappings on different platforms:
> >>>> https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h
> >>
> >> Could you give more details and some examples?
> >>
> >> Thanks,
> >> Laurent
> >>
> >>>> Signed-off-by: Lirong Yuan 
> >>>> ---
> >>>>  linux-user/main.c | 12 
> >>>>  linux-user/mmap.c |  3 ++-
> >>>>  linux-user/qemu.h |  5 +
> >>>>  3 files changed, 19 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/linux-user/main.c b/linux-user/main.c
> >>>> index fba833aac9..c01af6bfee 100644
> >>>> --- a/linux-user/main.c
> >>>> +++ b/linux-user/main.c
> >>>> @@ -336,6 +336,16 @@ static void handle_arg_guest_base(const char *arg)
> >>>>  have_guest_base = 1;
> >>>>  }
> >>>>
> >>>> +static void handle_arg_mmap_base(const char *arg)
> >>>> +{
> >>>> +int err = qemu_strtoul(arg, NULL, 0, &mmap_base);
> >>>> +if (err) {
> >>>> +fprintf(stderr, "Invalid mmap_base: %s, err: %d\n", arg, err);
> >>>> +exit(EXIT_FAILURE);
> >>>> +}
> >>>> +mmap_next_start = mmap_base;
> >>>> +}
> >>>> +
> >>>>  static void handle_arg_reserved_va(const char *arg)
> >>>>  {
> >>>>  char *p;
> >>>> @@ -440,6 +450,8 @@ static const struct qemu_argument arg_table[] = {
> >>>>   "uname",  "set qemu uname release string to 'uname'"},
> >>>>  {"B",  "QEMU_GUEST_BASE",  true,  handle_arg_guest_base,
> >>>>   "address","set guest_base address to 'address'"},
> >>>> +{"mmap_base",  "QEMU_MMAP_BASE",   true,  handle_arg_mmap_base,
> >>>> + "",   "begin allocating guest pages at this host address"},
> >>>>  {"R",  "QEMU_RESERVED_VA", true,  handle_arg_reserved_va,
> >>>>   "size",   "reserve 'size' bytes for guest virtual address 
> >>>> space"},
> >>>>  {"d",  "QEMU_LOG", true,  handle_arg_log,
> >>>> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> >>>> index 8685f02e7e..3f35543acf 100644
> >>>> --- a/linux-user/mmap.c
> >>>> +++ b/linux-user/mmap.c
> >>>> @@ -189,6 +189,7 @@ static int mmap_frag(abi_ulong real_start,
> >>>>  # define TASK_UNMAPPED_BASE  0x4000
> >>>>  #endif
> >>>>  abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
> >>>> +abi_ulong mmap_base = TASK_UNMAPPED_BASE;
> >>>>
> >>>>  unsigned long last_brk;
> >>>>
> >>>> @@ -299,7 +300,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong 
> >>>> size, abi_ulong align)
> >>>>
> >>>>  if ((addr & (align - 1)) == 0) {
> >>>>  /* Success.  */
> >>>> -if (start == mmap_next_start && addr >= 
> >>>> TASK_UNMAPPED_BASE) {
> >>>> +if (start == mmap_next_start && addr >= mmap_base) {
> >>>>  mmap_next_start = addr + size;
> >>>>  }
> >>>>  return addr;
> >>>> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> >>>> index 560a68090e..83c00cfea2 100644
> >>>> --- a/linux-user/qemu.h
> >>>> +++ b/linux-user/qemu.h
> >>>> @@ -161,6 +161,11 @@ void task_settid(TaskState *);
> >>>>  void stop_all_tasks(void);
> >>>>  extern c

Re: [PATCH] linux-user: Add AT_EXECFN and AT_EXECFD auxval

2020-03-02 Thread Lirong Yuan
On Mon, Mar 2, 2020 at 10:31 AM Laurent Vivier  wrote:
>
> Le 02/03/2020 à 19:18, Lirong Yuan a écrit :
> > On Mon, Mar 2, 2020 at 6:39 AM Laurent Vivier  wrote:
> >>
> >> Le 21/02/2020 à 21:28, Lirong Yuan a écrit :
> >>> This change adds the support for AT_EXECFN and AT_EXECFD auxval.
> >>
> >> Why do we need AT_EXECFD?
> >>
> >> AT_EXECFD is normally only used with binfmt_misc so I don't see any use
> >> cases for it with QEMU.
> >>
> >> For AT_EXECFN, according to kernel commit
> >>
> >>   651910874633 execve filename: document and export via auxiliary vector
> >>
> >> It sould be like readlink("/proc/self/exe",), and thus I think we should
> >> use realpath() like we have in syscall.c for TARGET_NR_readlink:
> >>
> >>  8843 case TARGET_NR_readlink:
> >> ...
> >>  8854 char real[PATH_MAX], *temp;
> >>  8855 temp = realpath(exec_path, real);
> >> ...
> >>
> >> Thanks,
> >> Laurent
> >>
> >>>
> >>> Signed-off-by: Lirong Yuan 
> >>> ---
> >>>  linux-user/elfload.c | 13 +
> >>>  1 file changed, 9 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> >>> index f3080a1635..7e0f3042f1 100644
> >>> --- a/linux-user/elfload.c
> >>> +++ b/linux-user/elfload.c
> >>> @@ -1568,7 +1568,7 @@ struct exec
> >>>   
> >>> ~(abi_ulong)(TARGET_ELF_EXEC_PAGESIZE-1))
> >>>  #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
> >>>
> >>> -#define DLINFO_ITEMS 15
> >>> +#define DLINFO_ITEMS 17
> >>>
> >>>  static inline void memcpy_fromfs(void * to, const void * from, unsigned 
> >>> long n)
> >>>  {
> >>> @@ -1888,11 +1888,14 @@ static abi_ulong 
> >>> loader_build_fdpic_loadmap(struct image_info *info, abi_ulong s
> >>>  return sp;
> >>>  }
> >>>
> >>> -static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
> >>> +static abi_ulong create_elf_tables(struct linux_binprm *bprm,
> >>> struct elfhdr *exec,
> >>> struct image_info *info,
> >>> struct image_info *interp_info)
> >>>  {
> >>> +abi_ulong p = bprm->p;
> >>> +int argc = bprm->argc;
> >>> +int envc = bprm->envc;
> >>>  abi_ulong sp;
> >>>  abi_ulong u_argc, u_argv, u_envp, u_auxv;
> >>>  int size;
> >>> @@ -2032,6 +2035,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int 
> >>> argc, int envc,
> >>>  NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
> >>>  NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
> >>>  NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
> >>> +NEW_AUX_ENT(AT_EXECFN, info->file_string);
> >>> +NEW_AUX_ENT(AT_EXECFD, bprm->fd);
> >>>
> >>>  #ifdef ELF_HWCAP2
> >>>  NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
> >>> @@ -2870,8 +2875,8 @@ int load_elf_binary(struct linux_binprm *bprm, 
> >>> struct image_info *info)
> >>>  #endif
> >>>  }
> >>>
> >>> -bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex,
> >>> -info, (elf_interpreter ? &interp_info : 
> >>> NULL));
> >>> +bprm->p = create_elf_tables(bprm, &elf_ex, info,
> >>> +(elf_interpreter ? &interp_info : NULL));
> >>>  info->start_stack = bprm->p;
> >>>
> >>>  /* If we have an interpreter, set that as the program's entry point.
> >>>
> >>
> >
> > Hi Laurent,
>
> Hi Lirong,
>
> > I added support for AT_EXECFD because I thought it might be useful to
> > implement all types that getauxval could take as an argument.
> > Would you prefer that it be removed?
>
> I think providing the AT_EXECFD to the target binary could make it think
> it has been run directly by binfmt_misc (as an interpreter itself), and
> that is not the case (qemu is run by binfmt_misc and is the interpreter).
>
> So I would prefer you remove it.
>
> > For AT_EXECFN, there are two questions that we considered:
> > 1) What should it return?
> > Since QEMU is emulating running the guest program, the function should
> > return the file name of the guest program (info->file_string), rather
> > than the QEMU program itself, which we get from
> > qemu_getauxval(AT_EXECFN).
> >
> > 2) Should it return the full path or as is?
> > We tested the behavior of getauxval with a simple test program on
> > Linux, and it turned out that it returned file path as is. For
> > example,
> > $ ./test
> > getauxval(AT_EXECFN): ./test
> > $ /usr/local/home/tmp/test
> > getauxval(AT_EXECFN): /usr/local/home/tmp/test
>
> If you have compared the result with the real one it's fine for me.
>
> Resend tou patch without the AT_EXECFD part and it will be good.
>
> Thanks,
> Laurent
>

Hi Laurent,

Thank you so much for the review! :)

Resent the v2 patch without AT_EXECFD:
http://patchwork.ozlabs.org/patch/1247861/

Thanks,
Lirong



Re: [PATCH v2] linux-user: Add AT_EXECFN auxval

2020-03-03 Thread Lirong Yuan
On Tue, Mar 3, 2020 at 1:40 AM Laurent Vivier  wrote:
>
> Le 02/03/2020 à 20:31, Lirong Yuan a écrit :
> > This change adds the support for AT_EXECFN auxval.
> >
> > Signed-off-by: Lirong Yuan 
> > ---
> > Changelog since v1:
> > - remove implementation for AT_EXECFD auxval.
> >
> >  linux-user/elfload.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> > index db748c5877..8198be0446 100644
> > --- a/linux-user/elfload.c
> > +++ b/linux-user/elfload.c
> > @@ -1573,7 +1573,7 @@ struct exec
> >   ~(abi_ulong)(TARGET_ELF_EXEC_PAGESIZE-1))
> >  #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
> >
> > -#define DLINFO_ITEMS 15
> > +#define DLINFO_ITEMS 16
> >
> >  static inline void memcpy_fromfs(void * to, const void * from, unsigned 
> > long n)
> >  {
> > @@ -2037,6 +2037,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int 
> > argc, int envc,
> >  NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
> >  NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
> >  NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
> > +NEW_AUX_ENT(AT_EXECFN, info->file_string);
> >
> >  #ifdef ELF_HWCAP2
> >  NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
> >
>
> Applied to my linux-user branch.
>
> Thanks,
> Laurent

Awesome, thanks for the review! :)

Regards,
Lirong



[PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-03-06 Thread Lirong Yuan
This allows gdb to access the target’s auxiliary vector,
which can be helpful for telling system libraries important details
about the hardware, operating system, and process.

Signed-off-by: Lirong Yuan 
---
 gdbstub.c | 50 ++
 1 file changed, 50 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 22a2d630cd..c2865ea873 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2105,6 +2105,12 @@ static void handle_query_supported(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
 ";qXfer:features:read+");
 }
+#ifdef CONFIG_USER_ONLY
+if (gdb_ctx->s->c_cpu->opaque) {
+pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
+";qXfer:auxv:read+");
+}
+#endif
 
 if (gdb_ctx->num_params &&
 strstr(gdb_ctx->params[0].data, "multiprocess+")) {
@@ -2166,6 +2172,42 @@ static void handle_query_xfer_features(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 put_packet_binary(gdb_ctx->s, gdb_ctx->str_buf, len + 1, true);
 }
 
+#ifdef CONFIG_USER_ONLY
+static void handle_query_xfer_auxv(GdbCmdContext *gdb_ctx, void *user_ctx)
+{
+TaskState *ts;
+unsigned long offset, len, saved_auxv, auxv_len;
+const char *mem;
+
+if (gdb_ctx->num_params < 2) {
+put_packet(gdb_ctx->s, "E22");
+return;
+}
+
+offset = gdb_ctx->params[0].val_ul;
+len = gdb_ctx->params[1].val_ul;
+
+ts = gdb_ctx->s->c_cpu->opaque;
+saved_auxv = ts->info->saved_auxv;
+auxv_len = ts->info->auxv_len;
+mem = (const char *)(saved_auxv + offset);
+
+if (len > (MAX_PACKET_LENGTH - 5) / 2) {
+len = (MAX_PACKET_LENGTH - 5) / 2;
+}
+
+if (len < auxv_len - offset) {
+gdb_ctx->str_buf[0] = 'm';
+len = memtox(gdb_ctx->str_buf + 1, mem, len);
+} else {
+gdb_ctx->str_buf[0] = 'l';
+len = memtox(gdb_ctx->str_buf + 1, mem, auxv_len - offset);
+}
+
+put_packet_binary(gdb_ctx->s, gdb_ctx->str_buf, len + 1, true);
+}
+#endif
+
 static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
 {
 put_packet(gdb_ctx->s, GDB_ATTACHED);
@@ -2271,6 +2313,14 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
 .cmd_startswith = 1,
 .schema = "s:l,l0"
 },
+#ifdef CONFIG_USER_ONLY
+{
+.handler = handle_query_xfer_auxv,
+.cmd = "Xfer:auxv:read:",
+.cmd_startswith = 1,
+.schema = "l,l0"
+},
+#endif
 {
 .handler = handle_query_attached,
 .cmd = "Attached:",
-- 
2.25.1.481.gfbce0eb801-goog




[PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-03-06 Thread Lirong Yuan
This allows gdb to access the target’s auxiliary vector,
which can be helpful for telling system libraries important details
about the hardware, operating system, and process.

Signed-off-by: Lirong Yuan 
---
 gdbstub.c | 55 +++
 1 file changed, 55 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 22a2d630cd..a946af7007 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2105,6 +2105,12 @@ static void handle_query_supported(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
 ";qXfer:features:read+");
 }
+#ifdef CONFIG_USER_ONLY
+if (gdb_ctx->s->c_cpu->opaque) {
+pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
+";qXfer:auxv:read+");
+}
+#endif
 
 if (gdb_ctx->num_params &&
 strstr(gdb_ctx->params[0].data, "multiprocess+")) {
@@ -2166,6 +2172,47 @@ static void handle_query_xfer_features(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 put_packet_binary(gdb_ctx->s, gdb_ctx->str_buf, len + 1, true);
 }
 
+#ifdef CONFIG_USER_ONLY
+static void handle_query_xfer_auxv(GdbCmdContext *gdb_ctx, void *user_ctx)
+{
+TaskState *ts;
+unsigned long offset, len, saved_auxv, auxv_len;
+const char *mem;
+
+if (gdb_ctx->num_params < 2) {
+put_packet(gdb_ctx->s, "E22");
+return;
+}
+
+offset = gdb_ctx->params[0].val_ul;
+len = gdb_ctx->params[1].val_ul;
+
+ts = gdb_ctx->s->c_cpu->opaque;
+saved_auxv = ts->info->saved_auxv;
+auxv_len = ts->info->auxv_len;
+mem = (const char *)(saved_auxv + offset);
+
+if (offset >= auxv_len) {
+put_packet(gdb_ctx->s, "E22");
+return;
+}
+
+if (len > (MAX_PACKET_LENGTH - 5) / 2) {
+len = (MAX_PACKET_LENGTH - 5) / 2;
+}
+
+if (len < auxv_len - offset) {
+gdb_ctx->str_buf[0] = 'm';
+len = memtox(gdb_ctx->str_buf + 1, mem, len);
+} else {
+gdb_ctx->str_buf[0] = 'l';
+len = memtox(gdb_ctx->str_buf + 1, mem, auxv_len - offset);
+}
+
+put_packet_binary(gdb_ctx->s, gdb_ctx->str_buf, len + 1, true);
+}
+#endif
+
 static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
 {
 put_packet(gdb_ctx->s, GDB_ATTACHED);
@@ -2271,6 +2318,14 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
 .cmd_startswith = 1,
 .schema = "s:l,l0"
 },
+#ifdef CONFIG_USER_ONLY
+{
+.handler = handle_query_xfer_auxv,
+.cmd = "Xfer:auxv:read:",
+.cmd_startswith = 1,
+.schema = "l,l0"
+},
+#endif
 {
 .handler = handle_query_attached,
 .cmd = "Attached:",
-- 
2.25.1.481.gfbce0eb801-goog




Re: [PATCH] linux-user: Add an argument QEMU_MMAP_BASE to set custom mmap base address in qemu user mode

2020-03-09 Thread Lirong Yuan
On Mon, Mar 2, 2020 at 11:51 AM Lirong Yuan  wrote:

> On Mon, Mar 2, 2020 at 10:39 AM Laurent Vivier  wrote:
> >
> > Le 02/03/2020 à 18:53, Lirong Yuan a écrit :
> > > On Mon, Mar 2, 2020 at 6:56 AM Laurent Vivier 
> wrote:
> > >>
> > >> Le 29/02/2020 à 01:43, Lirong Yuan a écrit :
> > >>> On Fri, Feb 21, 2020 at 5:09 PM Lirong Yuan 
> wrote:
> > >>>>
> > >>>> This change allows us to set custom base address for guest
> programs. It is needed to allow qemu to work with Thread Sanitizer (TSan),
> which has specific boundary definitions for memory mappings on different
> platforms:
> > >>>>
> https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h
> > >>
> > >> Could you give more details and some examples?
> > >>
> > >> Thanks,
> > >> Laurent
> > >>
> > >>>> Signed-off-by: Lirong Yuan 
> > >>>> ---
> > >>>>  linux-user/main.c | 12 
> > >>>>  linux-user/mmap.c |  3 ++-
> > >>>>  linux-user/qemu.h |  5 +
> > >>>>  3 files changed, 19 insertions(+), 1 deletion(-)
> > >>>>
> > >>>> diff --git a/linux-user/main.c b/linux-user/main.c
> > >>>> index fba833aac9..c01af6bfee 100644
> > >>>> --- a/linux-user/main.c
> > >>>> +++ b/linux-user/main.c
> > >>>> @@ -336,6 +336,16 @@ static void handle_arg_guest_base(const char
> *arg)
> > >>>>  have_guest_base = 1;
> > >>>>  }
> > >>>>
> > >>>> +static void handle_arg_mmap_base(const char *arg)
> > >>>> +{
> > >>>> +int err = qemu_strtoul(arg, NULL, 0, &mmap_base);
> > >>>> +if (err) {
> > >>>> +fprintf(stderr, "Invalid mmap_base: %s, err: %d\n", arg,
> err);
> > >>>> +exit(EXIT_FAILURE);
> > >>>> +}
> > >>>> +mmap_next_start = mmap_base;
> > >>>> +}
> > >>>> +
> > >>>>  static void handle_arg_reserved_va(const char *arg)
> > >>>>  {
> > >>>>  char *p;
> > >>>> @@ -440,6 +450,8 @@ static const struct qemu_argument arg_table[] =
> {
> > >>>>   "uname",  "set qemu uname release string to 'uname'"},
> > >>>>  {"B",  "QEMU_GUEST_BASE",  true,
> handle_arg_guest_base,
> > >>>>   "address","set guest_base address to 'address'"},
> > >>>> +{"mmap_base",  "QEMU_MMAP_BASE",   true,  handle_arg_mmap_base,
> > >>>> + "",   "begin allocating guest pages at this host
> address"},
> > >>>>  {"R",  "QEMU_RESERVED_VA", true,
> handle_arg_reserved_va,
> > >>>>   "size",   "reserve 'size' bytes for guest virtual address
> space"},
> > >>>>  {"d",  "QEMU_LOG", true,  handle_arg_log,
> > >>>> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> > >>>> index 8685f02e7e..3f35543acf 100644
> > >>>> --- a/linux-user/mmap.c
> > >>>> +++ b/linux-user/mmap.c
> > >>>> @@ -189,6 +189,7 @@ static int mmap_frag(abi_ulong real_start,
> > >>>>  # define TASK_UNMAPPED_BASE  0x4000
> > >>>>  #endif
> > >>>>  abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
> > >>>> +abi_ulong mmap_base = TASK_UNMAPPED_BASE;
> > >>>>
> > >>>>  unsigned long last_brk;
> > >>>>
> > >>>> @@ -299,7 +300,7 @@ abi_ulong mmap_find_vma(abi_ulong start,
> abi_ulong size, abi_ulong align)
> > >>>>
> > >>>>  if ((addr & (align - 1)) == 0) {
> > >>>>  /* Success.  */
> > >>>> -if (start == mmap_next_start && addr >=
> TASK_UNMAPPED_BASE) {
> > >>>> +if (start == mmap_next_start && addr >= mmap_base)
> {
> > >>>>  mmap_next_start = addr + size;
> > >>>>  }
> > >>>> 

Re: [PATCH] linux-user: Add an argument QEMU_MMAP_BASE to set custom mmap base address in qemu user mode

2020-03-12 Thread Lirong Yuan
On Thu, Mar 12, 2020 at 1:42 AM Laurent Vivier  wrote:

> Le 09/03/2020 à 19:07, Lirong Yuan a écrit :
> >
> > On Mon, Mar 2, 2020 at 11:51 AM Lirong Yuan  > <mailto:yua...@google.com>> wrote:
> >
> > On Mon, Mar 2, 2020 at 10:39 AM Laurent Vivier  > <mailto:laur...@vivier.eu>> wrote:
> > >
> > > Le 02/03/2020 à 18:53, Lirong Yuan a écrit :
> > > > On Mon, Mar 2, 2020 at 6:56 AM Laurent Vivier  > <mailto:laur...@vivier.eu>> wrote:
> > > >>
> > > >> Le 29/02/2020 à 01:43, Lirong Yuan a écrit :
> > > >>> On Fri, Feb 21, 2020 at 5:09 PM Lirong Yuan  > <mailto:yua...@google.com>> wrote:
> > > >>>>
> > > >>>> This change allows us to set custom base address for guest
> > programs. It is needed to allow qemu to work with Thread Sanitizer
> > (TSan), which has specific boundary definitions for memory mappings
> > on different platforms:
> > > >>>>
> >
> https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h
> > > >>
> > > >> Could you give more details and some examples?
> > > >>
> > > >> Thanks,
> > > >> Laurent
> > > >>
> > > >>>> Signed-off-by: Lirong Yuan  > <mailto:yua...@google.com>>
> > > >>>> ---
> > > >>>>  linux-user/main.c | 12 
> > > >>>>  linux-user/mmap.c |  3 ++-
> > > >>>>  linux-user/qemu.h |  5 +
> > > >>>>  3 files changed, 19 insertions(+), 1 deletion(-)
> > > >>>>
> > > >>>> diff --git a/linux-user/main.c b/linux-user/main.c
> > > >>>> index fba833aac9..c01af6bfee 100644
> > > >>>> --- a/linux-user/main.c
> > > >>>> +++ b/linux-user/main.c
> > > >>>> @@ -336,6 +336,16 @@ static void handle_arg_guest_base(const
> > char *arg)
> > > >>>>  have_guest_base = 1;
> > > >>>>  }
> > > >>>>
> > > >>>> +static void handle_arg_mmap_base(const char *arg)
> > > >>>> +{
> > > >>>> +int err = qemu_strtoul(arg, NULL, 0, &mmap_base);
> > > >>>> +if (err) {
> > > >>>> +fprintf(stderr, "Invalid mmap_base: %s, err: %d\n",
> > arg, err);
> > > >>>> +exit(EXIT_FAILURE);
> > > >>>> +}
> > > >>>> +mmap_next_start = mmap_base;
> > > >>>> +}
> > > >>>> +
> > > >>>>  static void handle_arg_reserved_va(const char *arg)
> > > >>>>  {
> > > >>>>  char *p;
> > > >>>> @@ -440,6 +450,8 @@ static const struct qemu_argument
> > arg_table[] = {
> > > >>>>   "uname",  "set qemu uname release string to
> 'uname'"},
> > > >>>>  {"B",  "QEMU_GUEST_BASE",  true,
> > handle_arg_guest_base,
> > > >>>>   "address","set guest_base address to 'address'"},
> > > >>>> +{"mmap_base",  "QEMU_MMAP_BASE",   true,
> > handle_arg_mmap_base,
> > > >>>> + "",   "begin allocating guest pages at this
> > host address"},
> > > >>>>  {"R",  "QEMU_RESERVED_VA", true,
> > handle_arg_reserved_va,
> > > >>>>   "size",   "reserve 'size' bytes for guest virtual
> > address space"},
> > > >>>>  {"d",  "QEMU_LOG", true,  handle_arg_log,
> > > >>>> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> > > >>>> index 8685f02e7e..3f35543acf 100644
> > > >>>> --- a/linux-user/mmap.c
> > > >>>> +++ b/linux-user/mmap.c
> > > >>>> @@ -189,6 +189,7 @@ static int mmap_frag(abi_ulong real_start,
> > > >>>>  # define TASK_UNMAPPED_BA

[PATCH] linux-user: Update TASK_UNMAPPED_BASE for aarch64

2020-03-12 Thread Lirong Yuan
This change updates TASK_UNMAPPED_BASE (the base address for guest programs) 
for aarch64. It is needed to allow qemu to work with Thread Sanitizer (TSan), 
which has specific boundary definitions for memory mappings on different 
platforms:
https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h

Signed-off-by: Lirong Yuan 
---
 linux-user/mmap.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 8685f02e7e..e378033797 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -184,7 +184,11 @@ static int mmap_frag(abi_ulong real_start,
 }
 
 #if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64
+#ifdef TARGET_AARCH64
+# define TASK_UNMAPPED_BASE  0x55
+#else
 # define TASK_UNMAPPED_BASE  (1ul << 38)
+#endif
 #else
 # define TASK_UNMAPPED_BASE  0x4000
 #endif
-- 
2.25.1.481.gfbce0eb801-goog




Re: [PATCH] linux-user: Update TASK_UNMAPPED_BASE for aarch64

2020-03-13 Thread Lirong Yuan
On Fri, Mar 13, 2020 at 2:45 PM Laurent Vivier  wrote:

> Le 13/03/2020 à 01:28, Lirong Yuan a écrit :
> > This change updates TASK_UNMAPPED_BASE (the base address for guest
> programs) for aarch64. It is needed to allow qemu to work with Thread
> Sanitizer (TSan), which has specific boundary definitions for memory
> mappings on different platforms:
> >
> https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h
> >
> > Signed-off-by: Lirong Yuan 
> > ---
> >  linux-user/mmap.c | 4 
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> > index 8685f02e7e..e378033797 100644
> > --- a/linux-user/mmap.c
> > +++ b/linux-user/mmap.c
> > @@ -184,7 +184,11 @@ static int mmap_frag(abi_ulong real_start,
> >  }
> >
> >  #if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64
> > +#ifdef TARGET_AARCH64
> > +# define TASK_UNMAPPED_BASE  0x55
> > +#else
> >  # define TASK_UNMAPPED_BASE  (1ul << 38)
> > +#endif
> >  #else
> >  # define TASK_UNMAPPED_BASE  0x4000
> >  #endif
> >
>
> Applied to my linux-user branch.
>
> Thanks,
> Laurent
>

Great, thanks a lot! :)


Re: [PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-07-21 Thread Lirong Yuan
On Tue, Mar 31, 2020 at 12:20 AM Alex Bennée  wrote:
>
>
> Lirong Yuan  writes:
>
> > On Mon, Mar 30, 2020 at 12:47 PM Alex Bennée  wrote:
> >
> >>
> >> Lirong Yuan  writes:
> >>
> >> > On Sat, Mar 21, 2020 at 6:56 AM Alex Bennée 
> >> wrote:
> >> >
> >> >>
> >> >> Lirong Yuan  writes:
> >> >>
> >> >> > On Fri, Mar 20, 2020 at 2:17 AM Alex Bennée 
> >> >> wrote:
> >> >> 
> >> >> >>
> >> >> >> Sorry I missed this on my radar. There was a minor re-factor of
> >> gdbstub
> >> >> >> that was just merged which will mean this patch needs a re-base to
> >> use
> >> >> >> g_string_* functions to expand stings.
> >> >> >>
> >> >> >> Also we have some simple gdbstub tests now - could we come up with a
> >> >> >> multiarch gdbstub test to verify this is working properly?
> >> >> >>
> >> >> 
> >> >> > For sure, I will re-base this patch to use g_string_* functions.
> >> >> >
> >> >> > Currently we are using qemu aarch64. I am not sure how to do this yet,
> >> >> but
> >> >> > I could try to add something to
> >> >> > https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub
> >> >>
> >> >> If the auxv support is appropriate to all linux-user targets you can
> >> >> plumb it into the multiarch tests - you can even use the existing
> >> >> binaries.
> >> >>
> >> >> So you need:
> >> >>
> >> >>   - a stanza in the makefiles to launch the test (see
> >> >> tests/tcg/aarch64/Makefile.target)
> >> >>
> >> >>   - a .py test script that manipulates gdbstub to check things are
> >> working
> >> >>
> >> >> So something like:
> >> >>
> >> >> .PHONY: gdbstub-foo-binary
> >> >> run-gdbstub-foo-binary: foo-binary
> >> >> $(call run-test, $@, $(GDB_SCRIPT) \
> >> >> --gdb $(HAVE_GDB_BIN) \
> >> >> --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
> >> >> --bin $< --test $(MULTIARCH_SRC)/gdbstub/test-foo.py, \
> >> >> "basic gdbstub FOO support")
> >> >>
> >> >>
> >> >> >
> >> >> > Does this sound good?
> >> >>
> >> >> Hope that helps.
> >> >>
> >> >> >
> >> >> > Thanks!
> >> >> > Lirong
> >> >>
> >> >>
> >> >> --
> >> >> Alex Bennée
> >> >>
> >> >
> >> > Hi Alex,
> >> >
> >> > Thanks for the instructions, very helpful!
> >> >
> >> > I rebased this patch to use g_string_* functions, and the link to
> >> patchwork
> >> > is:
> >> > http://patchwork.ozlabs.org/patch/1264125/
> >> > Could you help take another look?
> >> >
> >> > Regarding testing, I looked at some instructions for running tests, e.g.
> >> > https://github.com/qemu/qemu/blob/master/docs/devel/testing.rst
> >> > https://wiki.qemu.org/Testing
> >> > However I still could not get the tests for aarch64 to run. Do you know
> >> how
> >> > to run the aarch64 or multi-arch tests?
> >>
> >> The aarch64 ones run with "make run-tcg-tests-aarch64-linux-user" add
> >> V=1 to see the details.
> >>
> >> > Also there aren't any existing gdb stub tests that try to read
> >> > uninterpreted bytes from the target’s special data area identified by a
> >> > keyword:
> >> >
> >> https://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html#qXfer-auxiliary-vector-read
> >> > I looked at some other gdb stub tests, but they did not seem to send any
> >> > queries:
> >> > https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub
> >> > So I am not sure how to set up one for "Xfer:auxv:read:" packets...
> >> > Are there plans to add more tests for other packets like
> >> > "Xfer:features:read:"?
> >> > I'd be happy to add a test if there is an examp

Re: [PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-07-21 Thread Lirong Yuan
On Tue, Jul 21, 2020 at 12:50 PM Alex Bennée  wrote:
>
>
> Lirong Yuan  writes:
>
> > On Tue, Mar 31, 2020 at 12:20 AM Alex Bennée  wrote:
> >>
> >>
> >> Lirong Yuan  writes:
> >>
> >> > On Mon, Mar 30, 2020 at 12:47 PM Alex Bennée  
> >> > wrote:
> >> >
> >> >>
> >> >> Lirong Yuan  writes:
> >> >>
> >> >> > On Sat, Mar 21, 2020 at 6:56 AM Alex Bennée 
> >> >> wrote:
> >> >> >
> >> >> >>
> >> >> >> Lirong Yuan  writes:
> >> >> >>
> >> >> >> > On Fri, Mar 20, 2020 at 2:17 AM Alex Bennée 
> >> >> >> > 
> >> >> >> wrote:
> >> >> >> 
> >> >> >> >>
> >> >> >> >> Sorry I missed this on my radar. There was a minor re-factor of
> >> >> gdbstub
> >> >> >> >> that was just merged which will mean this patch needs a re-base to
> >> >> use
> >> >> >> >> g_string_* functions to expand stings.
> >> >> >> >>
> >> >> >> >> Also we have some simple gdbstub tests now - could we come up 
> >> >> >> >> with a
> >> >> >> >> multiarch gdbstub test to verify this is working properly?
> >> >> >> >>
> >> >> >> 
> >> >> >> > For sure, I will re-base this patch to use g_string_* functions.
> >> >> >> >
> >> >> >> > Currently we are using qemu aarch64. I am not sure how to do this 
> >> >> >> > yet,
> >> >> >> but
> >> >> >> > I could try to add something to
> >> >> >> > https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub
> >> >> >>
> >> >> >> If the auxv support is appropriate to all linux-user targets you can
> >> >> >> plumb it into the multiarch tests - you can even use the existing
> >> >> >> binaries.
> >> >> >>
> >> >> >> So you need:
> >> >> >>
> >> >> >>   - a stanza in the makefiles to launch the test (see
> >> >> >> tests/tcg/aarch64/Makefile.target)
> >> >> >>
> >> >> >>   - a .py test script that manipulates gdbstub to check things are
> >> >> working
> >> >> >>
> >> >> >> So something like:
> >> >> >>
> >> >> >> .PHONY: gdbstub-foo-binary
> >> >> >> run-gdbstub-foo-binary: foo-binary
> >> >> >> $(call run-test, $@, $(GDB_SCRIPT) \
> >> >> >> --gdb $(HAVE_GDB_BIN) \
> >> >> >> --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
> >> >> >> --bin $< --test 
> >> >> >> $(MULTIARCH_SRC)/gdbstub/test-foo.py, \
> >> >> >> "basic gdbstub FOO support")
> >> >> >>
> >> >> >>
> >> >> >> >
> >> >> >> > Does this sound good?
> >> >> >>
> >> >> >> Hope that helps.
> >> >> >>
> >> >> >> >
> >> >> >> > Thanks!
> >> >> >> > Lirong
> >> >> >>
> >> >> >>
> >> >> >> --
> >> >> >> Alex Bennée
> >> >> >>
> >> >> >
> >> >> > Hi Alex,
> >> >> >
> >> >> > Thanks for the instructions, very helpful!
> >> >> >
> >> >> > I rebased this patch to use g_string_* functions, and the link to
> >> >> patchwork
> >> >> > is:
> >> >> > http://patchwork.ozlabs.org/patch/1264125/
> >> >> > Could you help take another look?
> >> >> >
> >> >> > Regarding testing, I looked at some instructions for running tests, 
> >> >> > e.g.
> >> >> > https://github.com/qemu/qemu/blob/master/docs/devel/testing.rst
> >> >> > https://wiki.qemu.org/Testing
> >> >> > However I still could not get the tests for aarch64 to run. Do you 

[PATCH] [PATCH v2] gdbstub: add support to Xfer:auxv:read: packet

2020-07-30 Thread Lirong Yuan
This allows gdb to access the target’s auxiliary vector,
which can be helpful for telling system libraries important details
about the hardware, operating system, and process.

Signed-off-by: Lirong Yuan 
---
Changelog since v1:
 - Added a multiarch gdbstub test to verify this is working properly.
---
 gdbstub.c | 54 
 tests/tcg/multiarch/Makefile.target   |  9 ++-
 .../multiarch/gdbstub/test-qxfer-auxv-read.py | 64 +++
 3 files changed, 126 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py

diff --git a/gdbstub.c b/gdbstub.c
index f3a318cd7f..e1e1a2c1e6 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2124,6 +2124,12 @@ static void handle_query_supported(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
 }
 
+#ifdef CONFIG_USER_ONLY
+if (gdbserver_state.c_cpu->opaque) {
+g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
+}
+#endif
+
 if (gdb_ctx->num_params &&
 strstr(gdb_ctx->params[0].data, "multiprocess+")) {
 gdbserver_state.multiprocess = true;
@@ -2185,6 +2191,46 @@ static void handle_query_xfer_features(GdbCmdContext 
*gdb_ctx, void *user_ctx)
   gdbserver_state.str_buf->len, true);
 }
 
+#ifdef CONFIG_USER_ONLY
+static void handle_query_xfer_auxv(GdbCmdContext *gdb_ctx, void *user_ctx)
+{
+TaskState *ts;
+unsigned long offset, len, saved_auxv, auxv_len;
+const char *mem;
+
+if (gdb_ctx->num_params < 2) {
+put_packet("E22");
+return;
+}
+
+offset = gdb_ctx->params[0].val_ul;
+len = gdb_ctx->params[1].val_ul;
+ts = gdbserver_state.c_cpu->opaque;
+saved_auxv = ts->info->saved_auxv;
+auxv_len = ts->info->auxv_len;
+mem = (const char *)(saved_auxv + offset);
+if (offset > auxv_len) {
+put_packet("E00");
+return;
+}
+
+if (len > (MAX_PACKET_LENGTH - 5) / 2) {
+len = (MAX_PACKET_LENGTH - 5) / 2;
+}
+
+if (len < auxv_len - offset) {
+g_string_assign(gdbserver_state.str_buf, "m");
+memtox(gdbserver_state.str_buf, mem, len);
+} else {
+g_string_assign(gdbserver_state.str_buf, "l");
+memtox(gdbserver_state.str_buf, mem, auxv_len - offset);
+}
+
+put_packet_binary(gdbserver_state.str_buf->str,
+  gdbserver_state.str_buf->len, true);
+}
+#endif
+
 static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
 {
 put_packet(GDB_ATTACHED);
@@ -2290,6 +2336,14 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
 .cmd_startswith = 1,
 .schema = "s:l,l0"
 },
+#ifdef CONFIG_USER_ONLY
+{
+.handler = handle_query_xfer_auxv,
+.cmd = "Xfer:auxv:read::",
+.cmd_startswith = 1,
+.schema = "l,l0"
+},
+#endif
 {
 .handler = handle_query_attached,
 .cmd = "Attached:",
diff --git a/tests/tcg/multiarch/Makefile.target 
b/tests/tcg/multiarch/Makefile.target
index cb49cc9ccb..c8cdb1e04d 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -54,7 +54,14 @@ run-gdbstub-sha1: sha1
--bin $< --test $(MULTIARCH_SRC)/gdbstub/sha1.py, \
"basic gdbstub support")
 
-EXTRA_RUNS += run-gdbstub-sha1
+run-gdbstub-qxfer-auxv-read: sha1
+   $(call run-test, $@, $(GDB_SCRIPT) \
+   --gdb $(HAVE_GDB_BIN) \
+   --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
+   --bin $< --test 
$(MULTIARCH_SRC)/gdbstub/test-qxfer-auxv-read.py, \
+   "basic gdbstub qXfer:auxv:read support")
+
+EXTRA_RUNS += run-gdbstub-sha1 run-gdbstub-qxfer-auxv-read
 endif
 
 
diff --git a/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py 
b/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
new file mode 100644
index 00..88049dd330
--- /dev/null
+++ b/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
@@ -0,0 +1,64 @@
+from __future__ import print_function
+#
+# Test the SVE ZReg reports the right amount of data. It uses the
+from __future__ import print_function
+#
+# Test auxiliary vector is loaded via gdbstub
+#
+# This is launched via tests/guest-debug/run-test.py
+#
+
+import gdb
+import sys
+
+failcount = 0
+
+def report(cond, msg):
+"Report success/fail of test"
+if cond:
+print ("PASS: %s" % (msg))
+else:
+print ("FAIL: %s" % (msg))
+global failcount
+failcount += 1
+
+def run_test():
+"Run through the tests one by one"
+
+cond = True
+try:
+  gdb.execute("info auxv")
+except (gdb.error, AttributeError):
+  cond = False
+

Re: [PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-07-30 Thread Lirong Yuan
On Tue, Jul 21, 2020 at 1:29 PM Lirong Yuan  wrote:
>
> On Tue, Jul 21, 2020 at 12:50 PM Alex Bennée  wrote:
> >
> >
> > Lirong Yuan  writes:
> >
> > > On Tue, Mar 31, 2020 at 12:20 AM Alex Bennée  
> > > wrote:
> > >>
> > >>
> > >> Lirong Yuan  writes:
> > >>
> > >> > On Mon, Mar 30, 2020 at 12:47 PM Alex Bennée  
> > >> > wrote:
> > >> >
> > >> >>
> > >> >> Lirong Yuan  writes:
> > >> >>
> > >> >> > On Sat, Mar 21, 2020 at 6:56 AM Alex Bennée 
> > >> >> wrote:
> > >> >> >
> > >> >> >>
> > >> >> >> Lirong Yuan  writes:
> > >> >> >>
> > >> >> >> > On Fri, Mar 20, 2020 at 2:17 AM Alex Bennée 
> > >> >> >> > 
> > >> >> >> wrote:
> > >> >> >> 
> > >> >> >> >>
> > >> >> >> >> Sorry I missed this on my radar. There was a minor re-factor of
> > >> >> gdbstub
> > >> >> >> >> that was just merged which will mean this patch needs a re-base 
> > >> >> >> >> to
> > >> >> use
> > >> >> >> >> g_string_* functions to expand stings.
> > >> >> >> >>
> > >> >> >> >> Also we have some simple gdbstub tests now - could we come up 
> > >> >> >> >> with a
> > >> >> >> >> multiarch gdbstub test to verify this is working properly?
> > >> >> >> >>
> > >> >> >> 
> > >> >> >> > For sure, I will re-base this patch to use g_string_* functions.
> > >> >> >> >
> > >> >> >> > Currently we are using qemu aarch64. I am not sure how to do 
> > >> >> >> > this yet,
> > >> >> >> but
> > >> >> >> > I could try to add something to
> > >> >> >> > https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub
> > >> >> >>
> > >> >> >> If the auxv support is appropriate to all linux-user targets you 
> > >> >> >> can
> > >> >> >> plumb it into the multiarch tests - you can even use the existing
> > >> >> >> binaries.
> > >> >> >>
> > >> >> >> So you need:
> > >> >> >>
> > >> >> >>   - a stanza in the makefiles to launch the test (see
> > >> >> >> tests/tcg/aarch64/Makefile.target)
> > >> >> >>
> > >> >> >>   - a .py test script that manipulates gdbstub to check things are
> > >> >> working
> > >> >> >>
> > >> >> >> So something like:
> > >> >> >>
> > >> >> >> .PHONY: gdbstub-foo-binary
> > >> >> >> run-gdbstub-foo-binary: foo-binary
> > >> >> >> $(call run-test, $@, $(GDB_SCRIPT) \
> > >> >> >> --gdb $(HAVE_GDB_BIN) \
> > >> >> >> --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
> > >> >> >> --bin $< --test 
> > >> >> >> $(MULTIARCH_SRC)/gdbstub/test-foo.py, \
> > >> >> >> "basic gdbstub FOO support")
> > >> >> >>
> > >> >> >>
> > >> >> >> >
> > >> >> >> > Does this sound good?
> > >> >> >>
> > >> >> >> Hope that helps.
> > >> >> >>
> > >> >> >> >
> > >> >> >> > Thanks!
> > >> >> >> > Lirong
> > >> >> >>
> > >> >> >>
> > >> >> >> --
> > >> >> >> Alex Bennée
> > >> >> >>
> > >> >> >
> > >> >> > Hi Alex,
> > >> >> >
> > >> >> > Thanks for the instructions, very helpful!
> > >> >> >
> > >> >> > I rebased this patch to use g_string_* functions, a

Re: [PATCH] [PATCH v2] gdbstub: add support to Xfer:auxv:read: packet

2020-08-03 Thread Lirong Yuan
On Mon, Aug 3, 2020 at 4:27 AM Alex Bennée  wrote:
>
>
> Lirong Yuan  writes:
>
> > This allows gdb to access the target’s auxiliary vector,
> > which can be helpful for telling system libraries important details
> > about the hardware, operating system, and process.
> >
> > Signed-off-by: Lirong Yuan 
>
> I cleaned up the test a little:
>
> modified   tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
> @@ -22,13 +22,9 @@ def report(cond, msg):
>  def run_test():
>  "Run through the tests one by one"
>
> -cond = True
> -try:
> -  gdb.execute("info auxv")
> -except (gdb.error, AttributeError):
> -  cond = False
> -
> -report(cond, "Display the auxiliary vector of the inferior.")
> +auxv = gdb.execute("info auxv", False, True)
> +report(isinstance(auxv, str), "Fetched auxv from inferior")
> +report(auxv.find("sha1"), "Found test binary name in auxv")
>
>  #
>  # This runs as the script it sourced (via -x, via run-test.py)
>
>
> Queued to gdbstub/next, thanks.
>
> --
> Alex Bennée

Awesome, thank you Alex for the review and cleanup!

Regards,
Lirong



Re: [PATCH] linux-user: Update TASK_UNMAPPED_BASE for aarch64

2020-03-16 Thread Lirong Yuan
Thanks Laurent for the prompt responses! Yes that is exactly where the
value is taken from.

For anyone interested in detailed information of the change, here is the
previous discussion thread:
http://patchwork.ozlabs.org/patch/1242370/

Regards,
Lirong


On Sat, Mar 14, 2020 at 10:34 AM Laurent Vivier  wrote:

> Le 14/03/2020 à 18:01, Aleksandar Markovic a écrit :
> > On Sat, Mar 14, 2020 at 11:45 AM Laurent Vivier 
> wrote:
> >>
> >> Le 14/03/2020 à 04:06, Aleksandar Markovic a écrit :
> >>> On Fri, Mar 13, 2020 at 1:28 AM Lirong Yuan  wrote:
> >>>>
> >>>> This change updates TASK_UNMAPPED_BASE (the base address for guest
> programs) for aarch64. It is needed to allow qemu to work with Thread
> Sanitizer (TSan), which has specific boundary definitions for memory
> mappings on different platforms:
> >>>>
> https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h
> >>>>
> >>>> Signed-off-by: Lirong Yuan 
> >>>> ---
> >>>>  linux-user/mmap.c | 4 
> >>>>  1 file changed, 4 insertions(+)
> >>>>
> >>>> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> >>>> index 8685f02e7e..e378033797 100644
> >>>> --- a/linux-user/mmap.c
> >>>> +++ b/linux-user/mmap.c
> >>>> @@ -184,7 +184,11 @@ static int mmap_frag(abi_ulong real_start,
> >>>>  }
> >>>>
> >>>>  #if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64
> >>>> +#ifdef TARGET_AARCH64
> >>>> +# define TASK_UNMAPPED_BASE  0x55
> >>>
> >>> Hi, Lirong,
> >>>
> >>> Can you point from which line of the file you linked to did you
> >>> arrive to the value 0x55?
> >>>
> >>> Second question: What about other targets?
> >>
> >> Personally, I prefer to not change the value for other targets if it is
> >> not required by someone that had some problems with the current value.
> >>
> >> It needs to be changed carefully and to be well tested after change.
> >>
> >
> > Sure, but again, from where " 0x55" comes from?
>
> The URL is in the comment, but more precisely I guess:
>
>
> https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h#L164
>
> Thanks,
> Laurent
>
>


Re: [PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-03-18 Thread Lirong Yuan
On Fri, Mar 6, 2020 at 5:01 PM Lirong Yuan  wrote:

> This allows gdb to access the target’s auxiliary vector,
> which can be helpful for telling system libraries important details
> about the hardware, operating system, and process.
>
> Signed-off-by: Lirong Yuan 
> ---
>  gdbstub.c | 55 +++
>  1 file changed, 55 insertions(+)
>
> diff --git a/gdbstub.c b/gdbstub.c
> index 22a2d630cd..a946af7007 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -2105,6 +2105,12 @@ static void handle_query_supported(GdbCmdContext
> *gdb_ctx, void *user_ctx)
>  pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
>  ";qXfer:features:read+");
>  }
> +#ifdef CONFIG_USER_ONLY
> +if (gdb_ctx->s->c_cpu->opaque) {
> +pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
> +";qXfer:auxv:read+");
> +}
> +#endif
>
>  if (gdb_ctx->num_params &&
>  strstr(gdb_ctx->params[0].data, "multiprocess+")) {
> @@ -2166,6 +2172,47 @@ static void
> handle_query_xfer_features(GdbCmdContext *gdb_ctx, void *user_ctx)
>  put_packet_binary(gdb_ctx->s, gdb_ctx->str_buf, len + 1, true);
>  }
>
> +#ifdef CONFIG_USER_ONLY
> +static void handle_query_xfer_auxv(GdbCmdContext *gdb_ctx, void *user_ctx)
> +{
> +TaskState *ts;
> +unsigned long offset, len, saved_auxv, auxv_len;
> +const char *mem;
> +
> +if (gdb_ctx->num_params < 2) {
> +put_packet(gdb_ctx->s, "E22");
> +return;
> +}
> +
> +offset = gdb_ctx->params[0].val_ul;
> +len = gdb_ctx->params[1].val_ul;
> +
> +ts = gdb_ctx->s->c_cpu->opaque;
> +saved_auxv = ts->info->saved_auxv;
> +auxv_len = ts->info->auxv_len;
> +mem = (const char *)(saved_auxv + offset);
> +
> +if (offset >= auxv_len) {
> +put_packet(gdb_ctx->s, "E22");
> +return;
> +}
> +
> +if (len > (MAX_PACKET_LENGTH - 5) / 2) {
> +len = (MAX_PACKET_LENGTH - 5) / 2;
> +}
> +
> +if (len < auxv_len - offset) {
> +gdb_ctx->str_buf[0] = 'm';
> +len = memtox(gdb_ctx->str_buf + 1, mem, len);
> +} else {
> +gdb_ctx->str_buf[0] = 'l';
> +len = memtox(gdb_ctx->str_buf + 1, mem, auxv_len - offset);
> +}
> +
> +put_packet_binary(gdb_ctx->s, gdb_ctx->str_buf, len + 1, true);
> +}
> +#endif
> +
>  static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
>  {
>  put_packet(gdb_ctx->s, GDB_ATTACHED);
> @@ -2271,6 +2318,14 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
>  .cmd_startswith = 1,
>  .schema = "s:l,l0"
>  },
> +#ifdef CONFIG_USER_ONLY
> +{
> +.handler = handle_query_xfer_auxv,
> +.cmd = "Xfer:auxv:read:",
> +.cmd_startswith = 1,
> +.schema = "l,l0"
> +},
> +#endif
>  {
>  .handler = handle_query_attached,
>  .cmd = "Attached:",
> --
> 2.25.1.481.gfbce0eb801-goog
>
>
Friendly ping~

Link to the patchwork page:
http://patchwork.ozlabs.org/patch/1250727/


Re: [PATCH] gdbstub: add support to Xfer:auxv:read: packet

2020-03-20 Thread Lirong Yuan
On Fri, Mar 20, 2020 at 2:17 AM Alex Bennée  wrote:

>
> Lirong Yuan  writes:
>
> > On Fri, Mar 6, 2020 at 5:01 PM Lirong Yuan  wrote:
> >
> >> This allows gdb to access the target’s auxiliary vector,
> >> which can be helpful for telling system libraries important details
> >> about the hardware, operating system, and process.
> >>
> >> Signed-off-by: Lirong Yuan 
> >> ---
> >>  gdbstub.c | 55 +++
> >>  1 file changed, 55 insertions(+)
> >>
> >> diff --git a/gdbstub.c b/gdbstub.c
> >> index 22a2d630cd..a946af7007 100644
> >> --- a/gdbstub.c
> >> +++ b/gdbstub.c
> >> @@ -2105,6 +2105,12 @@ static void handle_query_supported(GdbCmdContext
> >> *gdb_ctx, void *user_ctx)
> >>  pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
> >>  ";qXfer:features:read+");
> >>  }
> >> +#ifdef CONFIG_USER_ONLY
> >> +if (gdb_ctx->s->c_cpu->opaque) {
> >> +pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
> >> +";qXfer:auxv:read+");
> >> +}
> >> +#endif
> >>
> >>  if (gdb_ctx->num_params &&
> >>  strstr(gdb_ctx->params[0].data, "multiprocess+")) {
> >> @@ -2166,6 +2172,47 @@ static void
> >> handle_query_xfer_features(GdbCmdContext *gdb_ctx, void *user_ctx)
> >>  put_packet_binary(gdb_ctx->s, gdb_ctx->str_buf, len + 1, true);
> >>  }
> >>
> >> +#ifdef CONFIG_USER_ONLY
> >> +static void handle_query_xfer_auxv(GdbCmdContext *gdb_ctx, void
> *user_ctx)
> >> +{
> >> +TaskState *ts;
> >> +unsigned long offset, len, saved_auxv, auxv_len;
> >> +const char *mem;
> >> +
> >> +if (gdb_ctx->num_params < 2) {
> >> +put_packet(gdb_ctx->s, "E22");
> >> +return;
> >> +}
> >> +
> >> +offset = gdb_ctx->params[0].val_ul;
> >> +len = gdb_ctx->params[1].val_ul;
> >> +
> >> +ts = gdb_ctx->s->c_cpu->opaque;
> >> +saved_auxv = ts->info->saved_auxv;
> >> +auxv_len = ts->info->auxv_len;
> >> +mem = (const char *)(saved_auxv + offset);
> >> +
> >> +if (offset >= auxv_len) {
> >> +put_packet(gdb_ctx->s, "E22");
> >> +return;
> >> +}
> >> +
> >> +if (len > (MAX_PACKET_LENGTH - 5) / 2) {
> >> +len = (MAX_PACKET_LENGTH - 5) / 2;
> >> +}
> >> +
> >> +if (len < auxv_len - offset) {
> >> +gdb_ctx->str_buf[0] = 'm';
> >> +len = memtox(gdb_ctx->str_buf + 1, mem, len);
> >> +} else {
> >> +gdb_ctx->str_buf[0] = 'l';
> >> +len = memtox(gdb_ctx->str_buf + 1, mem, auxv_len - offset);
> >> +}
> >> +
> >> +put_packet_binary(gdb_ctx->s, gdb_ctx->str_buf, len + 1, true);
> >> +}
> >> +#endif
> >> +
> >>  static void handle_query_attached(GdbCmdContext *gdb_ctx, void
> *user_ctx)
> >>  {
> >>  put_packet(gdb_ctx->s, GDB_ATTACHED);
> >> @@ -2271,6 +2318,14 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
> >>  .cmd_startswith = 1,
> >>  .schema = "s:l,l0"
> >>  },
> >> +#ifdef CONFIG_USER_ONLY
> >> +{
> >> +.handler = handle_query_xfer_auxv,
> >> +.cmd = "Xfer:auxv:read:",
> >> +.cmd_startswith = 1,
> >> +.schema = "l,l0"
> >> +},
> >> +#endif
> >>  {
> >>  .handler = handle_query_attached,
> >>  .cmd = "Attached:",
> >> --
> >> 2.25.1.481.gfbce0eb801-goog
> >>
> >>
> > Friendly ping~
>
> Sorry I missed this on my radar. There was a minor re-factor of gdbstub
> that was just merged which will mean this patch needs a re-base to use
> g_string_* functions to expand stings.
>
> Also we have some simple gdbstub tests now - could we come up with a
> multiarch gdbstub test to verify this is working properly?
>
> >
> > Link to the patchwork page:
> > http://patchwork.ozlabs.org/patch/1250727/
>
>
> --
> Alex Bennée
>

Hi Alex,

For sure, I will re-base this patch to use g_string_* functions.

Currently we are using qemu aarch64. I am not sure how to do this yet, but
I could try to add something to
https://github.com/qemu/qemu/tree/master/tests/tcg/aarch64/gdbstub

Does this sound good?

Thanks!
Lirong


[PATCH] linux-user: Add AT_EXECFN and AT_EXECFD auxval

2020-02-21 Thread Lirong Yuan
This change adds the support for AT_EXECFN and AT_EXECFD auxval.

Signed-off-by: Lirong Yuan 
---
 linux-user/elfload.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index f3080a1635..7e0f3042f1 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1568,7 +1568,7 @@ struct exec
  ~(abi_ulong)(TARGET_ELF_EXEC_PAGESIZE-1))
 #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
 
-#define DLINFO_ITEMS 15
+#define DLINFO_ITEMS 17
 
 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
 {
@@ -1888,11 +1888,14 @@ static abi_ulong loader_build_fdpic_loadmap(struct 
image_info *info, abi_ulong s
 return sp;
 }
 
-static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
+static abi_ulong create_elf_tables(struct linux_binprm *bprm,
struct elfhdr *exec,
struct image_info *info,
struct image_info *interp_info)
 {
+abi_ulong p = bprm->p;
+int argc = bprm->argc;
+int envc = bprm->envc;
 abi_ulong sp;
 abi_ulong u_argc, u_argv, u_envp, u_auxv;
 int size;
@@ -2032,6 +2035,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
 NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
 NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
 NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
+NEW_AUX_ENT(AT_EXECFN, info->file_string);
+NEW_AUX_ENT(AT_EXECFD, bprm->fd);
 
 #ifdef ELF_HWCAP2
 NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
@@ -2870,8 +2875,8 @@ int load_elf_binary(struct linux_binprm *bprm, struct 
image_info *info)
 #endif
 }
 
-bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex,
-info, (elf_interpreter ? &interp_info : NULL));
+bprm->p = create_elf_tables(bprm, &elf_ex, info,
+(elf_interpreter ? &interp_info : NULL));
 info->start_stack = bprm->p;
 
 /* If we have an interpreter, set that as the program's entry point.
-- 
2.25.0.265.gbab2e86ba0-goog




[PATCH] linux-user: Add an argument QEMU_MMAP_BASE to set custom mmap base address in qemu user mode

2020-02-21 Thread Lirong Yuan
This change allows us to set custom base address for guest programs. It is 
needed to allow qemu to work with Thread Sanitizer (TSan), which has specific 
boundary definitions for memory mappings on different platforms:
https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h

Signed-off-by: Lirong Yuan 
---
 linux-user/main.c | 12 
 linux-user/mmap.c |  3 ++-
 linux-user/qemu.h |  5 +
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index fba833aac9..dfcd867399 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -336,6 +336,16 @@ static void handle_arg_guest_base(const char *arg)
 have_guest_base = 1;
 }
 
+static void handle_arg_mmap_base(const char *arg)
+{
+mmap_base = strtoul(arg, NULL, 0);
+if (mmap_base == 0) {
+fprintf(stderr, "Invalid mmap_base: %s\n", arg);
+exit(EXIT_FAILURE);
+}
+mmap_next_start = mmap_base;
+}
+
 static void handle_arg_reserved_va(const char *arg)
 {
 char *p;
@@ -440,6 +450,8 @@ static const struct qemu_argument arg_table[] = {
  "uname",  "set qemu uname release string to 'uname'"},
 {"B",  "QEMU_GUEST_BASE",  true,  handle_arg_guest_base,
  "address","set guest_base address to 'address'"},
+{"mmap_base",  "QEMU_MMAP_BASE",   true,  handle_arg_mmap_base,
+ "",   "begin allocating guest pages at this host address"},
 {"R",  "QEMU_RESERVED_VA", true,  handle_arg_reserved_va,
  "size",   "reserve 'size' bytes for guest virtual address space"},
 {"d",  "QEMU_LOG", true,  handle_arg_log,
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 8685f02e7e..3f35543acf 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -189,6 +189,7 @@ static int mmap_frag(abi_ulong real_start,
 # define TASK_UNMAPPED_BASE  0x4000
 #endif
 abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
+abi_ulong mmap_base = TASK_UNMAPPED_BASE;
 
 unsigned long last_brk;
 
@@ -299,7 +300,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, 
abi_ulong align)
 
 if ((addr & (align - 1)) == 0) {
 /* Success.  */
-if (start == mmap_next_start && addr >= TASK_UNMAPPED_BASE) {
+if (start == mmap_next_start && addr >= mmap_base) {
 mmap_next_start = addr + size;
 }
 return addr;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 560a68090e..83c00cfea2 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -161,6 +161,11 @@ void task_settid(TaskState *);
 void stop_all_tasks(void);
 extern const char *qemu_uname_release;
 extern unsigned long mmap_min_addr;
+/*
+ * mmap_base is minimum address to use when allocating guest pages. All guest
+ * pages will be allocated at this (guest) address or higher addresses.
+ */
+extern abi_ulong mmap_base;
 
 /* ??? See if we can avoid exposing so much of the loader internals.  */
 
-- 
2.25.0.265.gbab2e86ba0-goog




[PATCH] linux-user: Add an argument QEMU_MMAP_BASE to set custom mmap base address in qemu user mode

2020-02-21 Thread Lirong Yuan
This change allows us to set custom base address for guest programs. It is 
needed to allow qemu to work with Thread Sanitizer (TSan), which has specific 
boundary definitions for memory mappings on different platforms:
https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/tsan/rtl/tsan_platform.h

Signed-off-by: Lirong Yuan 
---
 linux-user/main.c | 12 
 linux-user/mmap.c |  3 ++-
 linux-user/qemu.h |  5 +
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index fba833aac9..c01af6bfee 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -336,6 +336,16 @@ static void handle_arg_guest_base(const char *arg)
 have_guest_base = 1;
 }
 
+static void handle_arg_mmap_base(const char *arg)
+{
+int err = qemu_strtoul(arg, NULL, 0, &mmap_base);
+if (err) {
+fprintf(stderr, "Invalid mmap_base: %s, err: %d\n", arg, err);
+exit(EXIT_FAILURE);
+}
+mmap_next_start = mmap_base;
+}
+
 static void handle_arg_reserved_va(const char *arg)
 {
 char *p;
@@ -440,6 +450,8 @@ static const struct qemu_argument arg_table[] = {
  "uname",  "set qemu uname release string to 'uname'"},
 {"B",  "QEMU_GUEST_BASE",  true,  handle_arg_guest_base,
  "address","set guest_base address to 'address'"},
+{"mmap_base",  "QEMU_MMAP_BASE",   true,  handle_arg_mmap_base,
+ "",   "begin allocating guest pages at this host address"},
 {"R",  "QEMU_RESERVED_VA", true,  handle_arg_reserved_va,
  "size",   "reserve 'size' bytes for guest virtual address space"},
 {"d",  "QEMU_LOG", true,  handle_arg_log,
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 8685f02e7e..3f35543acf 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -189,6 +189,7 @@ static int mmap_frag(abi_ulong real_start,
 # define TASK_UNMAPPED_BASE  0x4000
 #endif
 abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
+abi_ulong mmap_base = TASK_UNMAPPED_BASE;
 
 unsigned long last_brk;
 
@@ -299,7 +300,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, 
abi_ulong align)
 
 if ((addr & (align - 1)) == 0) {
 /* Success.  */
-if (start == mmap_next_start && addr >= TASK_UNMAPPED_BASE) {
+if (start == mmap_next_start && addr >= mmap_base) {
 mmap_next_start = addr + size;
 }
 return addr;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 560a68090e..83c00cfea2 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -161,6 +161,11 @@ void task_settid(TaskState *);
 void stop_all_tasks(void);
 extern const char *qemu_uname_release;
 extern unsigned long mmap_min_addr;
+/*
+ * mmap_base is minimum address to use when allocating guest pages. All guest
+ * pages will be allocated at this (guest) address or higher addresses.
+ */
+extern abi_ulong mmap_base;
 
 /* ??? See if we can avoid exposing so much of the loader internals.  */
 
-- 
2.25.0.265.gbab2e86ba0-goog