Signed-off-by: Richard Henderson <richard.hender...@linaro.org>
---
 linux-user/loongarch64/vdso-asmoffset.h |   8 ++
 linux-user/elfload.c                    |   4 +
 linux-user/loongarch64/signal.c         |  17 +++-
 linux-user/loongarch64/Makefile.vdso    |   7 ++
 linux-user/loongarch64/meson.build      |   4 +
 linux-user/loongarch64/vdso.S           | 130 ++++++++++++++++++++++++
 linux-user/loongarch64/vdso.ld          |  73 +++++++++++++
 linux-user/loongarch64/vdso.so          | Bin 0 -> 3560 bytes
 linux-user/meson.build                  |   1 +
 9 files changed, 243 insertions(+), 1 deletion(-)
 create mode 100644 linux-user/loongarch64/vdso-asmoffset.h
 create mode 100644 linux-user/loongarch64/Makefile.vdso
 create mode 100644 linux-user/loongarch64/meson.build
 create mode 100644 linux-user/loongarch64/vdso.S
 create mode 100644 linux-user/loongarch64/vdso.ld
 create mode 100755 linux-user/loongarch64/vdso.so

diff --git a/linux-user/loongarch64/vdso-asmoffset.h 
b/linux-user/loongarch64/vdso-asmoffset.h
new file mode 100644
index 0000000000..60d113822f
--- /dev/null
+++ b/linux-user/loongarch64/vdso-asmoffset.h
@@ -0,0 +1,8 @@
+#define sizeof_rt_sigframe         0x240
+#define sizeof_sigcontext          0x110
+#define sizeof_sctx_info           0x10
+
+#define offsetof_sigcontext        0x130
+#define offsetof_sigcontext_pc     0
+#define offsetof_sigcontext_gr     8
+#define offsetof_fpucontext_fr     0
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index c9cba730de..498f5ed07e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1047,6 +1047,10 @@ static void elf_core_copy_regs(target_elf_gregset_t 
*regs, const CPUPPCState *en
 
 #define elf_check_arch(x) ((x) == EM_LOONGARCH)
 
+#include "vdso.c.inc"
+
+#define vdso_image_info()    &vdso_image_info
+
 static inline void init_thread(struct target_pt_regs *regs,
                                struct image_info *infop)
 {
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index bb8efb1172..b9d0a4cad7 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -10,8 +10,8 @@
 #include "user-internals.h"
 #include "signal-common.h"
 #include "linux-user/trace.h"
-
 #include "target/loongarch/internals.h"
+#include "vdso-asmoffset.h"
 
 /* FP context was used */
 #define SC_USED_FP              (1 << 0)
@@ -23,6 +23,11 @@ struct target_sigcontext {
     uint64_t sc_extcontext[0]   QEMU_ALIGNED(16);
 };
 
+QEMU_BUILD_BUG_ON(sizeof(struct target_sigcontext) != sizeof_sigcontext);
+QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext, sc_pc)
+                  != offsetof_sigcontext_pc);
+QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext, sc_regs)
+                  != offsetof_sigcontext_gr);
 
 #define FPU_CTX_MAGIC           0x46505501
 #define FPU_CTX_ALIGN           8
@@ -32,6 +37,9 @@ struct target_fpu_context {
     uint32_t fcsr;
 } QEMU_ALIGNED(FPU_CTX_ALIGN);
 
