All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] linux-user: Load a vdso for x86_64
@ 2020-05-19 19:44 Richard Henderson
  2020-05-19 19:44 ` [PATCH 1/2] linux-user: Build vdso for x64 Richard Henderson
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Richard Henderson @ 2020-05-19 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The subject of AT_SYSINFO came up on launchpad recently.

There is definite room for improvement in all of this:

(1) We could build the vdso binary into qemu instead of really
    loading it from the file system.  This would obviate the
    several problems of locating the .so file.  It would also
    mean that --static builds continue to create a standalone
    qemu binary.

(2) We could use our cross-build system to build the vdso.
    Though we'd still likely want to keep the image in git
    along side the other rom images for when cross-build is
    not available.

(3) There are some ??? comments where some decisions could be made,
    and other ??? that are merely commenting on weirdness.

(4) It shouldn't take too much effort to create vdsos for the
    other architectures.  But we should get this one as clean
    as we can first.

Amusingly, this patch set has just turned 10 years old.
First posted April 4, 2010.  I don't recall ever seeing
any review on the several postings over the years.


r~


Richard Henderson (2):
  linux-user: Build vdso for x64.
  linux-user: Load a VDSO for x86-64.

 Makefile                  |   4 +-
 linux-user/elfload.c      | 203 +++++++++++++++++++++++++++++++++++++-
 pc-bios/Makefile          |   5 +
 pc-bios/vdso-linux-x64.S  | 115 +++++++++++++++++++++
 pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++
 pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes
 6 files changed, 401 insertions(+), 7 deletions(-)
 create mode 100644 pc-bios/vdso-linux-x64.S
 create mode 100644 pc-bios/vdso-linux-x64.ld
 create mode 100755 pc-bios/vdso-linux-x64.so

-- 
2.20.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/2] linux-user: Build vdso for x64.
  2020-05-19 19:44 [PATCH 0/2] linux-user: Load a vdso for x86_64 Richard Henderson
@ 2020-05-19 19:44 ` Richard Henderson
  2020-05-19 19:44 ` [PATCH 2/2] linux-user: Load a VDSO for x86-64 Richard Henderson
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2020-05-19 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

... Well, sortof.  The Makefile bits are broken.
Patch to load the vdso into the running program to follow.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 Makefile                  |   4 +-
 pc-bios/Makefile          |   5 ++
 pc-bios/vdso-linux-x64.S  | 115 ++++++++++++++++++++++++++++++++++++++
 pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++++++++++++++
 pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes
 5 files changed, 203 insertions(+), 2 deletions(-)
 create mode 100644 pc-bios/vdso-linux-x64.S
 create mode 100644 pc-bios/vdso-linux-x64.ld
 create mode 100755 pc-bios/vdso-linux-x64.so

diff --git a/Makefile b/Makefile
index 40e4f7677b..73e380ac6a 100644
--- a/Makefile
+++ b/Makefile
@@ -848,8 +848,8 @@ qemu_vga.ndrv \
 edk2-licenses.txt \
 hppa-firmware.img \
 opensbi-riscv32-sifive_u-fw_jump.bin opensbi-riscv32-virt-fw_jump.bin \
-opensbi-riscv64-sifive_u-fw_jump.bin opensbi-riscv64-virt-fw_jump.bin
-
+opensbi-riscv64-sifive_u-fw_jump.bin opensbi-riscv64-virt-fw_jump.bin \
+vdso-linux-x64.so
 
 DESCS=50-edk2-i386-secure.json 50-edk2-x86_64-secure.json \
 60-edk2-aarch64.json 60-edk2-arm.json 60-edk2-i386.json 60-edk2-x86_64.json
diff --git a/pc-bios/Makefile b/pc-bios/Makefile
index 315288df84..70e2485e2e 100644
--- a/pc-bios/Makefile
+++ b/pc-bios/Makefile
@@ -15,5 +15,10 @@ all: $(TARGETS)
 %.dtb: %.dts
 	dtc -I dts -O dtb -o $@ $<
 
+vdso-linux-x64.so: vdso-linux-x64.o vdso-linux-x64.ld
+	$(CC) -nostdlib -shared -Wl,-T,vdso-linux-x64.ld \
+	  -Wl,-h,linux-vdso.so.1 -Wl,--hash-style=both \
+	  vdso-linux-x64.o -o $@
+
 clean:
 	rm -f $(TARGETS) *.o *~
diff --git a/pc-bios/vdso-linux-x64.S b/pc-bios/vdso-linux-x64.S
new file mode 100644
index 0000000000..090d82c26a
--- /dev/null
+++ b/pc-bios/vdso-linux-x64.S
@@ -0,0 +1,115 @@
+/*
+ *  x86-64 linux replacement vdso.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <asm/unistd.h>
+
+	.globl	__vdso_clock_gettime
+	.type	__vdso_clock_gettime, @function
+	.balign	16
+	.cfi_startproc
+__vdso_clock_gettime:
+	mov	$__NR_clock_gettime, %eax
+	syscall
+	ret
+	.cfi_endproc
+	.size	__vdso_clock_gettime, . - __vdso_clock_gettime
+
+clock_gettime = __vdso_clock_gettime
+	.weak	clock_gettime
+
+
+	.globl	__vdso_gettimeofday
+	.type	__vdso_gettimeofday, @function
+	.balign	16
+	.cfi_startproc
+__vdso_gettimeofday:
+	mov	$__NR_gettimeofday, %eax
+	syscall
+	ret
+	.cfi_endproc
+	.size	__vdso_gettimeofday, . - __vdso_gettimeofday
+
+gettimeofday = __vdso_gettimeofday
+	.weak	gettimeofday
+
+
+	.globl	__vdso_time
+	.type	__vdso_time, @function
+	.balign	16
+	.cfi_startproc
+__vdso_time:
+	mov	$__NR_time, %eax
+	syscall
+	ret
+	.cfi_endproc
+	.size	__vdso_time, . - __vdso_time
+
+time = __vdso_time
+	.weak	time
+
+
+	.globl	__vdso_getcpu
+	.type	__vdso_getcpu, @function
+	.balign	16
+	.cfi_startproc
+__vdso_getcpu:
+	/* ??? There is no syscall number for this allocated on x64.
+	   We can handle this several ways:
+
+	   (1) Invent a syscall number for use within qemu.
+               It should be easy enough to pick a number that
+               is well out of the way of the kernel numbers.
+
+           (2) Force the emulated cpu to support the rdtscp insn,
+	       and initialize the TSC_AUX value the appropriate value.
+
+	   (3) Pretend that we're always running on cpu 0.
+
+	   This last is the one that's implemented here, with the
+	   tiny bit of extra code to support rdtscp in place.  */
+
+	xor	%ecx, %ecx		/* rdtscp w/ tsc_aux = 0 */
+
+	/* if (cpu != NULL) *cpu = (ecx & 0xfff); */
+	test	%rdi, %rdi
+	jz	1f
+	mov	%ecx, %eax
+	and	$0xfff, %eax
+	mov	%eax, (%rdi)
+
+	/* if (node != NULL) *node = (ecx >> 12); */
+1:	test	%rsi, %rsi
+	jz	2f
+	shr	$12, %ecx
+	mov	%ecx, (%rsi)
+
+2:	xor	%eax, %eax
+	ret
+	.cfi_endproc
+	.size	__vdso_getcpu, . - __vdso_getcpu
+
+getcpu = __vdso_getcpu
+	.weak	getcpu
+
+/* ??? Perhaps add elf notes.  E.g.
+
+   #include <linux/elfnote.h>
+   ELFNOTE_START(Linux, 0, "a")
+	.long LINUX_VERSION_CODE
+   ELFNOTE_END
+
+   but what version number would we set for QEMU?  */
diff --git a/pc-bios/vdso-linux-x64.ld b/pc-bios/vdso-linux-x64.ld
new file mode 100644
index 0000000000..2ef21fbcab
--- /dev/null
+++ b/pc-bios/vdso-linux-x64.ld
@@ -0,0 +1,81 @@
+/*
+ * Linker script for linux x64 replacement vdso.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+VERSION {
+	LINUX_2.6 {
+	global:
+		clock_gettime;
+		__vdso_clock_gettime;
+		gettimeofday;
+		__vdso_gettimeofday;
+		getcpu;
+		__vdso_getcpu;
+		time;
+		__vdso_time;
+	local: *;
+	};
+}
+
+PHDRS {
+	phdr		PT_PHDR		FLAGS(4) PHDRS;
+	data		PT_LOAD		FLAGS(6) FILEHDR PHDRS;
+	text		PT_LOAD		FLAGS(5);
+	dynamic		PT_DYNAMIC	FLAGS(4);
+	note		PT_NOTE		FLAGS(4);
+	/* ??? Various versions of ld don't know PT_GNU_EH_FRAME. */
+	eh_frame_hdr	0x6474e550;
+}
+
+SECTIONS {
+	/* ??? We can't really prelink to any address without knowing
+	   something about the virtual memory space of the host, since
+	   that leaks over into the available memory space of the guest.  */
+	. = SIZEOF_HEADERS;
+
+	/* The following, including the FILEHDRS and PHDRS, are modified
+	   when we relocate the binary.  We want them to be initially
+	   writable for the relocation; we'll force them read-only after.  */
+	.dynamic	: { *(.dynamic) }	:data :dynamic
+	.dynsym		: { *(.dynsym) }	:data
+	.data		: {
+		/* There ought not be any real read-write data.
+		   But since we manipulated the segment layout,
+		   we have to put these sections somewhere.  */
+		*(.data*)
+		*(.sdata*)
+		*(.got.plt) *(.got)
+		*(.gnu.linkonce.d.*)
+		*(.bss*)
+		*(.dynbss*)
+		*(.gnu.linkonce.b.*)
+	}
+
+	. += 4096;
+	.hash		: { *(.hash) }		:text
+	.gnu.hash	: { *(.gnu.hash) }
+	.dynstr		: { *(.dynstr) }
+	.gnu.version	: { *(.gnu.version) }
+	.gnu.version_d	: { *(.gnu.version_d) }
+	.gnu.version_r	: { *(.gnu.version_r) }
+	.note		: { *(.note*) }		:text :note
+	.eh_frame_hdr	: { *(.eh_frame_hdr) }	:text :eh_frame_hdr
+	.eh_frame	: { *(.eh_frame) }	:text
+	.rodata		: { *(.rodata) }
+
+	. = ALIGN(0x100);
+	.text		: { *(.text*) }		:text	=0x90909090
+}
diff --git a/pc-bios/vdso-linux-x64.so b/pc-bios/vdso-linux-x64.so
new file mode 100755
index 0000000000000000000000000000000000000000..07cba76a4ab52b9bc5be22e2a6e2fe8295691717
GIT binary patch
literal 7500
zcmeHMO=w(I6h4zlnxv*p>K|&V4$_uV>LZaN1%F7|CQa!iDVksv@pYP+W<rx0O<u}G
zBvLVIR3wWof(t?1xGLEQS!tyxR$O%H#+^SXC<>aDI-c*n^G)a7Ok9bAyqnzl?)}a=
z_uYHmeKU{mzBrH_Y)YksB`uFi*t<Pq`pj_M`snt_VcDjiozkHw(j0QIz!nwaDI1#D
zW_Hks-KwmnBMVU^6B3AP(Yks|*xiI5G(|j-aiB5J6`PNX(W2GC?3^cJP_N&r9}RF%
zL<<qVD5t&&@@W5RaV{PVy+nwN+iCnUL-JhjZ+}+HFnww3M=nq@b{*z)#qzK{GRrfD
zHyPex_<J=PZ`I=eu)c-M&(>cwyM_HHke2pZJ~;v0r~5=#W&4x&4c(iS?{fIN&EMq@
zn19Cc?=^py$2P(E?sdnM-zC3P6=LN<?ZLmt#>YHR9?^>VyL@O&K9US18AvjaWFW~v
zl7S=xNd}S(BpFCDkYpgqK$3y~bp{}RL92nj0}ZHEYki^40euHr4Rs&HwQB`}hfV?8
z#X~)*!Gc_*FX9)+zj{tS?_PW5<kGi0-n!?dOO<zCxbwZErPmL9x^Lgw*}}}}SF7Ut
z7xHsue`2~kao(RS1i{oyfuwcI=kmD)a*loC*?F0sD$Q5!$1tA$_e%D}$oOgh0S}r8
zX6gQcP1)bOAN{lg($j9O)Woo+Cbe(OUrtk&g6@KXT!F*-kB^MY+sl2U-gjTDoNwCu
z<K<7@_@VN|hxt@@`l0>i+o6MD+}(;#D;`t~6dzW6Q<3ARo_|bIm9A8GM{66jL-3f>
z6|KA%+6?(ait7#dta57&_`GuOYo#Wn&3~<|f3275Y`NNb@5|ve*UvcpYw>>XwV|bI
z(7ycH-fE}Fa_i92M$q!{_Z`bSd#_v-Z*E~G$emRTW+N=Jm0u|3W~L^@(}sG9H(8qZ
zin+OB#00YubD=OhH&rghI(}ZfQaLDyS19`DW^*$IznE8l_QVSc72LFcpmggPcwVr7
zP`1*Esk`#tcSY`@4vgoP`YCl-Vw>(A6vV@a@zi5`>TKHFq;L0u)WY!@-yG4Qp1h%&
zE$!5ai9_Z`JL8QOJd^zH0GF``fJhyg{<a);_4GibT6cZw#zd1pYxCzkh$l538Z`UV
zrHO~_N^br*fv2>A?@GqIy8RwH8ZvLB&u9Z{V*FORJ^kJIk`te~E%GE*7-;C`A9h@y
z-{;hqiNj7j_Z{h7+Th+L2OPG<FV>UVcJE*P+Us3c?uvT*EipK!K;`_ofBD-}AB*-n
zzAUv|ilFxCUcY8&&`9fS`8?K}(|Wh~e8u^6?fHrG&9(EBINws+?{R*caR0{nR^h&k
z^KG^BqBy_#`~vp0Y!~j2xc`mw1@g!jejD99;5{H!+qLu-$!N3D`G}`{qjL&8UyaU9
z@Y~hs`~uG##&^$CCXIK`O{R@^&pYO9eC~7ZtJjQo#}WV7lOz4ZCyt7LJUe=%KkJVU
r4n96G=8yFs$qx7ue_y%r#$m5Bjow_8!`n*C6u!-v;qTsrLchNN5$+*|

literal 0
HcmV?d00001

-- 
2.20.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/2] linux-user: Load a VDSO for x86-64.
  2020-05-19 19:44 [PATCH 0/2] linux-user: Load a vdso for x86_64 Richard Henderson
  2020-05-19 19:44 ` [PATCH 1/2] linux-user: Build vdso for x64 Richard Henderson
@ 2020-05-19 19:44 ` Richard Henderson
  2020-05-28  9:54 ` [PATCH 0/2] linux-user: Load a vdso for x86_64 Laurent Vivier
  2020-05-28 10:08 ` Peter Maydell
  3 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2020-05-19 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/elfload.c | 203 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 198 insertions(+), 5 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 01a9323a63..d70e27cb62 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -199,6 +199,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
     (*regs)[26] = env->segs[R_GS].selector & 0xffff;
 }
 
+#define VDSO_BASENAME  "vdso-linux-x64.so"
+
 #else
 
 #define ELF_START_MMAP 0x80000000
@@ -1499,6 +1501,10 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
 #define STACK_ALIGNMENT 16
 #endif
 
+#ifndef VDSO_BASENAME
+#define VDSO_BASENAME NULL
+#endif
+
 #ifdef TARGET_ABI32
 #undef ELF_CLASS
 #define ELF_CLASS ELFCLASS32
@@ -1859,7 +1865,8 @@ static abi_ulong loader_build_fdpic_loadmap(struct image_info *info, abi_ulong s
 static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
                                    struct elfhdr *exec,
                                    struct image_info *info,
-                                   struct image_info *interp_info)
+                                   struct image_info *interp_info,
+                                   struct image_info *vdso_info)
 {
     abi_ulong sp;
     abi_ulong u_argc, u_argv, u_envp, u_auxv;
@@ -1931,8 +1938,12 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     }
 
     size = (DLINFO_ITEMS + 1) * 2;
-    if (k_platform)
+    if (k_platform) {
         size += 2;
+    }
+    if (vdso_info) {
+        size += 4;
+    }
 #ifdef DLINFO_ARCH_ITEMS
     size += DLINFO_ARCH_ITEMS * 2;
 #endif
@@ -2009,6 +2020,10 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     if (u_platform) {
         NEW_AUX_ENT(AT_PLATFORM, u_platform);
     }
+    if (vdso_info) {
+        NEW_AUX_ENT(AT_SYSINFO, vdso_info->entry);
+        NEW_AUX_ENT(AT_SYSINFO_EHDR, vdso_info->load_addr);
+    }
     NEW_AUX_ENT (AT_NULL, 0);
 #undef NEW_AUX_ENT
 
@@ -2614,6 +2629,177 @@ static void load_elf_interp(const char *filename, struct image_info *info,
     exit(-1);
 }
 
+static void load_elf_vdso(const char *basename, struct image_info *info,
+                          char bprm_buf[BPRM_BUF_SIZE])
+{
+    const char *errmsg;
+    char *filename;
+    int fd, retval, i;
+    abi_ulong load_bias;
+
+    /*
+     * ??? What we really need access to is qemu_find_file, but that is
+     * only built for system targets at the moment.
+     */
+    filename = g_build_filename(CONFIG_QEMU_DATADIR, basename, NULL);
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        goto exit_perror;
+    }
+    g_free(filename);
+
+    retval = read(fd, bprm_buf, BPRM_BUF_SIZE);
+    if (retval < 0) {
+        goto exit_perror;
+    }
+    if (retval < BPRM_BUF_SIZE) {
+        memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval);
+    }
+
+    load_elf_image(basename, fd, info, NULL, bprm_buf);
+    load_bias = info->load_bias;
+
+    /*
+     * We most likely need to relocate the VDSO image.  The one built into
+     * the kernel is built for a fixed address.  The one built for QEMU is
+     * not, since that requires close control of the guest address space.
+     */
+    if (load_bias) {
+        struct elfhdr *ehdr = (struct elfhdr *)bprm_buf;
+        struct elf_phdr *phdr;
+        abi_ulong dynamic_addr = -1;
+        abi_ulong dynsym_addr = -1;
+
+        /*
+         * ??? Assume QEMU's VDSO is built "properly", which arranges
+         * for the PHDRs, and all the sections manipulated below, to
+         * be included with a writable load segment.
+         *
+         * ??? One might think that we'd need to relocate ehdr.e_entry,
+         * but for some reason glibc does that one itself, though that
+         * is also available via the AT_SYSINFO entry.
+         */
+
+        /* Relocate the program headers.  */
+        phdr = (struct elf_phdr *)g2h(info->load_addr + ehdr->e_phoff);
+        bswap_phdr(phdr, ehdr->e_phnum);
+        for (i = 0; i < ehdr->e_phnum; ++i) {
+            phdr[i].p_vaddr += load_bias;
+            phdr[i].p_paddr += load_bias;
+            if (phdr[i].p_type == PT_DYNAMIC) {
+                dynamic_addr = phdr[i].p_vaddr;
+            }
+        }
+        bswap_phdr(phdr, ehdr->e_phnum);
+
+        /* Relocate the DYNAMIC entries.  */
+        if (dynamic_addr != -1) {
+            abi_ulong tag, val, *dyn = (abi_ulong *)g2h(dynamic_addr);
+            do {
+                tag = tswapl(dyn[0]);
+                val = tswapl(dyn[1]);
+                switch (tag) {
+                case DT_SYMTAB:
+                    dynsym_addr = load_bias + val;
+                    dyn[1] = tswapl(dynsym_addr);
+                    break;
+                case DT_SYMENT:
+                    if (val != sizeof(struct elf_sym)) {
+                        errmsg = "VDSO has an unexpected dynamic symbol size";
+                        goto exit_errmsg;
+                    }
+                    break;
+
+                case DT_HASH:
+                case DT_STRTAB:
+                case DT_VERDEF:
+                case DT_VERSYM:
+                case DT_ADDRRNGLO ... DT_ADDRRNGHI:
+                    /* These entries store an address in the entry.  */
+                    dyn[1] = tswapl(load_bias + val);
+                    break;
+
+                case DT_NULL:
+                case DT_STRSZ:
+                case DT_SONAME:
+                case DT_DEBUG:
+                case DT_FLAGS:
+                case DT_FLAGS_1:
+                case DT_VERDEFNUM:
+                case DT_VALRNGLO ... DT_VALRNGHI:
+                    /* These entries store an integer in the entry.  */
+                    break;
+
+                case DT_REL:
+                case DT_RELA:
+                    /*
+                     * These entries indicate that the VDSO was built
+                     * incorrectly.  It should not have real relocations.
+                     */
+                    errmsg = "VDSO has relocations";
+                    goto exit_errmsg;
+                case DT_NEEDED:
+                case DT_VERNEED:
+                    errmsg = "VDSO has external dependancies";
+                    goto exit_errmsg;
+
+                default:
+                    /* This is probably something target specific.  */
+                    errmsg = "VDSO has unknown DYNAMIC entry";
+                    goto exit_errmsg;
+                }
+                dyn += 2;
+            } while (tag != DT_NULL);
+        }
+
+        /* Relocate the dynamic symbol table.  */
+        if (dynsym_addr != -1) {
+            struct elf_shdr *shdr;
+            struct elf_sym *sym;
+            int dynsym_size = 0;
+
+            /*
+             * Read the section headers to find out the size of the
+             * dynamic symbol table.
+             */
+            shdr = (struct elf_shdr *)g2h(info->load_addr + ehdr->e_shoff);
+            for (i = 0; i < ehdr->e_shnum; ++i) {
+                abi_ulong addr = tswapl(shdr[i].sh_addr) + load_bias;
+                if (addr == dynsym_addr) {
+                    dynsym_size = tswapl(shdr[i].sh_size);
+                    break;
+                }
+            }
+
+            sym = (struct elf_sym *)g2h(dynsym_addr);
+            for (i = 0; i < dynsym_size / sizeof(*sym); ++i) {
+                sym[i].st_value = tswapl(tswapl(sym[i].st_value) + load_bias);
+            }
+        }
+    }
+
+    /*
+     * Mark the VDSO writable segment read-only.
+     *
+     * ??? This assumes that the VDSO implementation doesn't actually
+     * have any truely writable data.  Perhaps we should instead use
+     * the PT_GNU_RELRO header to indicate that we really want this.
+     */
+    retval = target_mprotect(info->start_data, info->brk - info->start_data,
+                             PROT_READ);
+    if (retval < 0) {
+        goto exit_perror;
+    }
+    return;
+
+ exit_perror:
+    errmsg = strerror(errno);
+ exit_errmsg:
+    fprintf(stderr, "%s: %s\n", filename, errmsg);
+    exit(-1);
+}
+
+
 static int symfind(const void *s0, const void *s1)
 {
     target_ulong addr = *(target_ulong *)s0;
@@ -2803,7 +2989,7 @@ uint32_t get_elf_eflags(int fd)
 
 int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
 {
-    struct image_info interp_info;
+    struct image_info interp_info, vdso_info;
     struct elfhdr elf_ex;
     char *elf_interpreter = NULL;
     char *scratch;
@@ -2879,8 +3065,15 @@ 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));
+    /* If we've been given a VDSO to load, do so.  */
+    if (VDSO_BASENAME) {
+        load_elf_vdso(VDSO_BASENAME, &vdso_info, bprm->buf);
+    }
+
+    bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc,
+                                &elf_ex, info,
+                                (elf_interpreter ? &interp_info : NULL),
+                                (VDSO_BASENAME ? &vdso_info : NULL));
     info->start_stack = bprm->p;
 
     /* If we have an interpreter, set that as the program's entry point.
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] linux-user: Load a vdso for x86_64
  2020-05-19 19:44 [PATCH 0/2] linux-user: Load a vdso for x86_64 Richard Henderson
  2020-05-19 19:44 ` [PATCH 1/2] linux-user: Build vdso for x64 Richard Henderson
  2020-05-19 19:44 ` [PATCH 2/2] linux-user: Load a VDSO for x86-64 Richard Henderson
@ 2020-05-28  9:54 ` Laurent Vivier
  2020-05-28 10:08 ` Peter Maydell
  3 siblings, 0 replies; 10+ messages in thread
From: Laurent Vivier @ 2020-05-28  9:54 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 19/05/2020 à 21:44, Richard Henderson a écrit :
> The subject of AT_SYSINFO came up on launchpad recently.
> 
> There is definite room for improvement in all of this:
> 
> (1) We could build the vdso binary into qemu instead of really
>     loading it from the file system.  This would obviate the
>     several problems of locating the .so file.  It would also
>     mean that --static builds continue to create a standalone
>     qemu binary.
> 
> (2) We could use our cross-build system to build the vdso.
>     Though we'd still likely want to keep the image in git
>     along side the other rom images for when cross-build is
>     not available.
> 
> (3) There are some ??? comments where some decisions could be made,
>     and other ??? that are merely commenting on weirdness.
> 
> (4) It shouldn't take too much effort to create vdsos for the
>     other architectures.  But we should get this one as clean
>     as we can first.
> 
> Amusingly, this patch set has just turned 10 years old.
> First posted April 4, 2010.  I don't recall ever seeing
> any review on the several postings over the years.
> 
> 
> r~
> 
> 
> Richard Henderson (2):
>   linux-user: Build vdso for x64.
>   linux-user: Load a VDSO for x86-64.
> 
>  Makefile                  |   4 +-
>  linux-user/elfload.c      | 203 +++++++++++++++++++++++++++++++++++++-
>  pc-bios/Makefile          |   5 +
>  pc-bios/vdso-linux-x64.S  | 115 +++++++++++++++++++++
>  pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++
>  pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes
>  6 files changed, 401 insertions(+), 7 deletions(-)
>  create mode 100644 pc-bios/vdso-linux-x64.S
>  create mode 100644 pc-bios/vdso-linux-x64.ld
>  create mode 100755 pc-bios/vdso-linux-x64.so
> 

Applied to my linux-user branch.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] linux-user: Load a vdso for x86_64
  2020-05-19 19:44 [PATCH 0/2] linux-user: Load a vdso for x86_64 Richard Henderson
                   ` (2 preceding siblings ...)
  2020-05-28  9:54 ` [PATCH 0/2] linux-user: Load a vdso for x86_64 Laurent Vivier
@ 2020-05-28 10:08 ` Peter Maydell
  2020-05-28 10:32   ` Laurent Vivier
  3 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2020-05-28 10:08 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Laurent Vivier

On Tue, 19 May 2020 at 20:45, Richard Henderson
<richard.henderson@linaro.org> wrote:
>  Makefile                  |   4 +-
>  linux-user/elfload.c      | 203 +++++++++++++++++++++++++++++++++++++-
>  pc-bios/Makefile          |   5 +
>  pc-bios/vdso-linux-x64.S  | 115 +++++++++++++++++++++
>  pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++
>  pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes

I'm not really a fan of binaries in source control :-(

thanks
-- PMM


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] linux-user: Load a vdso for x86_64
  2020-05-28 10:08 ` Peter Maydell
@ 2020-05-28 10:32   ` Laurent Vivier
  2020-05-28 13:20     ` Philippe Mathieu-Daudé
  2020-05-28 21:42     ` Richard Henderson
  0 siblings, 2 replies; 10+ messages in thread
From: Laurent Vivier @ 2020-05-28 10:32 UTC (permalink / raw)
  To: Peter Maydell, Richard Henderson; +Cc: QEMU Developers

Le 28/05/2020 à 12:08, Peter Maydell a écrit :
> On Tue, 19 May 2020 at 20:45, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>  Makefile                  |   4 +-
>>  linux-user/elfload.c      | 203 +++++++++++++++++++++++++++++++++++++-
>>  pc-bios/Makefile          |   5 +
>>  pc-bios/vdso-linux-x64.S  | 115 +++++++++++++++++++++
>>  pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++
>>  pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes
> 
> I'm not really a fan of binaries in source control :-(

Can't we see that as a firmware or a ROM?
It's only 7,4 KB and needs a cross-compilation env to be rebuilt.

Do you have another solution?

If you don't like this I can remove the series. Let me know.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] linux-user: Load a vdso for x86_64
  2020-05-28 10:32   ` Laurent Vivier
@ 2020-05-28 13:20     ` Philippe Mathieu-Daudé
  2020-05-28 21:42     ` Richard Henderson
  1 sibling, 0 replies; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-05-28 13:20 UTC (permalink / raw)
  To: Laurent Vivier, Peter Maydell, Richard Henderson; +Cc: QEMU Developers

On 5/28/20 12:32 PM, Laurent Vivier wrote:
> Le 28/05/2020 à 12:08, Peter Maydell a écrit :
>> On Tue, 19 May 2020 at 20:45, Richard Henderson
>> <richard.henderson@linaro.org> wrote:
>>>  Makefile                  |   4 +-
>>>  linux-user/elfload.c      | 203 +++++++++++++++++++++++++++++++++++++-
>>>  pc-bios/Makefile          |   5 +
>>>  pc-bios/vdso-linux-x64.S  | 115 +++++++++++++++++++++
>>>  pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++
>>>  pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes
>>
>> I'm not really a fan of binaries in source control :-(
> 
> Can't we see that as a firmware or a ROM?
> It's only 7,4 KB and needs a cross-compilation env to be rebuilt.
> 
> Do you have another solution?

There are only 13 asm instructions, the rest is ELF structure.
Maybe we can strip the linker version ELF sections. Taking out the
alignment gap, not much left.

Nonetheless it is certainly annoying to write that using a readable
scripting language when the linker already does the job, and the patch
is already written/tested.

> 
> If you don't like this I can remove the series. Let me know.
> 
> Thanks,
> Laurent
> 
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] linux-user: Load a vdso for x86_64
  2020-05-28 10:32   ` Laurent Vivier
  2020-05-28 13:20     ` Philippe Mathieu-Daudé
@ 2020-05-28 21:42     ` Richard Henderson
  2020-05-29  8:50       ` Laurent Vivier
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2020-05-28 21:42 UTC (permalink / raw)
  To: Laurent Vivier, Peter Maydell; +Cc: QEMU Developers

On 5/28/20 3:32 AM, Laurent Vivier wrote:
> Le 28/05/2020 à 12:08, Peter Maydell a écrit :
>> On Tue, 19 May 2020 at 20:45, Richard Henderson
>> <richard.henderson@linaro.org> wrote:
>>>  Makefile                  |   4 +-
>>>  linux-user/elfload.c      | 203 +++++++++++++++++++++++++++++++++++++-
>>>  pc-bios/Makefile          |   5 +
>>>  pc-bios/vdso-linux-x64.S  | 115 +++++++++++++++++++++
>>>  pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++
>>>  pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes
>>
>> I'm not really a fan of binaries in source control :-(
> 
> Can't we see that as a firmware or a ROM?
> It's only 7,4 KB and needs a cross-compilation env to be rebuilt.
> 
> Do you have another solution?
> 
> If you don't like this I can remove the series. Let me know.

I think some more of the questions in the cover letter need answering.  Does
this patch set not break your own --static chroot tests, for example?


r~


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] linux-user: Load a vdso for x86_64
  2020-05-28 21:42     ` Richard Henderson
@ 2020-05-29  8:50       ` Laurent Vivier
  2020-05-29  8:58         ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 10+ messages in thread
From: Laurent Vivier @ 2020-05-29  8:50 UTC (permalink / raw)
  To: Richard Henderson, Peter Maydell; +Cc: QEMU Developers

Le 28/05/2020 à 23:42, Richard Henderson a écrit :
> On 5/28/20 3:32 AM, Laurent Vivier wrote:
>> Le 28/05/2020 à 12:08, Peter Maydell a écrit :
>>> On Tue, 19 May 2020 at 20:45, Richard Henderson
>>> <richard.henderson@linaro.org> wrote:
>>>>  Makefile                  |   4 +-
>>>>  linux-user/elfload.c      | 203 +++++++++++++++++++++++++++++++++++++-
>>>>  pc-bios/Makefile          |   5 +
>>>>  pc-bios/vdso-linux-x64.S  | 115 +++++++++++++++++++++
>>>>  pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++
>>>>  pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes
>>>
>>> I'm not really a fan of binaries in source control :-(
>>
>> Can't we see that as a firmware or a ROM?
>> It's only 7,4 KB and needs a cross-compilation env to be rebuilt.
>>
>> Do you have another solution?
>>
>> If you don't like this I can remove the series. Let me know.
> 
> I think some more of the questions in the cover letter need answering.  Does
> this patch set not break your own --static chroot tests, for example?

I will test my branch with this series in my --static chroot and remove
the series before the PR.

Thanks,
Laurent


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] linux-user: Load a vdso for x86_64
  2020-05-29  8:50       ` Laurent Vivier
@ 2020-05-29  8:58         ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-05-29  8:58 UTC (permalink / raw)
  To: Laurent Vivier, Richard Henderson, Peter Maydell; +Cc: QEMU Developers

On 5/29/20 10:50 AM, Laurent Vivier wrote:
> Le 28/05/2020 à 23:42, Richard Henderson a écrit :
>> On 5/28/20 3:32 AM, Laurent Vivier wrote:
>>> Le 28/05/2020 à 12:08, Peter Maydell a écrit :
>>>> On Tue, 19 May 2020 at 20:45, Richard Henderson
>>>> <richard.henderson@linaro.org> wrote:
>>>>>  Makefile                  |   4 +-
>>>>>  linux-user/elfload.c      | 203 +++++++++++++++++++++++++++++++++++++-
>>>>>  pc-bios/Makefile          |   5 +
>>>>>  pc-bios/vdso-linux-x64.S  | 115 +++++++++++++++++++++
>>>>>  pc-bios/vdso-linux-x64.ld |  81 +++++++++++++++
>>>>>  pc-bios/vdso-linux-x64.so | Bin 0 -> 7500 bytes
>>>>
>>>> I'm not really a fan of binaries in source control :-(
>>>
>>> Can't we see that as a firmware or a ROM?
>>> It's only 7,4 KB and needs a cross-compilation env to be rebuilt.
>>>
>>> Do you have another solution?
>>>
>>> If you don't like this I can remove the series. Let me know.
>>
>> I think some more of the questions in the cover letter need answering.  Does
>> this patch set not break your own --static chroot tests, for example?
> 
> I will test my branch with this series in my --static chroot and remove
> the series before the PR.

Another option is to keep patch #1 in your pullreq, but removing the .so
binary...

> 
> Thanks,
> Laurent
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-05-29  8:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-19 19:44 [PATCH 0/2] linux-user: Load a vdso for x86_64 Richard Henderson
2020-05-19 19:44 ` [PATCH 1/2] linux-user: Build vdso for x64 Richard Henderson
2020-05-19 19:44 ` [PATCH 2/2] linux-user: Load a VDSO for x86-64 Richard Henderson
2020-05-28  9:54 ` [PATCH 0/2] linux-user: Load a vdso for x86_64 Laurent Vivier
2020-05-28 10:08 ` Peter Maydell
2020-05-28 10:32   ` Laurent Vivier
2020-05-28 13:20     ` Philippe Mathieu-Daudé
2020-05-28 21:42     ` Richard Henderson
2020-05-29  8:50       ` Laurent Vivier
2020-05-29  8:58         ` Philippe Mathieu-Daudé

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.