From ee95fae075c68cf1ae0fc1ffb00acca685bfb2c8 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 15 Jun 2021 10:21:37 -0700 Subject: [PATCH] linux-user/aarch64: Add vdso MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- linux-user/aarch64/Makefile.vdso | 15 +++++++ linux-user/aarch64/meson.build | 11 +++++ linux-user/aarch64/vdso-be.so | Bin 0 -> 3216 bytes linux-user/aarch64/vdso-le.so | Bin 0 -> 3216 bytes linux-user/aarch64/vdso.S | 71 ++++++++++++++++++++++++++++++ linux-user/aarch64/vdso.ld | 72 +++++++++++++++++++++++++++++++ linux-user/elfload.c | 6 +++ linux-user/meson.build | 1 + 8 files changed, 176 insertions(+) create mode 100644 linux-user/aarch64/Makefile.vdso create mode 100644 linux-user/aarch64/meson.build create mode 100755 linux-user/aarch64/vdso-be.so create mode 100755 linux-user/aarch64/vdso-le.so create mode 100644 linux-user/aarch64/vdso.S create mode 100644 linux-user/aarch64/vdso.ld diff --git a/linux-user/aarch64/Makefile.vdso b/linux-user/aarch64/Makefile.vdso new file mode 100644 index 00000000000..599958116b6 --- /dev/null +++ b/linux-user/aarch64/Makefile.vdso @@ -0,0 +1,15 @@ +include $(BUILD_DIR)/tests/tcg/aarch64-linux-user/config-target.mak + +SUBDIR = $(SRC_PATH)/linux-user/aarch64 +VPATH += $(SUBDIR) + +all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so + +LDFLAGS = -nostdlib -shared -Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \ + -Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld + +$(SUBDIR)/vdso-be.so: vdso.S vdso.ld + $(CC) -o $@ $(LDFLAGS) -mbig-endian $< + +$(SUBDIR)/vdso-le.so: vdso.S vdso.ld + $(CC) -o $@ $(LDFLAGS) -mlittle-endian $< diff --git a/linux-user/aarch64/meson.build b/linux-user/aarch64/meson.build new file mode 100644 index 00000000000..248c578d15c --- /dev/null +++ b/linux-user/aarch64/meson.build @@ -0,0 +1,11 @@ +# TARGET_BIG_ENDIAN is defined to 'n' for little-endian; which means it +# is always true as far as source_set.apply() is concerned. Always build +# both header files and include the right one via #if. + +vdso_be_inc = gen_vdso.process('vdso-be.so', + extra_args: ['-r', '__kernel_rt_sigreturn']) + +vdso_le_inc = gen_vdso.process('vdso-le.so', + extra_args: ['-r', '__kernel_rt_sigreturn']) + +linux_user_ss.add(when: 'TARGET_AARCH64', if_true: [vdso_be_inc, vdso_le_inc]) diff --git a/linux-user/aarch64/vdso-be.so b/linux-user/aarch64/vdso-be.so new file mode 100755 index 0000000000000000000000000000000000000000..6084f3d1a701316004894fcdd739c4e1e0463b68 GIT binary patch literal 3216 zc-qBQOK1~882)!RuhwWESQIK+p@>LbY6XqdLsOHsO03#is$RyJY@76v$YyI(LG8hd z2eINwJlKjC1<#5XJtzp?M5Q3;Ne~3lgI;{p+1=UQe}>(NAUN&joBx~n=ly>(7t)zN zS(d;}3f!l^h_F(R4Y37gB_K?H8=-+(5&DJrdLl~ed4w42BMLQB=rf1*sAR7{X)yqS zM~LN(_lG^dP}Lt{t$-o)ne83(M@R`6V?K@a3-=F>z+S7#vm-XhY<-}f;Vi>d4Aw=>`N#7zoa$;#MwBO8E39{3h^J%eoQpM$`_w@Bvk(aYG)ndpCP_R zvd*94t+$mA;|gdUL#U3#zQ`gSs?-AynQhinmbfN2>PatGc z(@WYE8P^P>IIWe(^4U3$%}tealTMirt!ovJ)eTZ9j_aB+qnBW+SemJBKa;PNRr3b862(ijwD-P)to&MXgFV<0PgN9e9nU zvqLm0H%hJXO%7+CO>;l2Ge_E$S6f@=Ur^_lj}`LTve)qT0I~~BcD~l`DenHbaqaLj zuP-jI2yx}`PJDI>d>F?q;v+)*I($@!V~3CV#UJJCaNHukUeGy*XK^1|5O^^jtjUM` z<0lUO>(&7N?ZiF33Ek$@-oO23$>q8AZw3E(sa}0$0P(4S_&*Y$BjW)&axOqGuKDUk zE|*B|?w=f0%g~;O_9~Fn@xkQ5{rhP6QQ;@)0n#^=JeVc}sUaZ!nM1wF3^~--H=I67 zjwX9EX~IX~--PmCX#}X1xoIPNilU+0Sa5QsvY~;RpDSgji#aPp>r%`bSy0DIGio7Q zDcHQB+sqkFuN2EA&LDYEwE`K_v(p+WPcI`_)Xl4?i`ud8&`Ka&^rYCo4S>t z_xm@&e_qh1M1a4UdQq9o>zAuzv*N{x@&{=DE4;s>bFSXSh5luPqvCtT(?eGm6Kwru zpYe|g_jIjyBJl4qD;Yli3xdvWt#SU&BmW4mGp^nwYVV&mL WDSDD+?$+49reOb=^X|MDMc-}mOdna<36Z>~q< zF;!83H4UCZRRZWjoU7xx5Y*8B&Cmq3RMxq1GHzBxWNsWW0RHW}E+XKnRGe=f{mBRt zvibTy+9}7bi2h`31rc=)oj!#AWQ>4_b(~!@?KQL??;CWe7kYVrtNK=y9sT3`OMzI} zdeZyh+u?1~^-Jl&FB_e4jW~W-T30_h`tiGzcW@Tv8q_bKT#NF&>S8_0mk}G-IU)Wk zx&FFvq7{@?b}lII)#1N3gZ2#&ghgCOGj|RS|4A3m;{xq1uw0V;C^&vW^0Nu~R}$~n z*!|PEJ=eJN;IF32ouh`lf_BfKOQDM{yHinr*F3WL`Bw4v%aP&c$o$UjE8&MrK*&YY z%9-ONZQ6Er!px7Q5;IjcIi62mWI7MpG7DAKvPmJEwoH4<%E5RxH&xs-ohsxF`nM0_ zy?uj2WWRCHIB>{aJ^Q%7$^G1W{&l@`pSN&#)%^_$+xb%*2R zR4jHTdX}6GcgLedjKIGM<-f`iU=(I1?8GQV+j23(zUA_^2}Wurmzc;V%U|eNiU~Ub zMmjfTWDhFH!+59YzFx>95euhV}=BUy;fng_C zcjWhq(?YcWq&1$|v%JJG5}w013zJzs zWEkT1U-el3Sfy^Q{!RpG-&nIHdzN1r?poviUE|&Y<$cpd46QLgKeyL=dJ>h+yRyyW b{;lKomTx0?;UBGWel0%s^*GUuHSGTYs2(Pr literal 0 Hc-jL100001 diff --git a/linux-user/aarch64/vdso.S b/linux-user/aarch64/vdso.S new file mode 100644 index 00000000000..34d3a9ebd2d --- /dev/null +++ b/linux-user/aarch64/vdso.S @@ -0,0 +1,71 @@ +/* + * aarch64 linux replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include + +/* ??? These are in include/elf.h, which is not ready for inclusion in asm. */ +#define NT_GNU_PROPERTY_TYPE_0 5 +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) + +#define GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT \ + (GNU_PROPERTY_AARCH64_FEATURE_1_BTI | GNU_PROPERTY_AARCH64_FEATURE_1_PAC) + + .section .note.gnu.property + .align 3 + .long 2f - 1f + .long 6f - 3f + .long NT_GNU_PROPERTY_TYPE_0 +1: .string "GNU" +2: .align 3 +3: .long GNU_PROPERTY_AARCH64_FEATURE_1_AND + .long 5f - 4f +4: .long GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT +5: .align 3 +6: + + .text + +.macro endf name + .globl \name + .type \name, @function + .size \name, . - \name +.endm + +.macro vdso_syscall name, nr +\name: + bti c + mov x8, #\nr + svc #0 + ret +endf \name +.endm + + .cfi_startproc + +vdso_syscall __kernel_gettimeofday, __NR_gettimeofday +vdso_syscall __kernel_clock_gettime, __NR_clock_gettime +vdso_syscall __kernel_clock_getres, __NR_clock_getres + + .cfi_endproc + + +/* + * TODO: The kernel makes a big deal of turning off the .cfi directives, + * because they cause libgcc to crash, but that's because they're wrong. + * + * For now, elide the unwind info for __kernel_rt_sigreturn and rely on + * the libgcc fallback routine as we have always done. This requires + * that the code sequence used be exact. + */ +__kernel_rt_sigreturn: + /* No BTI C insn here -- we arrive via RET. */ + mov x8, #__NR_rt_sigreturn + svc #0 +endf __kernel_rt_sigreturn diff --git a/linux-user/aarch64/vdso.ld b/linux-user/aarch64/vdso.ld new file mode 100644 index 00000000000..4c12f333526 --- /dev/null +++ b/linux-user/aarch64/vdso.ld @@ -0,0 +1,72 @@ +/* + * Linker script for linux aarch64 replacement vdso. + * + * Copyright 2021 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6.39 { + global: + __kernel_rt_sigreturn; + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; + + 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/elfload.c b/linux-user/elfload.c index 62a33481e19..0a3a57018b8 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -944,6 +944,12 @@ const char *elf_hwcap2_str(uint32_t bit) #undef GET_FEATURE_ID +#if TARGET_BIG_ENDIAN +# define VDSO_HEADER "vdso-be.c.inc" +#else +# define VDSO_HEADER "vdso-le.c.inc" +#endif + #endif /* not TARGET_AARCH64 */ #endif /* TARGET_ARM */ diff --git a/linux-user/meson.build b/linux-user/meson.build index e4cb70ed2df..dd243890524 100644 --- a/linux-user/meson.build +++ b/linux-user/meson.build @@ -35,6 +35,7 @@ gen_vdso_exe = executable('gen-vdso', 'gen-vdso.c', gen_vdso = generator(gen_vdso_exe, output: '@BASENAME@.c.inc', arguments: ['-o', '@OUTPUT@', '@EXTRA_ARGS@', '@INPUT@']) +subdir('aarch64') subdir('alpha') subdir('arm') subdir('hppa') -- 2.39.5