From e34136d93059ddd4a5e186b62282fccf27c3e9d0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 14 Aug 2023 17:58:55 -0700 Subject: [PATCH] linux-user/ppc: Add vdso Add support in gen-vdso-elfn.c.inc for the DT_PPC64_OPT dynamic tag: this is an integer, so does not need relocation. Signed-off-by: Richard Henderson --- linux-user/elfload.c | 8 ++ linux-user/gen-vdso-elfn.c.inc | 7 + linux-user/ppc/Makefile.vdso | 20 +++ linux-user/ppc/meson.build | 12 ++ linux-user/ppc/signal.c | 31 +++-- linux-user/ppc/vdso-32.ld | 70 ++++++++++ linux-user/ppc/vdso-32.so | Bin 0 -> 3020 bytes linux-user/ppc/vdso-64.ld | 68 +++++++++ linux-user/ppc/vdso-64.so | Bin 0 -> 3896 bytes linux-user/ppc/vdso-64le.so | Bin 0 -> 3896 bytes linux-user/ppc/vdso-asmoffset.h | 20 +++ linux-user/ppc/vdso.S | 239 ++++++++++++++++++++++++++++++++ 12 files changed, 467 insertions(+), 8 deletions(-) create mode 100644 linux-user/ppc/Makefile.vdso create mode 100644 linux-user/ppc/vdso-32.ld create mode 100755 linux-user/ppc/vdso-32.so create mode 100644 linux-user/ppc/vdso-64.ld create mode 100755 linux-user/ppc/vdso-64.so create mode 100755 linux-user/ppc/vdso-64le.so create mode 100644 linux-user/ppc/vdso-asmoffset.h create mode 100644 linux-user/ppc/vdso.S diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 4e6e0059e6..26602516aa 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1187,6 +1187,14 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 +#ifndef TARGET_PPC64 +# define VDSO_HEADER "vdso-32.c.inc" +#elif TARGET_BIG_ENDIAN +# define VDSO_HEADER "vdso-64.c.inc" +#else +# define VDSO_HEADER "vdso-64le.c.inc" +#endif + #endif #ifdef TARGET_LOONGARCH64 diff --git a/linux-user/gen-vdso-elfn.c.inc b/linux-user/gen-vdso-elfn.c.inc index 7034c36d5e..95856eb839 100644 --- a/linux-user/gen-vdso-elfn.c.inc +++ b/linux-user/gen-vdso-elfn.c.inc @@ -273,7 +273,14 @@ static void elfN(process)(FILE *outf, void *buf, bool need_bswap) errors++; break; + case PT_LOPROC + 3: + if (ehdr->e_machine == EM_PPC64) { + break; /* DT_PPC64_OPT: integer bitmask */ + } + goto do_default; + default: + do_default: /* This is probably something target specific. */ fprintf(stderr, "VDSO has unknown DYNAMIC entry (%lx)\n", (unsigned long)tag); diff --git a/linux-user/ppc/Makefile.vdso b/linux-user/ppc/Makefile.vdso new file mode 100644 index 0000000000..3ca3c6b83e --- /dev/null +++ b/linux-user/ppc/Makefile.vdso @@ -0,0 +1,20 @@ +include $(BUILD_DIR)/tests/tcg/ppc64-linux-user/config-target.mak + +SUBDIR = $(SRC_PATH)/linux-user/ppc +VPATH += $(SUBDIR) + +all: $(SUBDIR)/vdso-32.so $(SUBDIR)/vdso-64.so $(SUBDIR)/vdso-64le.so + +LDFLAGS32 = -nostdlib -shared -Wl,-T,$(SUBDIR)/vdso-32.ld \ + -Wl,-h,linux-vdso32.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1 +LDFLAGS64 = -nostdlib -shared -Wl,-T,$(SUBDIR)/vdso-64.ld \ + -Wl,-h,linux-vdso64.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1 + +$(SUBDIR)/vdso-32.so: vdso.S vdso-32.ld vdso-asmoffset.h + $(CC) -o $@ $(LDFLAGS32) -m32 $< + +$(SUBDIR)/vdso-64.so: vdso.S vdso-64.ld vdso-asmoffset.h + $(CC) -o $@ $(LDFLAGS64) -mbig-endian $< + +$(SUBDIR)/vdso-64le.so: vdso.S vdso-64.ld vdso-asmoffset.h + $(CC) -o $@ $(LDFLAGS64) -mlittle-endian $< diff --git a/linux-user/ppc/meson.build b/linux-user/ppc/meson.build index 19fead7bc8..80cacae396 100644 --- a/linux-user/ppc/meson.build +++ b/linux-user/ppc/meson.build @@ -3,3 +3,15 @@ syscall_nr_generators += { arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ], output: '@BASENAME@_nr.h') } + +vdso_32_inc = gen_vdso.process('vdso-32.so', extra_args: [ + '-s', '__kernel_sigtramp32', + '-r', '__kernel_sigtramp_rt32' + ]) +linux_user_ss.add(when: 'TARGET_PPC', if_true: vdso_32_inc) + +vdso_64_inc = gen_vdso.process('vdso-64.so', + extra_args: ['-r', '__kernel_sigtramp_rt64']) +vdso_64le_inc = gen_vdso.process('vdso-64le.so', + extra_args: ['-r', '__kernel_sigtramp_rt64']) +linux_user_ss.add(when: 'TARGET_PPC64', if_true: [vdso_64_inc, vdso_64le_inc]) diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c index a616f20efb..7e7302823b 100644 --- a/linux-user/ppc/signal.c +++ b/linux-user/ppc/signal.c @@ -21,14 +21,7 @@ #include "user-internals.h" #include "signal-common.h" #include "linux-user/trace.h" - -/* Size of dummy stack frame allocated when calling signal handler. - See arch/powerpc/include/asm/ptrace.h. */ -#if defined(TARGET_PPC64) -#define SIGNAL_FRAMESIZE 128 -#else -#define SIGNAL_FRAMESIZE 64 -#endif +#include "vdso-asmoffset.h" /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC; on 64-bit PPC, sigcontext and mcontext are one and the same. */ @@ -73,6 +66,16 @@ struct target_mcontext { #endif }; +QEMU_BUILD_BUG_ON(offsetof(struct target_mcontext, mc_fregs) + != offsetof_mcontext_fregs); +#if defined(TARGET_PPC64) +QEMU_BUILD_BUG_ON(offsetof(struct target_mcontext, v_regs) + != offsetof_mcontext_vregs_ptr); +#else +QEMU_BUILD_BUG_ON(offsetof(struct target_mcontext, mc_vregs) + != offsetof_mcontext_vregs); +#endif + /* See arch/powerpc/include/asm/sigcontext.h. */ struct target_sigcontext { target_ulong _unused[4]; @@ -161,6 +164,7 @@ struct target_ucontext { #endif }; +#if !defined(TARGET_PPC64) /* See arch/powerpc/kernel/signal_32.c. */ struct target_sigframe { struct target_sigcontext sctx; @@ -168,6 +172,10 @@ struct target_sigframe { int32_t abigap[56]; }; +QEMU_BUILD_BUG_ON(offsetof(struct target_sigframe, mctx) + != offsetof_sigframe_mcontext); +#endif + #if defined(TARGET_PPC64) #define TARGET_TRAMP_SIZE 6 @@ -184,6 +192,10 @@ struct target_rt_sigframe { char abigap[288]; } __attribute__((aligned(16))); +QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe, + uc.tuc_sigcontext.mcontext) + != offsetof_rt_sigframe_mcontext); + #else struct target_rt_sigframe { @@ -192,6 +204,9 @@ struct target_rt_sigframe { int32_t abigap[56]; }; +QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe, uc.tuc_mcontext) + != offsetof_rt_sigframe_mcontext); + #endif #if defined(TARGET_PPC64) diff --git a/linux-user/ppc/vdso-32.ld b/linux-user/ppc/vdso-32.ld new file mode 100644 index 0000000000..6962696540 --- /dev/null +++ b/linux-user/ppc/vdso-32.ld @@ -0,0 +1,70 @@ +/* + * Linker script for linux powerpc64 replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6.15 { + global: + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_gettime64; + __kernel_clock_getres; + __kernel_time; + __kernel_sync_dicache; + __kernel_sigtramp32; + __kernel_sigtramp_rt32; + __kernel_getcpu; + local: *; + }; +} + +PHDRS { + phdr PT_PHDR FLAGS(4) PHDRS; + load PT_LOAD FLAGS(7) FILEHDR PHDRS; /* FLAGS=RWX */ + dynamic PT_DYNAMIC FLAGS(4); + eh_frame_hdr PT_GNU_EH_FRAME; + note PT_NOTE FLAGS(4); +} + +SECTIONS { + . = 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 + .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.*) + } + + .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 +} diff --git a/linux-user/ppc/vdso-32.so b/linux-user/ppc/vdso-32.so new file mode 100755 index 0000000000000000000000000000000000000000..b19baafb0d38e15b4a24def5c44a6d684714be45 GIT binary patch literal 3020 zcmbuBe{54#6vw}>UCV$WJBWY|bRgnDc)~Vt3Mkz#ex#JSAM!)=t!ulrY;B?K#x~}C zBf&%ri73Q?A!ZshKnNka7-AMBfgp)UG$BYLiTr_ye~^e#kwmcO-1lzVRbn)rmy>tT zz31L{-@WI2?ltSY^_oLNMx2-oKvh%%W4*Gi5~XmV48@oTzzuL)Muz~Y1%Oo5-xl|L zNW~bt#R1@Ujt&A+W&dF6hX%lTBdeGWOV#-NzLcZ00jas|{2$Jhz835}bI#*@BRuci z!Edhi@2UCr^0u;J0QUhHvF7WjjHmzn4RE9YxB$m#>mRjV0OJ6B2Vgva;&?iJ2XGF@ z)9Jea9PxDeCg41z{`7x{4!EuXD4GNm0eBN|PXkbB+s%NB*G#ovRNo?`e+EzsxNhXM z9|7FFE~ zF2=Qy_LAW4_e$ps)qa1}a~Fou8A`-LT}DSJm5M||@%EsAwPewXY34e5}kw{gP=Q!Kd73JuP#JYPI z^aPXfigG;}*B8ON+SjtdDA$+hix$hZbKK+Mm6Oke*O&9YbDVR2a4f4;)y5cKeqgt; z$XL-zoJ#?4OgRAUDu9K6qYTi_a%{`){f#IX@MtAPGKINr8lW8pU~vH2fbG|Wf`J-# z9CT7m>mW!o$sx%33Ka~HYX`aeX-pp#_R`qxG_HrncT-V{CM4;;1WnvV#aoHuG$}^+ zM`>~wJG5hRTS0R_Gilz4Nl$!g()?2HoYbLGRWm3bS zNzdOA)OcG^)31V>ZwhL;A?Sr41+Bj>Xu~x@8?Or5bVbmMmjrG8TF^@u1igG-ka1Q} z>uEv$5kYOI1OEM}Y8!6nIBXNECOW;xr; z9WF5g*|wQfAX((J_{|t%#<9(e*q;nr^{Iqa(-TT0Bk|ZM z!w5nTg^l)vKN>Q^!9>=Ao(lEKsQuScl5-ZSdkmk|O6=UgO#AHQ+~GK7<-3xd3(}9{ zd!BtBGuL}9#Yx+bW1PohmY3Tx&*@oa$2RAI682+VW}nv%D?eq9uCUTZit?+9r_;AM zNv*tocU_g{_g m$b9FNcP{(Q%u;K`)4u@V4>^J*YF%iwU*Q)3_zX}Y{r&>p!S(F` literal 0 HcmV?d00001 diff --git a/linux-user/ppc/vdso-64.ld b/linux-user/ppc/vdso-64.ld new file mode 100644 index 0000000000..a55c65ed54 --- /dev/null +++ b/linux-user/ppc/vdso-64.ld @@ -0,0 +1,68 @@ +/* + * Linker script for linux powerpc64 replacement vdso. + * + * Copyright 2023 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +VERSION { + LINUX_2.6.15 { + global: + __kernel_gettimeofday; + __kernel_clock_gettime; + __kernel_clock_getres; + __kernel_sync_dicache; + __kernel_sigtramp_rt64; + __kernel_getcpu; + __kernel_time; + local: *; + }; +} + +PHDRS { + phdr PT_PHDR FLAGS(4) PHDRS; + load PT_LOAD FLAGS(7) FILEHDR PHDRS; /* FLAGS=RWX */ + dynamic PT_DYNAMIC FLAGS(4); + eh_frame_hdr PT_GNU_EH_FRAME; + note PT_NOTE FLAGS(4); +} + +SECTIONS { + . = 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 + .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.*) + } + + .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 +} diff --git a/linux-user/ppc/vdso-64.so b/linux-user/ppc/vdso-64.so new file mode 100755 index 0000000000000000000000000000000000000000..913c831b3819fc09912b9b31f7fbe9ee311ae12f GIT binary patch literal 3896 zcmc&%U2IfE6h8Of?GOKR5Ckn~5ky3}0+w3&(Uxw@kL^+ml^@aD?e4a_w7Xk(w{?ri zT@oKOF|mn>G3rAhF;Qbo6;S-8zL^k{KJs8)6uJ%3kjjg_*VEmW&M zs+8XxsG5`&%F175mijXavi=`dC|y~oj^?g)l>7qMWqrAYRZ{mYjf?;3Cm&JmmRVS* z{MfS3G61mlgu39`jWeeLVZKdhS?RX&8pioc?)nonzx%IV@?ze(MC zN7YxT@{g)aYXATyw>e+wA1J#(S#KQ%0W4MakS-Sglq@h#HeD>sy^KIww?5Wl!sY>ZXcd?KxGZy2`6NVz00N z_NRm5Soi5)(!=l7L|-~vyM8RV|IGRP_wP2{1jp%*Wm2&Lr!SVvC6cjpZ!|noQX>QD zNI%!jB4=XRlG+!`MFxjTWooZf%8sNWPBak-N8-Ag=*wlo$w4QRtFMEBL~1C%X*ilq z*VozEw7mt|_Jz8RI9u&{d&@SO0<-LoV8}o7#4cJ}I$v~V<+-7mF~O*EuDq@42xmRF z8fyoDxBpE5llISM0P{NlqYePPIANUZgh0N@s98u2dD=<n1jL7XS?x&C_T-kAYKI@f=p3#Htaj&f~miasDta7{Y})T$IJd8C>!Vib2FQE=}Pr zNnAF7%lq-x6SyLQE8}=uAKu=JH8ETj#nlnKqX+K{W7BbLJ%+U%xaI)f6~eXcxULQF zehk;|$9wkShP`<29^BZ9_qE{tLEO}g_HKNj2{$+5mdh?~{mR7$zjU$g3m3P2?qdCC zEWTPMsNHzwdL$YxYk4rWIqEoU-5CSEZLYLjz~6c zh@+BC7~+^@lZJRwvMECxmu%V)Pf1oV#nY0Fn!=H6%oN>{jhiAY*@P*2B%3rvM6xMU zL?xRxMNG1SC3+=K7X%*m%)w(&k`-m=XB%g^haza%W*kMpRnQ(V#WiU-Tj z_f}jgzRr2c%UcXf-VrE-alG|l0q1`|kFl;|;>>(w`EgU`DTW1{?>L`JSipI&LgiCm zFOTO0!FmVqix{QsHDG;*sn~66|O=7Y4g8HDt%b*|^km8L14% zGTB5rHKX7}!H&h9-b^?dbK=oVsRVW|md~kO^q)}!{{H84%jc4?6dHMK9@yUto9SZlhH9Ao)p=tJ!8!a1yR|y@SNCbQ{{5N3^FY|2E*6WbLiuyN zVhc;PJ_zbN&mJznXM-Qt{P;%Wr}bk$9zUU1n}6=V>|Nu(V;K7Wp^ePrQT`k!*_!Ho z2gfhA(B^weaDN2iJgzeEyU*O9-bVD!B=GoY|Ir;6|GxqK-^0KF literal 0 HcmV?d00001 diff --git a/linux-user/ppc/vdso-64le.so b/linux-user/ppc/vdso-64le.so new file mode 100755 index 0000000000000000000000000000000000000000..258a03b807c4eca23547d978c16d1ad5ebd08bc5 GIT binary patch literal 3896 zcmc&%U2IfU5T1MQmKG>*20_q*7C}Um3&m0^KT7EjKekIPRDMKnx4YZ!((Z2E-PRV7 zyCghlLShqMjNze}n4mGH3M&5B2NM%x(nlUl?28ExB$Oy<*>GrPC9ZDQhs-zGcX znKN_d+;h)4GuN$eY%mQ21QslXLJMFgcT~?83({3X5$ps7i(n1_1Uz@bZ2;ZpqZsYm0w=R?GLiT@?rTF)dBLLj`dm=^hBDagQ z8m@Dj)}Js)3j+Z2w15v;%4=KBZ401>=_LM|(Bltt;Je)B;b5HGZ_C8~C)fa>pcKyY zz9{8+9Ay1vpZ)>>Al#hrPq&WkFZ%4;SwF&hd0cw!6!(nJzMu6!uwM4rGS(0J?BTSY z3B9(tJSkdZ@gu#wTLQ(W*z|sBDC(!S=-w%>E2=4hc4|`}*}WCrcJ;uGpVppgJF4FA zOZ|4?jYwJD(Ax6;OQ-kUt$FVkaGb7aIvMSDI-}WaJP}QGL_z}vZMZuX?vlP4)ahuZ zpzVxi!#%x)HjP(kWd@RAClU{b!ZEKl-kD8@5whKuGYv|hu& zNi2F5=bXUe0W9gqxv${7KAhi+rCD5%!G&pD^fIa*#1t-0;ynpm(v3^I@ZRINERM@# zcwZ;p-+^UOToJ*QVSJz+9}Hp5F>E-B<;}QiKRy)1)lImj5g&dQ*Y3kd_Tsud_~>q2 z-++(Rp%(33xUmK|?Zk?2UEKVQi%)#*V&zvZZu!#1sxMr8@^crfuekWsXD)92 z)WvO|xVZhYi#sm4`1HpvKJ$@F&u#$x4gf<2=<}wUidVm0G-q`VR8X@)Q2R9-0@bY9 zFsSD=8v)g#*(j(3nvH=vsM$EER?TvTdS0_ZLmkp=$WVth8#dGt%|;A$RI^b-y`b5c zp^j-bZm1VE%bDsW%?3^7Xf|Z3HqC}j71C_PRPCCLnkuZ>n5iO~jhiZ}Sb<%I=iK971~ftAlIURV%-7+pF(SWuMDTV7Z&C!fE( zu%I}f$GothWX61B!Q6bF^1_07`MmCh1@j@`y;K>N=ROzcyLI|H=zKbT{FSrhm-T%A z`}50I*8B5UGwc2NrGxeUd~}la{=9RJ^)ux`%3ss+kyCdhSktt(793}Hu+^#G<21C? zG}SwM>RP7W!``GZ<;Ksa3x8giA+`LQe2@<`HI?MUOsc`o3?#ClcCa(qw3abp$y7E9 zc4QzKO2osHBr}izI}*xephbSM#ZVv%&A z1$H*tpOr21pHRkmUFxja>PmssBZ5_&^W_-MRtIw#lCLu)*U>(u+EC(4{V4J(2O@tu z8&ao89l4qH5?}5Ekzy~9w#e;V??`;9cSTmSql_BF#=gP0qtV1zuc1|b22f8-~SZ*%lC)eUm_dDk>OuIZ)`8*dv6`br|+Xhp68eS gM>VvptrvfCaec+B +#include + +#ifndef _ARCH_PPC64 +# define TARGET_ABI32 +#endif +#include "vdso-asmoffset.h" + + + .text + +.macro endf name + .globl \name + .size \name, .-\name + /* For PPC64, functions have special linkage; we export pointers. */ +#ifndef _ARCH_PPC64 + .type \name, @function +#endif +.endm + +.macro raw_syscall nr + addi 0, 0, \nr + sc +.endm + +.macro vdso_syscall name, nr +\name: + raw_syscall \nr + blr +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 +vdso_syscall __kernel_getcpu, __NR_getcpu +vdso_syscall __kernel_time, __NR_time + +#ifdef __NR_clock_gettime64 +vdso_syscall __kernel_clock_gettime64, __NR_clock_gettime64 +#endif + +__kernel_sync_dicache: + /* qemu does not need to flush caches */ + blr +endf __kernel_sync_dicache + + .cfi_endproc + +/* + * TODO: __kernel_get_tbfreq + * This is probably a constant for QEMU. + */ + +/* + * 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 + +#ifdef _ARCH_PPC64 +# define __kernel_sigtramp_rt __kernel_sigtramp_rt64 +# define sizeof_reg 8 +#else +# define __kernel_sigtramp_rt __kernel_sigtramp_rt32 +# define sizeof_reg 4 +#endif +#define sizeof_freg 8 +#define sizeof_vreg 16 + + .cfi_def_cfa 1, SIGNAL_FRAMESIZE + offsetof_rt_sigframe_mcontext + + /* Return address */ + .cfi_return_column 67 + .cfi_offset 67, 32 * sizeof_reg /* nip */ + + /* Integer registers */ + .cfi_offset 0, 0 * sizeof_reg + .cfi_offset 1, 1 * sizeof_reg + .cfi_offset 2, 2 * sizeof_reg + .cfi_offset 3, 3 * sizeof_reg + .cfi_offset 4, 4 * sizeof_reg + .cfi_offset 5, 5 * sizeof_reg + .cfi_offset 6, 6 * sizeof_reg + .cfi_offset 7, 7 * sizeof_reg + .cfi_offset 8, 8 * sizeof_reg + .cfi_offset 9, 9 * sizeof_reg + .cfi_offset 10, 10 * sizeof_reg + .cfi_offset 11, 11 * sizeof_reg + .cfi_offset 12, 12 * sizeof_reg + .cfi_offset 13, 13 * sizeof_reg + .cfi_offset 14, 14 * sizeof_reg + .cfi_offset 15, 15 * sizeof_reg + .cfi_offset 16, 16 * sizeof_reg + .cfi_offset 17, 17 * sizeof_reg + .cfi_offset 18, 18 * sizeof_reg + .cfi_offset 19, 19 * sizeof_reg + .cfi_offset 20, 20 * sizeof_reg + .cfi_offset 21, 21 * sizeof_reg + .cfi_offset 22, 22 * sizeof_reg + .cfi_offset 23, 23 * sizeof_reg + .cfi_offset 24, 24 * sizeof_reg + .cfi_offset 25, 25 * sizeof_reg + .cfi_offset 26, 26 * sizeof_reg + .cfi_offset 27, 27 * sizeof_reg + .cfi_offset 28, 28 * sizeof_reg + .cfi_offset 29, 29 * sizeof_reg + .cfi_offset 30, 30 * sizeof_reg + .cfi_offset 31, 31 * sizeof_reg + .cfi_offset 65, 36 * sizeof_reg /* lr */ + .cfi_offset 70, 38 * sizeof_reg /* ccr */ + + /* Floating point registers */ + .cfi_offset 32, offsetof_mcontext_fregs + .cfi_offset 33, offsetof_mcontext_fregs + 1 * sizeof_freg + .cfi_offset 34, offsetof_mcontext_fregs + 2 * sizeof_freg + .cfi_offset 35, offsetof_mcontext_fregs + 3 * sizeof_freg + .cfi_offset 36, offsetof_mcontext_fregs + 4 * sizeof_freg + .cfi_offset 37, offsetof_mcontext_fregs + 5 * sizeof_freg + .cfi_offset 38, offsetof_mcontext_fregs + 6 * sizeof_freg + .cfi_offset 39, offsetof_mcontext_fregs + 7 * sizeof_freg + .cfi_offset 40, offsetof_mcontext_fregs + 8 * sizeof_freg + .cfi_offset 41, offsetof_mcontext_fregs + 9 * sizeof_freg + .cfi_offset 42, offsetof_mcontext_fregs + 10 * sizeof_freg + .cfi_offset 43, offsetof_mcontext_fregs + 11 * sizeof_freg + .cfi_offset 44, offsetof_mcontext_fregs + 12 * sizeof_freg + .cfi_offset 45, offsetof_mcontext_fregs + 13 * sizeof_freg + .cfi_offset 46, offsetof_mcontext_fregs + 14 * sizeof_freg + .cfi_offset 47, offsetof_mcontext_fregs + 15 * sizeof_freg + .cfi_offset 48, offsetof_mcontext_fregs + 16 * sizeof_freg + .cfi_offset 49, offsetof_mcontext_fregs + 17 * sizeof_freg + .cfi_offset 50, offsetof_mcontext_fregs + 18 * sizeof_freg + .cfi_offset 51, offsetof_mcontext_fregs + 19 * sizeof_freg + .cfi_offset 52, offsetof_mcontext_fregs + 20 * sizeof_freg + .cfi_offset 53, offsetof_mcontext_fregs + 21 * sizeof_freg + .cfi_offset 54, offsetof_mcontext_fregs + 22 * sizeof_freg + .cfi_offset 55, offsetof_mcontext_fregs + 23 * sizeof_freg + .cfi_offset 56, offsetof_mcontext_fregs + 24 * sizeof_freg + .cfi_offset 57, offsetof_mcontext_fregs + 25 * sizeof_freg + .cfi_offset 58, offsetof_mcontext_fregs + 26 * sizeof_freg + .cfi_offset 59, offsetof_mcontext_fregs + 27 * sizeof_freg + .cfi_offset 60, offsetof_mcontext_fregs + 28 * sizeof_freg + .cfi_offset 61, offsetof_mcontext_fregs + 29 * sizeof_freg + .cfi_offset 62, offsetof_mcontext_fregs + 30 * sizeof_freg + .cfi_offset 63, offsetof_mcontext_fregs + 31 * sizeof_freg + + /* + * Unlike the kernel, unconditionally represent the Altivec/VSX regs. + * The space within the stack frame is always available, and most of + * our supported processors have them enabled. The only complication + * for PPC64 is the misalignment, so that we have to use indirection. + */ +.macro save_vreg_ofs reg, ofs +#ifdef _ARCH_PPC64 + /* + * vreg = *(cfa + offsetof(v_regs)) + ofs + * + * The CFA is input to the expression on the stack, so: + * DW_CFA_expression reg, length (7), + * DW_OP_plus_uconst (0x23), vreg_ptr, DW_OP_deref (0x06), + * DW_OP_plus_uconst (0x23), ofs + */ + .cfi_escape 0x10, 77 + \reg, 7, 0x23, (offsetof_mcontext_vregs_ptr & 0x7f) + 0x80, offsetof_mcontext_vregs_ptr >> 7, 0x06, 0x23, (\ofs & 0x7f) | 0x80, \ofs >> 7 +#else + .cfi_offset 77 + \reg, offsetof_mcontext_vregs + \ofs +#endif +.endm + +.macro save_vreg reg + save_vreg_ofs \reg, (\reg * sizeof_vreg) +.endm + + save_vreg 0 + save_vreg 1 + save_vreg 2 + save_vreg 3 + save_vreg 4 + save_vreg 5 + save_vreg 6 + save_vreg 7 + save_vreg 8 + save_vreg 9 + save_vreg 10 + save_vreg 11 + save_vreg 12 + save_vreg 13 + save_vreg 14 + save_vreg 15 + save_vreg 16 + save_vreg 17 + save_vreg 18 + save_vreg 19 + save_vreg 20 + save_vreg 21 + save_vreg 22 + save_vreg 23 + save_vreg 24 + save_vreg 25 + save_vreg 26 + save_vreg 27 + save_vreg 28 + save_vreg 29 + save_vreg 30 + save_vreg 31 + save_vreg 32 + save_vreg_ofs 33, (32 * sizeof_vreg + 12) + + nop + +__kernel_sigtramp_rt: + raw_syscall __NR_rt_sigreturn +endf __kernel_sigtramp_rt + +#ifndef _ARCH_PPC64 + /* + * The non-rt sigreturn has the same layout at a different offset. + * Move the CFA and leave all othe other descriptions the same. + */ + .cfi_def_cfa 1, SIGNAL_FRAMESIZE + offsetof_sigframe_mcontext + nop +__kernel_sigtramp32: + raw_syscall __NR_sigreturn +endf __kernel_sigtramp32 +#endif + + .cfi_endproc -- 2.50.1