Message ID | 20230829220228.928506-17-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | linux-user: Implement VDSOs | expand |
On Wed, Aug 30, 2023 at 9:17 AM Richard Henderson <richard.henderson@linaro.org> wrote: > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Acked-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > linux-user/riscv/vdso-asmoffset.h | 9 ++ > linux-user/elfload.c | 4 + > linux-user/riscv/signal.c | 8 ++ > linux-user/meson.build | 1 + > linux-user/riscv/meson.build | 30 +++++ > linux-user/riscv/vdso-32.so | Bin 0 -> 2888 bytes > linux-user/riscv/vdso-64.so | Bin 0 -> 3840 bytes > linux-user/riscv/vdso.S | 186 ++++++++++++++++++++++++++++++ > linux-user/riscv/vdso.ld | 74 ++++++++++++ > 9 files changed, 312 insertions(+) > create mode 100644 linux-user/riscv/vdso-asmoffset.h > create mode 100644 linux-user/riscv/meson.build > create mode 100755 linux-user/riscv/vdso-32.so > create mode 100755 linux-user/riscv/vdso-64.so > create mode 100644 linux-user/riscv/vdso.S > create mode 100644 linux-user/riscv/vdso.ld > > diff --git a/linux-user/riscv/vdso-asmoffset.h b/linux-user/riscv/vdso-asmoffset.h > new file mode 100644 > index 0000000000..123902ef61 > --- /dev/null > +++ b/linux-user/riscv/vdso-asmoffset.h > @@ -0,0 +1,9 @@ > +#ifdef TARGET_ABI32 > +# define sizeof_rt_sigframe 0x2b0 > +# define offsetof_uc_mcontext 0x120 > +# define offsetof_freg0 0x80 > +#else > +# define sizeof_rt_sigframe 0x340 > +# define offsetof_uc_mcontext 0x130 > +# define offsetof_freg0 0x100 > +#endif > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index eb22a17e0e..8f902bb427 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -1733,8 +1733,10 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, > > #ifdef TARGET_RISCV32 > #define ELF_CLASS ELFCLASS32 > +#include "vdso-32.c.inc" > #else > #define ELF_CLASS ELFCLASS64 > +#include "vdso-64.c.inc" > #endif > > #define ELF_HWCAP get_elf_hwcap() > @@ -1751,6 +1753,8 @@ static uint32_t get_elf_hwcap(void) > #undef MISA_BIT > } > > +#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/riscv/signal.c b/linux-user/riscv/signal.c > index eaa168199a..5449c7618a 100644 > --- a/linux-user/riscv/signal.c > +++ b/linux-user/riscv/signal.c > @@ -21,6 +21,7 @@ > #include "user-internals.h" > #include "signal-common.h" > #include "linux-user/trace.h" > +#include "vdso-asmoffset.h" > > /* Signal handler invocation must be transparent for the code being > interrupted. Complete CPU (hart) state is saved on entry and restored > @@ -37,6 +38,8 @@ struct target_sigcontext { > uint32_t fcsr; > }; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */ > > +QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext, fpr) != offsetof_freg0); > + > struct target_ucontext { > unsigned long uc_flags; > struct target_ucontext *uc_link; > @@ -51,6 +54,11 @@ struct target_rt_sigframe { > struct target_ucontext uc; > }; > > +QEMU_BUILD_BUG_ON(sizeof(struct target_rt_sigframe) > + != sizeof_rt_sigframe); > +QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe, uc.uc_mcontext) > + != offsetof_uc_mcontext); > + > static abi_ulong get_sigframe(struct target_sigaction *ka, > CPURISCVState *regs, size_t framesize) > { > diff --git a/linux-user/meson.build b/linux-user/meson.build > index 1b265ed365..3aa967b27c 100644 > --- a/linux-user/meson.build > +++ b/linux-user/meson.build > @@ -46,6 +46,7 @@ subdir('microblaze') > subdir('mips64') > subdir('mips') > subdir('ppc') > +subdir('riscv') > subdir('s390x') > subdir('sh4') > subdir('sparc') > diff --git a/linux-user/riscv/meson.build b/linux-user/riscv/meson.build > new file mode 100644 > index 0000000000..0a00cae9fd > --- /dev/null > +++ b/linux-user/riscv/meson.build > @@ -0,0 +1,30 @@ > +vdso_cmd = [ > + build_vdso_cmd, > + '-B', meson.project_build_root(), > + '-C', meson.current_source_dir(), > + '-T', 'riscv64-linux-user', > + '-o', '@OUTPUT@', > + '--', > + '-nostdlib', '-shared', '-fpic', > + '-Wl,-h,linux-vdso.so.1', > + '-Wl,--build-id=sha1', > + '-Wl,--hash-style=both', > + '-Wl,-T,@INPUT1@', > + '@INPUT0@' > +] > + > +vdso_32_so = custom_target(output: 'vdso-32.so', > + input: files('vdso.S', 'vdso.ld'), > + depend_files: files('vdso-asmoffset.h'), > + command: vdso_cmd + ['-mabi=ilp32d', '-march=rv32g']) > + > +vdso_64_so = custom_target(output: 'vdso-64.so', > + input: files('vdso.S', 'vdso.ld'), > + depend_files: files('vdso-asmoffset.h'), > + command: vdso_cmd + ['-mabi=lp64d', '-march=rv64g']) > + > +vdso_32_inc = gen_vdso.process(vdso_32_so, extra_args: ['-r', '__vdso_rt_sigreturn']) > +vdso_64_inc = gen_vdso.process(vdso_64_so, extra_args: ['-r', '__vdso_rt_sigreturn']) > + > +linux_user_ss.add(when: 'TARGET_RISCV32', if_true: vdso_32_inc) > +linux_user_ss.add(when: 'TARGET_RISCV64', if_true: vdso_64_inc) > diff --git a/linux-user/riscv/vdso-32.so b/linux-user/riscv/vdso-32.so > new file mode 100755 > index 0000000000000000000000000000000000000000..189e2f49e78f158cf49e6092edf7ece8cf7e8a25 > GIT binary patch > literal 2888 > zcmb_eU2GIp6h5=d;!>e*DVSm#Q)tD8)XjFOgkaNj+iv-BX`4b7lsMh)Zo3=lZnHbv > zKtn88L{tQ{1rbpTD59cPKoLbD(ZobwOnmZP<BKu=pbv`F@0*#sOtlX_c-n8zJwJ2i > z-nr*~Gb7<ho2F@^#4W#yvg+ZS@QTcWu9r%gEj3aiK4{uEa0O$6d4yYJu-1ctEiJZY > zjI~vL+bzr`Zlc2{;({telEM+#gsR{9oe@8Rn<!KxMyNRTRR?B@FF+h6WOaMD)NVO* > z_^kKZ)kEKYIr2xx`Cl$9zC2Qlm;ta>D<<^Y^{LDbXfEp#G@rpF=2!%M0Js^z)U7o@ > z<FT1C2fuTHYg1F19^CLRXs+)k=m;n9KS&b`Lfn`wpY3T(dK2_~+<6(a7nA0EXzzwr > zQX)T3^}wih#1}H?up=<b9CjmYpTp)JaT#1EHTRIu#wkcQg>&HZq;Sg2rzUufRx+n9 > zBt9Q)=9&HQMfv201A%14_`a!A7Y7zEI@ywLSorzTJ12V+qU%HPTt@Ft7)EL!k?D&^ > zw<}+4YbN%viu}u&P2`jh7sm$k%Ie#i&n5L#EE-D|%4ZEdm+H?ZjC?jNTT|)$w!3&+ > zKmO|^vbMc@lV0zyyBiaRxTgKF*R8+fmw%kco~r=ZR}}7*3%~i1?~53tsQuB(-S<?& > z<}>mkaV2yTx)XXY^fmecihH<Av>lpOKF=krQwDqmum_~GxH67rW^Mprtx9OhxTSdg > z1{7%0%ICT!J)WlcuHHv`MjzU}<*^6$Y<m2@y&IqCdb0DW_I;73*X>_(pzUDmGtJL7 > zjWv!p99ngF<#Q{J)IT3Q8hF8ftoFraFV(!fbfWcm^NFUDjjuGky6V)**H)aae?9m{ > z;7$LT+P9XyUGvV;$?A8PoUJ@}`}vCZZhOD%!mS@HxH$hq-$%ul=6+oCiTCnsbFRlQ > zH$DrV9ZGDEN2(@(6CNqmwChzh$EDPx$(T2=D2Mpy5>4DyAsMaOC8Kv}8gg7QpT||| > z>HITR;YO}VY4Og+b6<bzuA1mZoxJq#l*096-X62gn0IFp>oK44QjEvElV18l&G^Zt > za<L)NxF4SE(DGm^I9R6-1P23pl%u}jU{H_qXE+thW$7PI^(E4=1QNLcGssoj=QcaS > z;yt?D=E<;l#<JNBB27FX5T17m`HA8-*-3;vW!ctABwty!d7?z|j@xFb9;+;_=P9;$ > z)ygNkf$s`&vYf>))b7IW(4sxhUV&xL0>5zo$VZl_-Lx#mZ^4ipLeXHecLO$I&<?^T > z&s$O?VGPvz8GlfPpvh-_&`!P@hVA6T{ji<<#XfWL-z01&Uw#JL$%hh)t=}A6p6K&u > zq<Wj^t()6J>({o3-r3dB5^nA83hSVRdqb<k`o>UmB&>s3@Q%^LYxK6R(E6~xrnO7- > z)sc?oP(<%&Yugass1hAiViVg;Y%~+uP3N#_d}UWE(4m9*3O<sjh(EV|z=-xj8(B*y > z)hL}Y65@|<Pe%t*F>`=i=%^7De}6jfPeyY|%Wq^Y&rl+pOJ&m23_ULXL{jg|Mh6ml > zGLB4TiQh<UGsJHmE`QW8vZ>y@0h0dDQjSb^H(Q<OiKqsYs1{rd2TuiC%K3d^oeb-} > z!}k>5o9uSh<9nVsh_Si{>-hloC)=0x*q4O57hL9;b_2k+W<8!)f*hh+n>hr1zuVsk > zJjX;6eE-aAwtWbj-y=NZ{0>pVIZ@UDQ+7R`dtyF(svfT=?g!MjNe_Yq=i*#1OyT)r > zZC>O2{(@<WTDt*D<&i&#AM6||mG_99$35XWC3Z8x7L`XIN(?GLzZYAS0j<`n?x{k9 > q$h!h3d4}IMtjB#*-zylJ62L;gQ3kZCSAsF_TaY<uj>84(M&92P;-?}2 > > literal 0 > HcmV?d00001 > > diff --git a/linux-user/riscv/vdso-64.so b/linux-user/riscv/vdso-64.so > new file mode 100755 > index 0000000000000000000000000000000000000000..3c3b3a8cc579649e5108402b706bf7f741efd2e4 > GIT binary patch > literal 3840 > zcmc&%Z){Ul6hCieP{)QF3^Uxa3^Nr8G^Lqjk%hc&>o&BEW`j7R$)jt#wQ*~k_I247 > zB2(voWYYm6qJk)jf9oF<{Kq~RB_>8b>UWK3jL{hVV9<Had*_tbyGB3w!L!}>yZ8LL > z_r7!Q{k_}0fnZmerh$kHeuc{|0G$o<6?SC_f)1^)6rVLvjR;`tY`bnlAuhz73A)+t > z0!UNb2z5|GIuxDEiEx=>b2g<vL7bu`W%#7=&TvO6dRZ?h^9+4!Mk%hT-0Ef#Hrr|t > zBwrFjDzn_LisCOwz9fXTSTH}(-Mb4m{&4D#+@;gYKK=e$!~ad=mM<FvU!VzA&;!M^ > z!HT2mc?v}N?XQKDRpE|#`k-@L(teQ=gTl)TGj<b}GuAPxIhXvf8Lm+LFD=;PU*z%r > z<TeinKXdy6+ohlX16`QCdCr@RPs_FvDxrlFRmq0+tnXpH<Y5~1HSo&<yA@zJ)~KJT > z;=h{px}p!Ven8Q0WqnA|%RZ**(;5)cTCp3}Y?1Y+`AW)ZEy$mc-j`yu>NPdG242#U > zpSA9v*XR3Zyzzzu`xZ`~9bLQTL`Sl1^=C(}&kx4HFvg<UlrbDL&BSOdH53g`h%Pdc > zirgudMaoPpD>@90q;t|58p&njMj{f9#0%YLOe32Z&cw`ICJ7^nWNv&T4eP=GO%UAH > zyKBH`@oc&gCyY{7^k?fdd_(#>e(t9#I$sS~<m}M9m!U1U_qz(Rk<faQX!Wiw&4`qz > zT6AnfY(fkn>J&%?g=q#{lYOA=(X{%iGD}D2=K>blKjgOo%XutKSV#`rK(YN8tZVg^ > zW%EnR^=a+yDeay;_l{4S_oeS2c_98^^r77k-|@)6zMYST_6KKrW;-9#A8(s$J<xK{ > zduYQG>kc<R*>t4gsk)=JPgg%v`K<d`=kfOE^b=d3Z+qdUldUgqeyQb@?`7{Ro>w=# > zw*K{XZ(Nsee)F2Qn%-`Fr{VO~@7BF{)tTC}E8nmFV8w@(A60zpK1ch3=6eiFD;9Z& > zIrnTu7Td#90CVo@WmKPYH!)6GwpF;{$iB+5<=y1tZ^uU_k&TRjM*Wp%#x}PkeCbWb > zs4wj`!c-gbrF}+}9+QbkHbeT!#8505iJ_wxgZ@EWxER8-PB#~>uAGx%y$gi@iuH^6 > zfb1?PFYs%zKW0h}mBZk|)1#NvyP*{Cx$p!FUpl(MaVrYnonrlR=#hi%Ft{AN<xpck > zRnDeWr|r9>1aH}EeVPB9fu;PfL<bG~QS(gupY&;kkbG8$i{C52{_}L;9CAC>OY!Rv > z>WN=fzMN#e%HR80ukz?o)~h_7XT8ezpRiu#Z-_*~og>+}&y#}YaWFb>>-BHn)&WMS > zZ%0R<b5~!$K)Slc-yJY^`rCs616dEh^G2Y@=<4%t4;Ve2ePDD4ceMM1#*VJ8{=iOg > zbkH1=ZYicLMa0GYTEwN?Q-P`-tX$9$u>*Lr6QgE$5Yf!o7?)ZyWyZi0ok)g96A`O| > zzKCHn44&a+&Jz!3<F?++*qX6eCYwkliyB50Jh8YjlnIZ<jCd41r3D@{Hg1B)A`eg4 > zG&708oQWTh|19;`1AXJ@dq*PtAxPZs6!kc-MI&u(*{-tx1-<-zu)d?{C-(*7RT8>S > z&|OQ$7d{gFikwhnjuKDjiiFM)4I$&pxe*k9@+FbBAbrn>LS%foKME30lSuy(CwU<I > z?|7G!_yP~IgHFLHYP_ulXlI+m3ttM#eN_B8ozjGxv9{nCUwBn;C40*FGLGP_Xs5fW > zw1s~K<^9$C%LIsjXigHZ{!aL}{X=&UXT0#a;Eys8qvT)IcX7PXtMHwm%wPOv-K0H@ > z70gXq+Jf@?sY4WuYW|&bce>_zLdQ5U^nIW^ugt%Wo#oEzjHP;re^7j_7}W7=&@OB1 > QbiILp&>V6qv98Ad4M&HUy8r+H > > literal 0 > HcmV?d00001 > > diff --git a/linux-user/riscv/vdso.S b/linux-user/riscv/vdso.S > new file mode 100644 > index 0000000000..70a4f710db > --- /dev/null > +++ b/linux-user/riscv/vdso.S > @@ -0,0 +1,186 @@ > +/* > + * RISC-V linux replacement vdso. > + * > + * Copyright 2021 Linaro, Ltd. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include <asm/unistd.h> > +#include <asm/errno.h> > + > +#if __riscv_xlen == 32 > +# define TARGET_ABI32 > +#endif > +#include "vdso-asmoffset.h" > + > + .text > + > +.macro endf name > + .globl \name > + .type \name, @function > + .size \name, . - \name > +.endm > + > +.macro raw_syscall nr > + li a7, \nr > + ecall > +.endm > + > +.macro vdso_syscall name, nr > +\name: > + raw_syscall \nr > +endf \name > +.endm > + > +__vdso_gettimeofday: > + .cfi_startproc > +#ifdef __NR_gettimeofday > + raw_syscall __NR_gettimeofday > + ret > +#else > + /* No gettimeofday, fall back to clock_gettime64. */ > + beq a1, zero, 1f > + sw zero, 0(a1) /* tz->tz_minuteswest = 0 */ > + sw zero, 4(a1) /* tz->tz_dsttime = 0 */ > +1: addi sp, sp, -32 > + .cfi_adjust_cfa_offset 32 > + sw a0, 16(sp) /* save tv */ > + mv a0, sp > + raw_syscall __NR_clock_gettime64 > + lw t0, 0(sp) /* timespec.tv_sec.low */ > + lw t1, 4(sp) /* timespec.tv_sec.high */ > + lw t2, 8(sp) /* timespec.tv_nsec.low */ > + lw a1, 16(sp) /* restore tv */ > + addi sp, sp, 32 > + .cfi_adjust_cfa_offset -32 > + bne a0, zero, 9f /* syscall error? */ > + li a0, -EOVERFLOW > + bne t1, zero, 9f /* y2038? */ > + li a0, 0 > + li t3, 1000 > + divu t2, t2, t3 /* nsec -> usec */ > + sw t0, 0(a1) /* tz->tv_sec */ > + sw t2, 4(a1) /* tz->tv_usec */ > +9: ret > +#endif > + .cfi_endproc > +endf __vdso_gettimeofday > + > + .cfi_startproc > + > +#ifdef __NR_clock_gettime > +vdso_syscall __vdso_clock_gettime, __NR_clock_gettime > +#else > +vdso_syscall __vdso_clock_gettime, __NR_clock_gettime64 > +#endif > + > +#ifdef __NR_clock_getres > +vdso_syscall __vdso_clock_getres, __NR_clock_getres > +#else > +vdso_syscall __vdso_clock_getres, __NR_clock_getres_time64 > +#endif > + > +vdso_syscall __vdso_getcpu, __NR_getcpu > + > +__vdso_flush_icache: > + /* qemu does not need to flush the icache */ > + li a0, 0 > + ret > +endf __vdso_flush_icache > + > + .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 sizeof_reg (__riscv_xlen / 4) > +#define sizeof_freg 8 > +#define B_GR (offsetof_uc_mcontext - sizeof_rt_sigframe) > +#define B_FR (offsetof_uc_mcontext - sizeof_rt_sigframe + offsetof_freg0) > + > + .cfi_def_cfa 2, sizeof_rt_sigframe > + > + /* Return address */ > + .cfi_return_column 64 > + .cfi_offset 64, B_GR + 0 /* pc */ > + > + /* Integer registers */ > + .cfi_offset 1, B_GR + 1 * sizeof_reg /* r1 (ra) */ > + .cfi_offset 2, B_GR + 2 * sizeof_reg /* r2 (sp) */ > + .cfi_offset 3, B_GR + 3 * sizeof_reg > + .cfi_offset 4, B_GR + 4 * sizeof_reg > + .cfi_offset 5, B_GR + 5 * sizeof_reg > + .cfi_offset 6, B_GR + 6 * sizeof_reg > + .cfi_offset 7, B_GR + 7 * sizeof_reg > + .cfi_offset 8, B_GR + 8 * sizeof_reg > + .cfi_offset 9, B_GR + 9 * sizeof_reg > + .cfi_offset 10, B_GR + 10 * sizeof_reg > + .cfi_offset 11, B_GR + 11 * sizeof_reg > + .cfi_offset 12, B_GR + 12 * sizeof_reg > + .cfi_offset 13, B_GR + 13 * sizeof_reg > + .cfi_offset 14, B_GR + 14 * sizeof_reg > + .cfi_offset 15, B_GR + 15 * sizeof_reg > + .cfi_offset 16, B_GR + 16 * sizeof_reg > + .cfi_offset 17, B_GR + 17 * sizeof_reg > + .cfi_offset 18, B_GR + 18 * sizeof_reg > + .cfi_offset 19, B_GR + 19 * sizeof_reg > + .cfi_offset 20, B_GR + 20 * sizeof_reg > + .cfi_offset 21, B_GR + 21 * sizeof_reg > + .cfi_offset 22, B_GR + 22 * sizeof_reg > + .cfi_offset 23, B_GR + 23 * sizeof_reg > + .cfi_offset 24, B_GR + 24 * sizeof_reg > + .cfi_offset 25, B_GR + 25 * sizeof_reg > + .cfi_offset 26, B_GR + 26 * sizeof_reg > + .cfi_offset 27, B_GR + 27 * sizeof_reg > + .cfi_offset 28, B_GR + 28 * sizeof_reg > + .cfi_offset 29, B_GR + 29 * sizeof_reg > + .cfi_offset 30, B_GR + 30 * sizeof_reg > + .cfi_offset 31, B_GR + 31 * sizeof_reg /* r31 */ > + > + .cfi_offset 32, B_FR + 0 /* f0 */ > + .cfi_offset 33, B_FR + 1 * sizeof_freg /* f1 */ > + .cfi_offset 34, B_FR + 2 * sizeof_freg > + .cfi_offset 35, B_FR + 3 * sizeof_freg > + .cfi_offset 36, B_FR + 4 * sizeof_freg > + .cfi_offset 37, B_FR + 5 * sizeof_freg > + .cfi_offset 38, B_FR + 6 * sizeof_freg > + .cfi_offset 39, B_FR + 7 * sizeof_freg > + .cfi_offset 40, B_FR + 8 * sizeof_freg > + .cfi_offset 41, B_FR + 9 * sizeof_freg > + .cfi_offset 42, B_FR + 10 * sizeof_freg > + .cfi_offset 43, B_FR + 11 * sizeof_freg > + .cfi_offset 44, B_FR + 12 * sizeof_freg > + .cfi_offset 45, B_FR + 13 * sizeof_freg > + .cfi_offset 46, B_FR + 14 * sizeof_freg > + .cfi_offset 47, B_FR + 15 * sizeof_freg > + .cfi_offset 48, B_FR + 16 * sizeof_freg > + .cfi_offset 49, B_FR + 17 * sizeof_freg > + .cfi_offset 50, B_FR + 18 * sizeof_freg > + .cfi_offset 51, B_FR + 19 * sizeof_freg > + .cfi_offset 52, B_FR + 20 * sizeof_freg > + .cfi_offset 53, B_FR + 21 * sizeof_freg > + .cfi_offset 54, B_FR + 22 * sizeof_freg > + .cfi_offset 55, B_FR + 23 * sizeof_freg > + .cfi_offset 56, B_FR + 24 * sizeof_freg > + .cfi_offset 57, B_FR + 25 * sizeof_freg > + .cfi_offset 58, B_FR + 26 * sizeof_freg > + .cfi_offset 59, B_FR + 27 * sizeof_freg > + .cfi_offset 60, B_FR + 28 * sizeof_freg > + .cfi_offset 61, B_FR + 29 * sizeof_freg > + .cfi_offset 62, B_FR + 30 * sizeof_freg > + .cfi_offset 63, B_FR + 31 * sizeof_freg /* f31 */ > + > + nop > + > +__vdso_rt_sigreturn: > + raw_syscall __NR_rt_sigreturn > +endf __vdso_rt_sigreturn > + > + .cfi_endproc > diff --git a/linux-user/riscv/vdso.ld b/linux-user/riscv/vdso.ld > new file mode 100644 > index 0000000000..aabe2b0ab3 > --- /dev/null > +++ b/linux-user/riscv/vdso.ld > @@ -0,0 +1,74 @@ > +/* > + * Linker script for linux riscv replacement vdso. > + * > + * Copyright 2021 Linaro, Ltd. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +VERSION { > + LINUX_4.15 { > + global: > + __vdso_rt_sigreturn; > + __vdso_gettimeofday; > + __vdso_clock_gettime; > + __vdso_clock_getres; > + __vdso_getcpu; > + __vdso_flush_icache; > + > + 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 > +} > -- > 2.34.1 > >
diff --git a/linux-user/riscv/vdso-asmoffset.h b/linux-user/riscv/vdso-asmoffset.h new file mode 100644 index 0000000000..123902ef61 --- /dev/null +++ b/linux-user/riscv/vdso-asmoffset.h @@ -0,0 +1,9 @@ +#ifdef TARGET_ABI32 +# define sizeof_rt_sigframe 0x2b0 +# define offsetof_uc_mcontext 0x120 +# define offsetof_freg0 0x80 +#else +# define sizeof_rt_sigframe 0x340 +# define offsetof_uc_mcontext 0x130 +# define offsetof_freg0 0x100 +#endif diff --git a/linux-user/elfload.c b/linux-user/elfload.c index eb22a17e0e..8f902bb427 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1733,8 +1733,10 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, #ifdef TARGET_RISCV32 #define ELF_CLASS ELFCLASS32 +#include "vdso-32.c.inc" #else #define ELF_CLASS ELFCLASS64 +#include "vdso-64.c.inc" #endif #define ELF_HWCAP get_elf_hwcap() @@ -1751,6 +1753,8 @@ static uint32_t get_elf_hwcap(void) #undef MISA_BIT } +#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/riscv/signal.c b/linux-user/riscv/signal.c index eaa168199a..5449c7618a 100644 --- a/linux-user/riscv/signal.c +++ b/linux-user/riscv/signal.c @@ -21,6 +21,7 @@ #include "user-internals.h" #include "signal-common.h" #include "linux-user/trace.h" +#include "vdso-asmoffset.h" /* Signal handler invocation must be transparent for the code being interrupted. Complete CPU (hart) state is saved on entry and restored @@ -37,6 +38,8 @@ struct target_sigcontext { uint32_t fcsr; }; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */ +QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext, fpr) != offsetof_freg0); + struct target_ucontext { unsigned long uc_flags; struct target_ucontext *uc_link; @@ -51,6 +54,11 @@ struct target_rt_sigframe { struct target_ucontext uc; }; +QEMU_BUILD_BUG_ON(sizeof(struct target_rt_sigframe) + != sizeof_rt_sigframe); +QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe, uc.uc_mcontext) + != offsetof_uc_mcontext); + static abi_ulong get_sigframe(struct target_sigaction *ka, CPURISCVState *regs, size_t framesize) { diff --git a/linux-user/meson.build b/linux-user/meson.build index 1b265ed365..3aa967b27c 100644 --- a/linux-user/meson.build +++ b/linux-user/meson.build @@ -46,6 +46,7 @@ subdir('microblaze') subdir('mips64') subdir('mips') subdir('ppc') +subdir('riscv') subdir('s390x') subdir('sh4') subdir('sparc') diff --git a/linux-user/riscv/meson.build b/linux-user/riscv/meson.build new file mode 100644 index 0000000000..0a00cae9fd --- /dev/null +++ b/linux-user/riscv/meson.build @@ -0,0 +1,30 @@ +vdso_cmd = [ + build_vdso_cmd, + '-B', meson.project_build_root(), + '-C', meson.current_source_dir(), + '-T', 'riscv64-linux-user', + '-o', '@OUTPUT@', + '--', + '-nostdlib', '-shared', '-fpic', + '-Wl,-h,linux-vdso.so.1', + '-Wl,--build-id=sha1', + '-Wl,--hash-style=both', + '-Wl,-T,@INPUT1@', + '@INPUT0@' +] + +vdso_32_so = custom_target(output: 'vdso-32.so', + input: files('vdso.S', 'vdso.ld'), + depend_files: files('vdso-asmoffset.h'), + command: vdso_cmd + ['-mabi=ilp32d', '-march=rv32g']) + +vdso_64_so = custom_target(output: 'vdso-64.so', + input: files('vdso.S', 'vdso.ld'), + depend_files: files('vdso-asmoffset.h'), + command: vdso_cmd + ['-mabi=lp64d', '-march=rv64g']) + +vdso_32_inc = gen_vdso.process(vdso_32_so, extra_args: ['-r', '__vdso_rt_sigreturn']) +vdso_64_inc = gen_vdso.process(vdso_64_so, extra_args: ['-r', '__vdso_rt_sigreturn']) + +linux_user_ss.add(when: 'TARGET_RISCV32', if_true: vdso_32_inc) +linux_user_ss.add(when: 'TARGET_RISCV64', if_true: vdso_64_inc) diff --git a/linux-user/riscv/vdso-32.so b/linux-user/riscv/vdso-32.so new file mode 100755 index 0000000000000000000000000000000000000000..189e2f49e78f158cf49e6092edf7ece8cf7e8a25 GIT binary patch literal 2888 zcmb_eU2GIp6h5=d;!>e*DVSm#Q)tD8)XjFOgkaNj+iv-BX`4b7lsMh)Zo3=lZnHbv zKtn88L{tQ{1rbpTD59cPKoLbD(ZobwOnmZP<BKu=pbv`F@0*#sOtlX_c-n8zJwJ2i z-nr*~Gb7<ho2F@^#4W#yvg+ZS@QTcWu9r%gEj3aiK4{uEa0O$6d4yYJu-1ctEiJZY zjI~vL+bzr`Zlc2{;({telEM+#gsR{9oe@8Rn<!KxMyNRTRR?B@FF+h6WOaMD)NVO* z_^kKZ)kEKYIr2xx`Cl$9zC2Qlm;ta>D<<^Y^{LDbXfEp#G@rpF=2!%M0Js^z)U7o@ z<FT1C2fuTHYg1F19^CLRXs+)k=m;n9KS&b`Lfn`wpY3T(dK2_~+<6(a7nA0EXzzwr zQX)T3^}wih#1}H?up=<b9CjmYpTp)JaT#1EHTRIu#wkcQg>&HZq;Sg2rzUufRx+n9 zBt9Q)=9&HQMfv201A%14_`a!A7Y7zEI@ywLSorzTJ12V+qU%HPTt@Ft7)EL!k?D&^ zw<}+4YbN%viu}u&P2`jh7sm$k%Ie#i&n5L#EE-D|%4ZEdm+H?ZjC?jNTT|)$w!3&+ zKmO|^vbMc@lV0zyyBiaRxTgKF*R8+fmw%kco~r=ZR}}7*3%~i1?~53tsQuB(-S<?& z<}>mkaV2yTx)XXY^fmecihH<Av>lpOKF=krQwDqmum_~GxH67rW^Mprtx9OhxTSdg z1{7%0%ICT!J)WlcuHHv`MjzU}<*^6$Y<m2@y&IqCdb0DW_I;73*X>_(pzUDmGtJL7 zjWv!p99ngF<#Q{J)IT3Q8hF8ftoFraFV(!fbfWcm^NFUDjjuGky6V)**H)aae?9m{ z;7$LT+P9XyUGvV;$?A8PoUJ@}`}vCZZhOD%!mS@HxH$hq-$%ul=6+oCiTCnsbFRlQ zH$DrV9ZGDEN2(@(6CNqmwChzh$EDPx$(T2=D2Mpy5>4DyAsMaOC8Kv}8gg7QpT||| z>HITR;YO}VY4Og+b6<bzuA1mZoxJq#l*096-X62gn0IFp>oK44QjEvElV18l&G^Zt za<L)NxF4SE(DGm^I9R6-1P23pl%u}jU{H_qXE+thW$7PI^(E4=1QNLcGssoj=QcaS z;yt?D=E<;l#<JNBB27FX5T17m`HA8-*-3;vW!ctABwty!d7?z|j@xFb9;+;_=P9;$ z)ygNkf$s`&vYf>))b7IW(4sxhUV&xL0>5zo$VZl_-Lx#mZ^4ipLeXHecLO$I&<?^T z&s$O?VGPvz8GlfPpvh-_&`!P@hVA6T{ji<<#XfWL-z01&Uw#JL$%hh)t=}A6p6K&u zq<Wj^t()6J>({o3-r3dB5^nA83hSVRdqb<k`o>UmB&>s3@Q%^LYxK6R(E6~xrnO7- z)sc?oP(<%&Yugass1hAiViVg;Y%~+uP3N#_d}UWE(4m9*3O<sjh(EV|z=-xj8(B*y z)hL}Y65@|<Pe%t*F>`=i=%^7De}6jfPeyY|%Wq^Y&rl+pOJ&m23_ULXL{jg|Mh6ml zGLB4TiQh<UGsJHmE`QW8vZ>y@0h0dDQjSb^H(Q<OiKqsYs1{rd2TuiC%K3d^oeb-} z!}k>5o9uSh<9nVsh_Si{>-hloC)=0x*q4O57hL9;b_2k+W<8!)f*hh+n>hr1zuVsk zJjX;6eE-aAwtWbj-y=NZ{0>pVIZ@UDQ+7R`dtyF(svfT=?g!MjNe_Yq=i*#1OyT)r zZC>O2{(@<WTDt*D<&i&#AM6||mG_99$35XWC3Z8x7L`XIN(?GLzZYAS0j<`n?x{k9 q$h!h3d4}IMtjB#*-zylJ62L;gQ3kZCSAsF_TaY<uj>84(M&92P;-?}2 literal 0 HcmV?d00001 diff --git a/linux-user/riscv/vdso-64.so b/linux-user/riscv/vdso-64.so new file mode 100755 index 0000000000000000000000000000000000000000..3c3b3a8cc579649e5108402b706bf7f741efd2e4 GIT binary patch literal 3840 zcmc&%Z){Ul6hCieP{)QF3^Uxa3^Nr8G^Lqjk%hc&>o&BEW`j7R$)jt#wQ*~k_I247 zB2(voWYYm6qJk)jf9oF<{Kq~RB_>8b>UWK3jL{hVV9<Had*_tbyGB3w!L!}>yZ8LL z_r7!Q{k_}0fnZmerh$kHeuc{|0G$o<6?SC_f)1^)6rVLvjR;`tY`bnlAuhz73A)+t z0!UNb2z5|GIuxDEiEx=>b2g<vL7bu`W%#7=&TvO6dRZ?h^9+4!Mk%hT-0Ef#Hrr|t zBwrFjDzn_LisCOwz9fXTSTH}(-Mb4m{&4D#+@;gYKK=e$!~ad=mM<FvU!VzA&;!M^ z!HT2mc?v}N?XQKDRpE|#`k-@L(teQ=gTl)TGj<b}GuAPxIhXvf8Lm+LFD=;PU*z%r z<TeinKXdy6+ohlX16`QCdCr@RPs_FvDxrlFRmq0+tnXpH<Y5~1HSo&<yA@zJ)~KJT z;=h{px}p!Ven8Q0WqnA|%RZ**(;5)cTCp3}Y?1Y+`AW)ZEy$mc-j`yu>NPdG242#U zpSA9v*XR3Zyzzzu`xZ`~9bLQTL`Sl1^=C(}&kx4HFvg<UlrbDL&BSOdH53g`h%Pdc zirgudMaoPpD>@90q;t|58p&njMj{f9#0%YLOe32Z&cw`ICJ7^nWNv&T4eP=GO%UAH zyKBH`@oc&gCyY{7^k?fdd_(#>e(t9#I$sS~<m}M9m!U1U_qz(Rk<faQX!Wiw&4`qz zT6AnfY(fkn>J&%?g=q#{lYOA=(X{%iGD}D2=K>blKjgOo%XutKSV#`rK(YN8tZVg^ zW%EnR^=a+yDeay;_l{4S_oeS2c_98^^r77k-|@)6zMYST_6KKrW;-9#A8(s$J<xK{ zduYQG>kc<R*>t4gsk)=JPgg%v`K<d`=kfOE^b=d3Z+qdUldUgqeyQb@?`7{Ro>w=# zw*K{XZ(Nsee)F2Qn%-`Fr{VO~@7BF{)tTC}E8nmFV8w@(A60zpK1ch3=6eiFD;9Z& zIrnTu7Td#90CVo@WmKPYH!)6GwpF;{$iB+5<=y1tZ^uU_k&TRjM*Wp%#x}PkeCbWb zs4wj`!c-gbrF}+}9+QbkHbeT!#8505iJ_wxgZ@EWxER8-PB#~>uAGx%y$gi@iuH^6 zfb1?PFYs%zKW0h}mBZk|)1#NvyP*{Cx$p!FUpl(MaVrYnonrlR=#hi%Ft{AN<xpck zRnDeWr|r9>1aH}EeVPB9fu;PfL<bG~QS(gupY&;kkbG8$i{C52{_}L;9CAC>OY!Rv z>WN=fzMN#e%HR80ukz?o)~h_7XT8ezpRiu#Z-_*~og>+}&y#}YaWFb>>-BHn)&WMS zZ%0R<b5~!$K)Slc-yJY^`rCs616dEh^G2Y@=<4%t4;Ve2ePDD4ceMM1#*VJ8{=iOg zbkH1=ZYicLMa0GYTEwN?Q-P`-tX$9$u>*Lr6QgE$5Yf!o7?)ZyWyZi0ok)g96A`O| zzKCHn44&a+&Jz!3<F?++*qX6eCYwkliyB50Jh8YjlnIZ<jCd41r3D@{Hg1B)A`eg4 zG&708oQWTh|19;`1AXJ@dq*PtAxPZs6!kc-MI&u(*{-tx1-<-zu)d?{C-(*7RT8>S z&|OQ$7d{gFikwhnjuKDjiiFM)4I$&pxe*k9@+FbBAbrn>LS%foKME30lSuy(CwU<I z?|7G!_yP~IgHFLHYP_ulXlI+m3ttM#eN_B8ozjGxv9{nCUwBn;C40*FGLGP_Xs5fW zw1s~K<^9$C%LIsjXigHZ{!aL}{X=&UXT0#a;Eys8qvT)IcX7PXtMHwm%wPOv-K0H@ z70gXq+Jf@?sY4WuYW|&bce>_zLdQ5U^nIW^ugt%Wo#oEzjHP;re^7j_7}W7=&@OB1 QbiILp&>V6qv98Ad4M&HUy8r+H literal 0 HcmV?d00001 diff --git a/linux-user/riscv/vdso.S b/linux-user/riscv/vdso.S new file mode 100644 index 0000000000..70a4f710db --- /dev/null +++ b/linux-user/riscv/vdso.S @@ -0,0 +1,186 @@ +/* + * RISC-V linux replacement vdso. + * + * Copyright 2021 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <asm/unistd.h> +#include <asm/errno.h> + +#if __riscv_xlen == 32 +# define TARGET_ABI32 +#endif +#include "vdso-asmoffset.h" + + .text + +.macro endf name + .globl \name + .type \name, @function + .size \name, . - \name +.endm + +.macro raw_syscall nr + li a7, \nr + ecall +.endm + +.macro vdso_syscall name, nr +\name: + raw_syscall \nr +endf \name +.endm + +__vdso_gettimeofday: + .cfi_startproc +#ifdef __NR_gettimeofday + raw_syscall __NR_gettimeofday + ret +#else + /* No gettimeofday, fall back to clock_gettime64. */ + beq a1, zero, 1f + sw zero, 0(a1) /* tz->tz_minuteswest = 0 */ + sw zero, 4(a1) /* tz->tz_dsttime = 0 */ +1: addi sp, sp, -32 + .cfi_adjust_cfa_offset 32 + sw a0, 16(sp) /* save tv */ + mv a0, sp + raw_syscall __NR_clock_gettime64 + lw t0, 0(sp) /* timespec.tv_sec.low */ + lw t1, 4(sp) /* timespec.tv_sec.high */ + lw t2, 8(sp) /* timespec.tv_nsec.low */ + lw a1, 16(sp) /* restore tv */ + addi sp, sp, 32 + .cfi_adjust_cfa_offset -32 + bne a0, zero, 9f /* syscall error? */ + li a0, -EOVERFLOW + bne t1, zero, 9f /* y2038? */ + li a0, 0 + li t3, 1000 + divu t2, t2, t3 /* nsec -> usec */ + sw t0, 0(a1) /* tz->tv_sec */ + sw t2, 4(a1) /* tz->tv_usec */ +9: ret +#endif + .cfi_endproc +endf __vdso_gettimeofday + + .cfi_startproc + +#ifdef __NR_clock_gettime +vdso_syscall __vdso_clock_gettime, __NR_clock_gettime +#else +vdso_syscall __vdso_clock_gettime, __NR_clock_gettime64 +#endif + +#ifdef __NR_clock_getres +vdso_syscall __vdso_clock_getres, __NR_clock_getres +#else +vdso_syscall __vdso_clock_getres, __NR_clock_getres_time64 +#endif + +vdso_syscall __vdso_getcpu, __NR_getcpu + +__vdso_flush_icache: + /* qemu does not need to flush the icache */ + li a0, 0 + ret +endf __vdso_flush_icache + + .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 sizeof_reg (__riscv_xlen / 4) +#define sizeof_freg 8 +#define B_GR (offsetof_uc_mcontext - sizeof_rt_sigframe) +#define B_FR (offsetof_uc_mcontext - sizeof_rt_sigframe + offsetof_freg0) + + .cfi_def_cfa 2, sizeof_rt_sigframe + + /* Return address */ + .cfi_return_column 64 + .cfi_offset 64, B_GR + 0 /* pc */ + + /* Integer registers */ + .cfi_offset 1, B_GR + 1 * sizeof_reg /* r1 (ra) */ + .cfi_offset 2, B_GR + 2 * sizeof_reg /* r2 (sp) */ + .cfi_offset 3, B_GR + 3 * sizeof_reg + .cfi_offset 4, B_GR + 4 * sizeof_reg + .cfi_offset 5, B_GR + 5 * sizeof_reg + .cfi_offset 6, B_GR + 6 * sizeof_reg + .cfi_offset 7, B_GR + 7 * sizeof_reg + .cfi_offset 8, B_GR + 8 * sizeof_reg + .cfi_offset 9, B_GR + 9 * sizeof_reg + .cfi_offset 10, B_GR + 10 * sizeof_reg + .cfi_offset 11, B_GR + 11 * sizeof_reg + .cfi_offset 12, B_GR + 12 * sizeof_reg + .cfi_offset 13, B_GR + 13 * sizeof_reg + .cfi_offset 14, B_GR + 14 * sizeof_reg + .cfi_offset 15, B_GR + 15 * sizeof_reg + .cfi_offset 16, B_GR + 16 * sizeof_reg + .cfi_offset 17, B_GR + 17 * sizeof_reg + .cfi_offset 18, B_GR + 18 * sizeof_reg + .cfi_offset 19, B_GR + 19 * sizeof_reg + .cfi_offset 20, B_GR + 20 * sizeof_reg + .cfi_offset 21, B_GR + 21 * sizeof_reg + .cfi_offset 22, B_GR + 22 * sizeof_reg + .cfi_offset 23, B_GR + 23 * sizeof_reg + .cfi_offset 24, B_GR + 24 * sizeof_reg + .cfi_offset 25, B_GR + 25 * sizeof_reg + .cfi_offset 26, B_GR + 26 * sizeof_reg + .cfi_offset 27, B_GR + 27 * sizeof_reg + .cfi_offset 28, B_GR + 28 * sizeof_reg + .cfi_offset 29, B_GR + 29 * sizeof_reg + .cfi_offset 30, B_GR + 30 * sizeof_reg + .cfi_offset 31, B_GR + 31 * sizeof_reg /* r31 */ + + .cfi_offset 32, B_FR + 0 /* f0 */ + .cfi_offset 33, B_FR + 1 * sizeof_freg /* f1 */ + .cfi_offset 34, B_FR + 2 * sizeof_freg + .cfi_offset 35, B_FR + 3 * sizeof_freg + .cfi_offset 36, B_FR + 4 * sizeof_freg + .cfi_offset 37, B_FR + 5 * sizeof_freg + .cfi_offset 38, B_FR + 6 * sizeof_freg + .cfi_offset 39, B_FR + 7 * sizeof_freg + .cfi_offset 40, B_FR + 8 * sizeof_freg + .cfi_offset 41, B_FR + 9 * sizeof_freg + .cfi_offset 42, B_FR + 10 * sizeof_freg + .cfi_offset 43, B_FR + 11 * sizeof_freg + .cfi_offset 44, B_FR + 12 * sizeof_freg + .cfi_offset 45, B_FR + 13 * sizeof_freg + .cfi_offset 46, B_FR + 14 * sizeof_freg + .cfi_offset 47, B_FR + 15 * sizeof_freg + .cfi_offset 48, B_FR + 16 * sizeof_freg + .cfi_offset 49, B_FR + 17 * sizeof_freg + .cfi_offset 50, B_FR + 18 * sizeof_freg + .cfi_offset 51, B_FR + 19 * sizeof_freg + .cfi_offset 52, B_FR + 20 * sizeof_freg + .cfi_offset 53, B_FR + 21 * sizeof_freg + .cfi_offset 54, B_FR + 22 * sizeof_freg + .cfi_offset 55, B_FR + 23 * sizeof_freg + .cfi_offset 56, B_FR + 24 * sizeof_freg + .cfi_offset 57, B_FR + 25 * sizeof_freg + .cfi_offset 58, B_FR + 26 * sizeof_freg + .cfi_offset 59, B_FR + 27 * sizeof_freg + .cfi_offset 60, B_FR + 28 * sizeof_freg + .cfi_offset 61, B_FR + 29 * sizeof_freg + .cfi_offset 62, B_FR + 30 * sizeof_freg + .cfi_offset 63, B_FR + 31 * sizeof_freg /* f31 */ + + nop + +__vdso_rt_sigreturn: + raw_syscall __NR_rt_sigreturn +endf __vdso_rt_sigreturn + + .cfi_endproc diff --git a/linux-user/riscv/vdso.ld b/linux-user/riscv/vdso.ld new file mode 100644 index 0000000000..aabe2b0ab3 --- /dev/null +++ b/linux-user/riscv/vdso.ld @@ -0,0 +1,74 @@ +/* + * Linker script for linux riscv replacement vdso. + * + * Copyright 2021 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_4.15 { + global: + __vdso_rt_sigreturn; + __vdso_gettimeofday; + __vdso_clock_gettime; + __vdso_clock_getres; + __vdso_getcpu; + __vdso_flush_icache; + + 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 +}
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/riscv/vdso-asmoffset.h | 9 ++ linux-user/elfload.c | 4 + linux-user/riscv/signal.c | 8 ++ linux-user/meson.build | 1 + linux-user/riscv/meson.build | 30 +++++ linux-user/riscv/vdso-32.so | Bin 0 -> 2888 bytes linux-user/riscv/vdso-64.so | Bin 0 -> 3840 bytes linux-user/riscv/vdso.S | 186 ++++++++++++++++++++++++++++++ linux-user/riscv/vdso.ld | 74 ++++++++++++ 9 files changed, 312 insertions(+) create mode 100644 linux-user/riscv/vdso-asmoffset.h create mode 100644 linux-user/riscv/meson.build create mode 100755 linux-user/riscv/vdso-32.so create mode 100755 linux-user/riscv/vdso-64.so create mode 100644 linux-user/riscv/vdso.S create mode 100644 linux-user/riscv/vdso.ld