+QEMU_BUILD_BUG_ON(offsetof(struct target_fpu_context, regs)
+                  != offsetof_fpucontext_fr);
+
 #define CONTEXT_INFO_ALIGN      16
 struct target_sctx_info {
     uint32_t magic;
@@ -39,6 +47,8 @@ struct target_sctx_info {
     uint64_t padding;
 } QEMU_ALIGNED(CONTEXT_INFO_ALIGN);
 
+QEMU_BUILD_BUG_ON(sizeof(struct target_sctx_info) != sizeof_sctx_info);
+
 struct target_ucontext {
     abi_ulong tuc_flags;
     abi_ptr tuc_link;
@@ -53,6 +63,11 @@ struct target_rt_sigframe {
     struct target_ucontext       rs_uc;
 };
 
+QEMU_BUILD_BUG_ON(sizeof(struct target_rt_sigframe)
+                  != sizeof_rt_sigframe);
+QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe, rs_uc.tuc_mcontext)
+                  != offsetof_sigcontext);
+
 /*
  * These two structures are not present in guest memory, are private
  * to the signal implementation, but are largely copied from the
diff --git a/linux-user/loongarch64/Makefile.vdso 
b/linux-user/loongarch64/Makefile.vdso
new file mode 100644
index 0000000000..dc266a65cf
--- /dev/null
+++ b/linux-user/loongarch64/Makefile.vdso
@@ -0,0 +1,7 @@
+CROSS_CC ?= loongarch64-linux-gnu-gcc
+
+all: vdso.so
+
+vdso.so: vdso.S vdso.ld vdso-asmoffset.h Makefile.vdso
+       $(CROSS_CC) -nostdlib -fpic -shared -Wl,-T,vdso.ld -Wl,--build-id=sha1 \
+          -Wl,-h,linux-vdso.so.1 -Wl,--hash-style=both vdso.S -o $@
diff --git a/linux-user/loongarch64/meson.build 
b/linux-user/loongarch64/meson.build
new file mode 100644
index 0000000000..7ae2ea13c0
--- /dev/null
+++ b/linux-user/loongarch64/meson.build
@@ -0,0 +1,4 @@
+gen = [
+  gen_vdso.process('vdso.so', extra_args: ['-r', '__vdso_rt_sigreturn'])
+]
+linux_user_ss.add(when: 'TARGET_LOONGARCH64', if_true: gen)
diff --git a/linux-user/loongarch64/vdso.S b/linux-user/loongarch64/vdso.S
new file mode 100644
index 0000000000..780a5fda12
--- /dev/null
+++ b/linux-user/loongarch64/vdso.S
@@ -0,0 +1,130 @@
+/*
+ * Loongarch64 linux replacement vdso.
+ *
+ * Copyright 2023 Linaro, Ltd.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include "vdso-asmoffset.h"
+
+
+       .text
+
+.macro endf name
+       .globl  \name
+       .type   \name, @function
+       .size   \name, . - \name
+.endm
+
+.macro vdso_syscall name, nr
+\name:
+       li.w    $a7, \nr
+       syscall 0
+       jr      $ra
+endf   \name
+.endm
+
+       .cfi_startproc
+
+vdso_syscall __vdso_gettimeofday, __NR_gettimeofday
+vdso_syscall __vdso_clock_gettime, __NR_clock_gettime
+vdso_syscall __vdso_clock_getres, __NR_clock_getres
+vdso_syscall __vdso_getcpu, __NR_getcpu
+
+       .cfi_endproc
+
+/*
+ * Start the unwind info at least one instruction before the signal
+ * trampoline, because the unwinder will assume we are returning
+ * after a call site.
+ */
+
+       .cfi_startproc simple
+       .cfi_signal_frame
+
+#define B_GR   offsetof_sigcontext_gr
+#define B_FR   sizeof_sigcontext + sizeof_sctx_info + offsetof_fpucontext_fr
+
+       .cfi_def_cfa    2, offsetof_sigcontext
+
+       /* Return address */
+       .cfi_return_column 64
+       .cfi_offset     64, offsetof_sigcontext_pc      /* pc */
+
+       /* Integer registers */
+       .cfi_offset     1, B_GR + 1 * 8
+       .cfi_offset     2, B_GR + 2 * 8
+       .cfi_offset     3, B_GR + 3 * 8
+       .cfi_offset     4, B_GR + 4 * 8
+       .cfi_offset     5, B_GR + 5 * 8
+       .cfi_offset     6, B_GR + 6 * 8
+       .cfi_offset     7, B_GR + 7 * 8
+       .cfi_offset     8, B_GR + 8 * 8
+       .cfi_offset     9, B_GR + 9 * 8
+       .cfi_offset     10, B_GR + 10 * 8
+       .cfi_offset     11, B_GR + 11 * 8
+       .cfi_offset     12, B_GR + 12 * 8
+       .cfi_offset     13, B_GR + 13 * 8
+       .cfi_offset     14, B_GR + 14 * 8
+       .cfi_offset     15, B_GR + 15 * 8
+       .cfi_offset     16, B_GR + 16 * 8
+       .cfi_offset     17, B_GR + 17 * 8
+       .cfi_offset     18, B_GR + 18 * 8
+       .cfi_offset     19, B_GR + 19 * 8
+       .cfi_offset     20, B_GR + 20 * 8
+       .cfi_offset     21, B_GR + 21 * 8
+       .cfi_offset     22, B_GR + 22 * 8
+       .cfi_offset     23, B_GR + 23 * 8
+       .cfi_offset     24, B_GR + 24 * 8
+       .cfi_offset     25, B_GR + 25 * 8
+       .cfi_offset     26, B_GR + 26 * 8
+       .cfi_offset     27, B_GR + 27 * 8
+       .cfi_offset     28, B_GR + 28 * 8
+       .cfi_offset     29, B_GR + 29 * 8
+       .cfi_offset     30, B_GR + 30 * 8
+       .cfi_offset     31, B_GR + 31 * 8
+
+       /* Floating point registers */
+       .cfi_offset     32, B_FR + 0
+       .cfi_offset     33, B_FR + 1 * 8
+       .cfi_offset     34, B_FR + 2 * 8
+       .cfi_offset     35, B_FR + 3 * 8
+       .cfi_offset     36, B_FR + 4 * 8
+       .cfi_offset     37, B_FR + 5 * 8
+       .cfi_offset     38, B_FR + 6 * 8
+       .cfi_offset     39, B_FR + 7 * 8
+       .cfi_offset     40, B_FR + 8 * 8
+       .cfi_offset     41, B_FR + 9 * 8
+       .cfi_offset     42, B_FR + 10 * 8
+       .cfi_offset     43, B_FR + 11 * 8
+       .cfi_offset     44, B_FR + 12 * 8
+       .cfi_offset     45, B_FR + 13 * 8
+       .cfi_offset     46, B_FR + 14 * 8
+       .cfi_offset     47, B_FR + 15 * 8
+       .cfi_offset     48, B_FR + 16 * 8
+       .cfi_offset     49, B_FR + 17 * 8
+       .cfi_offset     50, B_FR + 18 * 8
+       .cfi_offset     51, B_FR + 19 * 8
+       .cfi_offset     52, B_FR + 20 * 8
+       .cfi_offset     53, B_FR + 21 * 8
+       .cfi_offset     54, B_FR + 22 * 8
+       .cfi_offset     55, B_FR + 23 * 8
+       .cfi_offset     56, B_FR + 24 * 8
+       .cfi_offset     57, B_FR + 25 * 8
+       .cfi_offset     58, B_FR + 26 * 8
+       .cfi_offset     59, B_FR + 27 * 8
+       .cfi_offset     60, B_FR + 28 * 8
+       .cfi_offset     61, B_FR + 29 * 8
+       .cfi_offset     62, B_FR + 30 * 8
+       .cfi_offset     63, B_FR + 31 * 8
+
+       nop
+
+__vdso_rt_sigreturn:
+       li.w    $a7, __NR_rt_sigreturn
+       syscall 0
+       .cfi_endproc
+endf __vdso_rt_sigreturn
diff --git a/linux-user/loongarch64/vdso.ld b/linux-user/loongarch64/vdso.ld
new file mode 100644
index 0000000000..682446ed0c
--- /dev/null
+++ b/linux-user/loongarch64/vdso.ld
@@ -0,0 +1,73 @@
+/*
+ * Linker script for linux loongarch64 replacement vdso.
+ *
+ * Copyright 2023 Linaro, Ltd.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+VERSION {
+        LINUX_5.10 {
+        global:
+                __vdso_getcpu;
+                __vdso_clock_getres;
+                __vdso_clock_gettime;
+                __vdso_gettimeofday;
+                __vdso_rt_sigreturn;
+
+        local: *;
+        };
+}
+
+
+PHDRS {
+        phdr            PT_PHDR         FLAGS(4) PHDRS;
+        load            PT_LOAD         FLAGS(7) FILEHDR PHDRS;
+        dynamic         PT_DYNAMIC      FLAGS(4);
+        eh_frame_hdr    PT_GNU_EH_FRAME;
+        note            PT_NOTE         FLAGS(4);
+}
+
+SECTIONS {
+        /*
+         * We can't 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.
+         */
+        .note           : { *(.note*) }         :load :note
+        .dynamic        : { *(.dynamic) }       :load :dynamic
+        .dynsym         : { *(.dynsym) }        :load
+        /*
+         * There ought not be any real read-write data.
+         * But since we manipulated the segment layout,
+         * we have to put these sections somewhere.
+         */
+        .data           : {
+                *(.data*)
+                *(.sdata*)
+                *(.got.plt) *(.got)
+                *(.gnu.linkonce.d.*)
+                *(.bss*)
+                *(.dynbss*)
+                *(.gnu.linkonce.b.*)
+        }
+
+        .rodata         : { *(.rodata*) }
+        .hash           : { *(.hash) }
+        .gnu.hash       : { *(.gnu.hash) }
+        .dynstr         : { *(.dynstr) }
+        .gnu.version    : { *(.gnu.version) }
+        .gnu.version_d  : { *(.gnu.version_d) }
+        .gnu.version_r  : { *(.gnu.version_r) }
+        .eh_frame_hdr   : { *(.eh_frame_hdr) }  :load :eh_frame_hdr
+        .eh_frame       : { *(.eh_frame) }      :load
+
+        .text           : { *(.text*) }         :load   =0xd503201f
+}
diff --git a/linux-user/loongarch64/vdso.so b/linux-user/loongarch64/vdso.so
new file mode 100755
index 
0000000000000000000000000000000000000000..bfaa26f2bfe1aaa01d9a349b8b030ef6323e1f8e
GIT binary patch
literal 3560
zcmc&%|4$r66ra5<U&=wttF2NG6%=bN^n^+++FFk<$Cr9ga)46PxE$QUp>Rj;76P?0
z*pkLHYK<{!)EKHwLri1P7+ZfbCjMajKaBm!V50tDu=w8YyuH2cp)oP>9lM{I&%8Hp
zXLj~8gA7MHeVQiNbm6WE5mF5|x7&qwgpg<vMR>0iJ4G?pw^^Ls9<srSt5RJvma2B5
zOH{cKEK$d3jNG9QIm)-B`t@R?;u$$#|Bq&z;@0U_0IO|UFe*1I7nO%qzh10Uag6S`
z-Poq%)zvp7qV*T`vX?&yG++NVu{3(B=kn+08z^)K-Oxs?yFE54u2LY{Z?`tngf~^a
zh$?7xDv_Edu|^YvR%U~ENugh1l|t{F^Zcl0p<c6K|BX#M{|%MzPgPgx#JZ}l@W8pF
z{{eM;TPtdw-05}U7nMA5t_EF{iw>SZ#nWrv<>Jc~e?al4l|S<l#m_6A=W~zZ`#t{0
z6`%C*GsuJZWfLLKczx5b=-tvV=pA|ABT|-8xBLw5S3>brr}2@GURkPzG*L^O6Z1o0
zZQxR4^6J;qwR=BlPwiV9O)S*Bz9|f2E}l&r6A9CtoKB?2<FN(i#-`F^FLKLmWG0bi
z4ui*LX1SIzjqKz^CSlHIQetW{H9LQhQUvj@Nkn@3hK7y9!KOxhIAuPO`w^w7-{o(9
zuAuLXzS|MJ$Y_i{yw6<vsf^mlXnx7GfPR#GY5fkOV>9A1Vu*s!Ds2$jnW)gtYFeN|
zw>bJ9NW=J%e$Dv}pkqi2l>63vMIiy&S@4|!eIB;WL6Hf?87P^7(iCi;g0dIDpM>&p
zsEEUkQP?>GmCpm5hF#CW9mBBu8Q3!jcShl^eyHk$y%D(k1O&RFx)bi{fP35Ez7W*h
zkWl-Tg!{jg@W2-m>eeJY_?d)#*Cagjsf7Kj5+1%P;lLFM^&d-USdnn>BMHF|B|P%J
zgvR$IG`%C?(AyFoeM>^~n-UJcA>pytBpkUYq2*Nxk6)1R#Il5==Oi3klJMlMML52(
z2v7a7XwT0Ej{O*3{0;c8oWtc+FKUE{_`iE4SN`5rUdj33Z0r68yRN3OAn5oGS#RAA
zxJNnqpU>-#4(9V)=|YjCv-$qTj^5_;C64aq^QEGY{^|IovTo-4mpS`TKL77@N<+O^
zQtOucA&szjr7z6aS%us49#Q^Y-RwoakPgNa@6|8bq{!c^gXb0R)y;Pm@72d^$QRN<
zVRW48Ywhi67e;^dWP7+{C>l0UD4uTZ3LAs1ZIQ5n+JZZ+5$-lRqpiJRqq`$2jIPMZ
zw$_Mova@p_JeYIbQqTTIrj!agisuqHha-K=)30E5VcLw1ieT2v*qG!}Ds3i2FustA
zO;3(l1@uLXnK2QZNX-V5v24=j&5X^=B{JE`bSkf6#6>WXG{!Tr>4cGtqbJuy&`ivm
zIHCW61+Wj=b9mq9?~>78U%5oIuehxiE7rcFNM5&$d|u;yjrTCtW7>b|EW`Qvyu-Mz
z`lWcv&GCGWIfNX2Dkx5t@p@-uf7R^7Gf#R)doSnb^BE(xlX3qX$MevFZNKALiR1Y^
z$GBCz)hXWERNoxW=RZb1@3Fr}7Q_i`*mUJ*y<+5jlAoXRFg}a%boS#q>l!1CkBrv{
zkKbm67{>xV6UTec;nnP@kmrqQTE^~pKF={Wdj{;yk6V`&&$7tpK1QB@&gbbaFE{%T
t^8Y9M)xhXH4|s8YUVn6E<GID6W2?&Xy2IE7Z+_~tP`sfI?92ZU{}&)DVfp|7

literal 0
HcmV?d00001

diff --git a/linux-user/meson.build b/linux-user/meson.build
index 3ff3bc5bbc..bc41e8c3bc 100644
--- a/linux-user/meson.build
+++ b/linux-user/meson.build
@@ -40,6 +40,7 @@ subdir('alpha')
 subdir('arm')
 subdir('hppa')
 subdir('i386')
+subdir('loongarch64')
 subdir('m68k')
 subdir('microblaze')
 subdir('mips64')
-- 
2.34.1


Reply via email to