]> git.baikalelectronics.ru Git - kernel.git/commitdiff
powerpc/vdso: Rework VDSO32 makefile to add a prefix to object files
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Fri, 21 Jan 2022 16:30:23 +0000 (16:30 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Sat, 12 Feb 2022 11:47:43 +0000 (22:47 +1100)
In order to merge vdso32 and vdso64 build in following patch, rework
Makefile is order to add -32 suffix to VDSO32 object files.

Also change sigtramp.S to sigtramp32.S as VDSO64 sigtramp.S is too
different to be squashed into VDSO32 sigtramp.S at the first place.

gen_vdso_offsets.sh also becomes gen_vdso32_offsets.sh

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/0c421b704a57b228e75a891512568339c53667ad.1642782130.git.christophe.leroy@csgroup.eu
arch/powerpc/kernel/vdso32/Makefile
arch/powerpc/kernel/vdso32/gen_vdso32_offsets.sh [new file with mode: 0755]
arch/powerpc/kernel/vdso32/gen_vdso_offsets.sh [deleted file]
arch/powerpc/kernel/vdso32/sigtramp.S [deleted file]
arch/powerpc/kernel/vdso32/sigtramp32.S [new file with mode: 0644]

index 7d9a6fee0e3dc1a01e066314721f09e732af8ae6..7d7b38d90ca5125746ee0c0c5f925c08a070c378 100644 (file)
@@ -5,15 +5,16 @@
 ARCH_REL_TYPE_ABS := R_PPC_JUMP_SLOT|R_PPC_GLOB_DAT|R_PPC_ADDR32|R_PPC_ADDR24|R_PPC_ADDR16|R_PPC_ADDR16_LO|R_PPC_ADDR16_HI|R_PPC_ADDR16_HA|R_PPC_ADDR14|R_PPC_ADDR14_BRTAKEN|R_PPC_ADDR14_BRNTAKEN|R_PPC_REL24
 include $(srctree)/lib/vdso/Makefile
 
-obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o
+obj-vdso32 = sigtramp32-32.o gettimeofday-32.o datapage-32.o cacheflush-32.o note-32.o getcpu-32.o
 
 ifneq ($(c-gettimeofday-y),)
-  CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y)
-  CFLAGS_vgettimeofday.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
-  CFLAGS_vgettimeofday.o += $(call cc-option, -fno-stack-protector)
-  CFLAGS_vgettimeofday.o += -DDISABLE_BRANCH_PROFILING
-  CFLAGS_vgettimeofday.o += -ffreestanding -fasynchronous-unwind-tables
-  CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+  CFLAGS_vgettimeofday-32.o += -include $(c-gettimeofday-y)
+  CFLAGS_vgettimeofday-32.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+  CFLAGS_vgettimeofday-32.o += $(call cc-option, -fno-stack-protector)
+  CFLAGS_vgettimeofday-32.o += -DDISABLE_BRANCH_PROFILING
+  CFLAGS_vgettimeofday-32.o += -ffreestanding -fasynchronous-unwind-tables
+  CFLAGS_REMOVE_vgettimeofday-32.o = $(CC_FLAGS_FTRACE)
+  CFLAGS_REMOVE_vgettimeofday-32.o += -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc
 endif
 
 # Build rules
@@ -24,13 +25,7 @@ else
     VDSOCC := $(CC)
 endif
 
-CC32FLAGS :=
-ifdef CONFIG_PPC64
-CC32FLAGS += -m32
-KBUILD_CFLAGS := $(filter-out -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc,$(KBUILD_CFLAGS))
-endif
-
-targets := $(obj-vdso32) vdso32.so.dbg vgettimeofday.o
+targets := $(obj-vdso32) vdso32.so.dbg vgettimeofday-32.o
 obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
 
 GCOV_PROFILE := n
@@ -38,36 +33,36 @@ KCOV_INSTRUMENT := n
 UBSAN_SANITIZE := n
 KASAN_SANITIZE := n
 
-ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
-       -Wl,-soname=linux-vdso32.so.1 -Wl,--hash-style=both
-asflags-y := -D__VDSO32__ -s
+ccflags-y := -shared -fno-common -fno-builtin -nostdlib -Wl,--hash-style=both
+
+CC32FLAGS := -Wl,-soname=linux-vdso32.so.1 -m32
+AS32FLAGS := -D__VDSO32__ -s
 
-obj-y += vdso32_wrapper.o
 targets += vdso32.lds
 CPPFLAGS_vdso32.lds += -P -C -Upowerpc
 
 # link rule for the .so file, .lds has to be first
-$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday.o FORCE
+$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday-32.o FORCE
        $(call if_changed,vdso32ld_and_check)
 
 # assembly rules for the .S files
-$(obj-vdso32): %.o: %.S FORCE
+$(obj-vdso32): %-32.o: %.S FORCE
        $(call if_changed_dep,vdso32as)
-$(obj)/vgettimeofday.o: %.o: %.c FORCE
+$(obj)/vgettimeofday-32.o: %-32.o: %.c FORCE
        $(call if_changed_dep,vdso32cc)
 
 # Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
-quiet_cmd_vdsosym = VDSOSYM $@
-      cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
+gen-vdso32sym := $(srctree)/$(src)/gen_vdso32_offsets.sh
+quiet_cmd_vdso32sym = VDSO32SYM $@
+      cmd_vdso32sym = $(NM) $< | $(gen-vdso32sym) | LC_ALL=C sort > $@
 
 include/generated/vdso32-offsets.h: $(obj)/vdso32.so.dbg FORCE
-       $(call if_changed,vdsosym)
+       $(call if_changed,vdso32sym)
 
 # actual build commands
 quiet_cmd_vdso32ld_and_check = VDSO32L $@
       cmd_vdso32ld_and_check = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) ; $(cmd_vdso_check)
 quiet_cmd_vdso32as = VDSO32A $@
-      cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) -c -o $@ $<
+      cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) $(AS32FLAGS) -c -o $@ $<
 quiet_cmd_vdso32cc = VDSO32C $@
       cmd_vdso32cc = $(VDSOCC) $(c_flags) $(CC32FLAGS) -c -o $@ $<
diff --git a/arch/powerpc/kernel/vdso32/gen_vdso32_offsets.sh b/arch/powerpc/kernel/vdso32/gen_vdso32_offsets.sh
new file mode 100755 (executable)
index 0000000..c7b54a5
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+#
+# Match symbols in the DSO that look like VDSO_*; produce a header file
+# of constant offsets into the shared object.
+#
+# Doing this inside the Makefile will break the $(filter-out) function,
+# causing Kbuild to rebuild the vdso-offsets header file every time.
+#
+# Author: Will Deacon <will.deacon@arm.com
+#
+
+LC_ALL=C
+sed -n -e 's/^00*/0/' -e \
+'s/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso32_offset_\2\t0x\1/p'
diff --git a/arch/powerpc/kernel/vdso32/gen_vdso_offsets.sh b/arch/powerpc/kernel/vdso32/gen_vdso_offsets.sh
deleted file mode 100755 (executable)
index c7b54a5..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-#
-# Match symbols in the DSO that look like VDSO_*; produce a header file
-# of constant offsets into the shared object.
-#
-# Doing this inside the Makefile will break the $(filter-out) function,
-# causing Kbuild to rebuild the vdso-offsets header file every time.
-#
-# Author: Will Deacon <will.deacon@arm.com
-#
-
-LC_ALL=C
-sed -n -e 's/^00*/0/' -e \
-'s/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso32_offset_\2\t0x\1/p'
diff --git a/arch/powerpc/kernel/vdso32/sigtramp.S b/arch/powerpc/kernel/vdso32/sigtramp.S
deleted file mode 100644 (file)
index 0bcc5e5..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Signal trampolines for 32 bits processes in a ppc64 kernel for
- * use in the vDSO
- *
- * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org), IBM Corp.
- * Copyright (C) 2004 Alan Modra (amodra@au.ibm.com)), IBM Corp.
- */
-#include <asm/processor.h>
-#include <asm/ppc_asm.h>
-#include <asm/unistd.h>
-#include <asm/vdso.h>
-
-       .text
-
-/* The nop here is a hack.  The dwarf2 unwind routines subtract 1 from
-   the return address to get an address in the middle of the presumed
-   call instruction.  Since we don't have a call here, we artificially
-   extend the range covered by the unwind info by adding a nop before
-   the real start.  */
-       nop
-V_FUNCTION_BEGIN(__kernel_sigtramp32)
-.Lsig_start = . - 4
-       li      r0,__NR_sigreturn
-       sc
-.Lsig_end:
-V_FUNCTION_END(__kernel_sigtramp32)
-
-.Lsigrt_start:
-       nop
-V_FUNCTION_BEGIN(__kernel_sigtramp_rt32)
-       li      r0,__NR_rt_sigreturn
-       sc
-.Lsigrt_end:
-V_FUNCTION_END(__kernel_sigtramp_rt32)
-
-       .section .eh_frame,"a",@progbits
-
-/* Register r1 can be found at offset 4 of a pt_regs structure.
-   A pointer to the pt_regs is stored in memory at the old sp plus PTREGS.  */
-#define cfa_save \
-  .byte 0x0f;                  /* DW_CFA_def_cfa_expression */         \
-  .uleb128 9f - 1f;            /*   length */                          \
-1:                                                                     \
-  .byte 0x71; .sleb128 PTREGS; /*     DW_OP_breg1 */                   \
-  .byte 0x06;                  /*     DW_OP_deref */                   \
-  .byte 0x23; .uleb128 RSIZE;  /*     DW_OP_plus_uconst */             \
-  .byte 0x06;                  /*     DW_OP_deref */                   \
-9:
-
-/* Register REGNO can be found at offset OFS of a pt_regs structure.
-   A pointer to the pt_regs is stored in memory at the old sp plus PTREGS.  */
-#define rsave(regno, ofs) \
-  .byte 0x10;                  /* DW_CFA_expression */                 \
-  .uleb128 regno;              /*   regno */                           \
-  .uleb128 9f - 1f;            /*   length */                          \
-1:                                                                     \
-  .byte 0x71; .sleb128 PTREGS; /*     DW_OP_breg1 */                   \
-  .byte 0x06;                  /*     DW_OP_deref */                   \
-  .ifne ofs;                                                           \
-    .byte 0x23; .uleb128 ofs;  /*     DW_OP_plus_uconst */             \
-  .endif;                                                              \
-9:
-
-/* If msr bit 1<<25 is set, then VMX register REGNO is at offset REGNO*16
-   of the VMX reg struct.  The VMX reg struct is at offset VREGS of
-   the pt_regs struct.  This macro is for REGNO == 0, and contains
-   'subroutines' that the other macros jump to.  */
-#define vsave_msr0(regno) \
-  .byte 0x10;                  /* DW_CFA_expression */                 \
-  .uleb128 regno + 77;         /*   regno */                           \
-  .uleb128 9f - 1f;            /*   length */                          \
-1:                                                                     \
-  .byte 0x30 + regno;          /*     DW_OP_lit0 */                    \
-2:                                                                     \
-  .byte 0x40;                  /*     DW_OP_lit16 */                   \
-  .byte 0x1e;                  /*     DW_OP_mul */                     \
-3:                                                                     \
-  .byte 0x71; .sleb128 PTREGS; /*     DW_OP_breg1 */                   \
-  .byte 0x06;                  /*     DW_OP_deref */                   \
-  .byte 0x12;                  /*     DW_OP_dup */                     \
-  .byte 0x23;                  /*     DW_OP_plus_uconst */             \
-    .uleb128 33*RSIZE;         /*       msr offset */                  \
-  .byte 0x06;                  /*     DW_OP_deref */                   \
-  .byte 0x0c; .long 1 << 25;   /*     DW_OP_const4u */                 \
-  .byte 0x1a;                  /*     DW_OP_and */                     \
-  .byte 0x12;                  /*     DW_OP_dup, ret 0 if bra taken */ \
-  .byte 0x30;                  /*     DW_OP_lit0 */                    \
-  .byte 0x29;                  /*     DW_OP_eq */                      \
-  .byte 0x28; .short 0x7fff;   /*     DW_OP_bra to end */              \
-  .byte 0x13;                  /*     DW_OP_drop, pop the 0 */         \
-  .byte 0x23; .uleb128 VREGS;  /*     DW_OP_plus_uconst */             \
-  .byte 0x22;                  /*     DW_OP_plus */                    \
-  .byte 0x2f; .short 0x7fff;   /*     DW_OP_skip to end */             \
-9:
-
-/* If msr bit 1<<25 is set, then VMX register REGNO is at offset REGNO*16
-   of the VMX reg struct.  REGNO is 1 thru 31.  */
-#define vsave_msr1(regno) \
-  .byte 0x10;                  /* DW_CFA_expression */                 \
-  .uleb128 regno + 77;         /*   regno */                           \
-  .uleb128 9f - 1f;            /*   length */                          \
-1:                                                                     \
-  .byte 0x30 + regno;          /*     DW_OP_lit n */                   \
-  .byte 0x2f; .short 2b - 9f;  /*     DW_OP_skip */                    \
-9:
-
-/* If msr bit 1<<25 is set, then VMX register REGNO is at offset OFS of
-   the VMX save block.  */
-#define vsave_msr2(regno, ofs) \
-  .byte 0x10;                  /* DW_CFA_expression */                 \
-  .uleb128 regno + 77;         /*   regno */                           \
-  .uleb128 9f - 1f;            /*   length */                          \
-1:                                                                     \
-  .byte 0x0a; .short ofs;      /*     DW_OP_const2u */                 \
-  .byte 0x2f; .short 3b - 9f;  /*     DW_OP_skip */                    \
-9:
-
-/* VMX register REGNO is at offset OFS of the VMX save area.  */
-#define vsave(regno, ofs) \
-  .byte 0x10;                  /* DW_CFA_expression */                 \
-  .uleb128 regno + 77;         /*   regno */                           \
-  .uleb128 9f - 1f;            /*   length */                          \
-1:                                                                     \
-  .byte 0x71; .sleb128 PTREGS; /*     DW_OP_breg1 */                   \
-  .byte 0x06;                  /*     DW_OP_deref */                   \
-  .byte 0x23; .uleb128 VREGS;  /*     DW_OP_plus_uconst */             \
-  .byte 0x23; .uleb128 ofs;    /*     DW_OP_plus_uconst */             \
-9:
-
-/* This is where the pt_regs pointer can be found on the stack.  */
-#define PTREGS 64+28
-
-/* Size of regs.  */
-#define RSIZE 4
-
-/* This is the offset of the VMX regs.  */
-#define VREGS 48*RSIZE+34*8
-
-/* Describe where general purpose regs are saved.  */
-#define EH_FRAME_GEN \
-  cfa_save;                                                            \
-  rsave ( 0,  0*RSIZE);                                                        \
-  rsave ( 2,  2*RSIZE);                                                        \
-  rsave ( 3,  3*RSIZE);                                                        \
-  rsave ( 4,  4*RSIZE);                                                        \
-  rsave ( 5,  5*RSIZE);                                                        \
-  rsave ( 6,  6*RSIZE);                                                        \
-  rsave ( 7,  7*RSIZE);                                                        \
-  rsave ( 8,  8*RSIZE);                                                        \
-  rsave ( 9,  9*RSIZE);                                                        \
-  rsave (10, 10*RSIZE);                                                        \
-  rsave (11, 11*RSIZE);                                                        \
-  rsave (12, 12*RSIZE);                                                        \
-  rsave (13, 13*RSIZE);                                                        \
-  rsave (14, 14*RSIZE);                                                        \
-  rsave (15, 15*RSIZE);                                                        \
-  rsave (16, 16*RSIZE);                                                        \
-  rsave (17, 17*RSIZE);                                                        \
-  rsave (18, 18*RSIZE);                                                        \
-  rsave (19, 19*RSIZE);                                                        \
-  rsave (20, 20*RSIZE);                                                        \
-  rsave (21, 21*RSIZE);                                                        \
-  rsave (22, 22*RSIZE);                                                        \
-  rsave (23, 23*RSIZE);                                                        \
-  rsave (24, 24*RSIZE);                                                        \
-  rsave (25, 25*RSIZE);                                                        \
-  rsave (26, 26*RSIZE);                                                        \
-  rsave (27, 27*RSIZE);                                                        \
-  rsave (28, 28*RSIZE);                                                        \
-  rsave (29, 29*RSIZE);                                                        \
-  rsave (30, 30*RSIZE);                                                        \
-  rsave (31, 31*RSIZE);                                                        \
-  rsave (67, 32*RSIZE);                /* ap, used as temp for nip */          \
-  rsave (65, 36*RSIZE);                /* lr */                                \
-  rsave (70, 38*RSIZE)         /* cr */
-
-/* Describe where the FP regs are saved.  */
-#define EH_FRAME_FP \
-  rsave (32, 48*RSIZE +  0*8);                                         \
-  rsave (33, 48*RSIZE +  1*8);                                         \
-  rsave (34, 48*RSIZE +  2*8);                                         \
-  rsave (35, 48*RSIZE +  3*8);                                         \
-  rsave (36, 48*RSIZE +  4*8);                                         \
-  rsave (37, 48*RSIZE +  5*8);                                         \
-  rsave (38, 48*RSIZE +  6*8);                                         \
-  rsave (39, 48*RSIZE +  7*8);                                         \
-  rsave (40, 48*RSIZE +  8*8);                                         \
-  rsave (41, 48*RSIZE +  9*8);                                         \
-  rsave (42, 48*RSIZE + 10*8);                                         \
-  rsave (43, 48*RSIZE + 11*8);                                         \
-  rsave (44, 48*RSIZE + 12*8);                                         \
-  rsave (45, 48*RSIZE + 13*8);                                         \
-  rsave (46, 48*RSIZE + 14*8);                                         \
-  rsave (47, 48*RSIZE + 15*8);                                         \
-  rsave (48, 48*RSIZE + 16*8);                                         \
-  rsave (49, 48*RSIZE + 17*8);                                         \
-  rsave (50, 48*RSIZE + 18*8);                                         \
-  rsave (51, 48*RSIZE + 19*8);                                         \
-  rsave (52, 48*RSIZE + 20*8);                                         \
-  rsave (53, 48*RSIZE + 21*8);                                         \
-  rsave (54, 48*RSIZE + 22*8);                                         \
-  rsave (55, 48*RSIZE + 23*8);                                         \
-  rsave (56, 48*RSIZE + 24*8);                                         \
-  rsave (57, 48*RSIZE + 25*8);                                         \
-  rsave (58, 48*RSIZE + 26*8);                                         \
-  rsave (59, 48*RSIZE + 27*8);                                         \
-  rsave (60, 48*RSIZE + 28*8);                                         \
-  rsave (61, 48*RSIZE + 29*8);                                         \
-  rsave (62, 48*RSIZE + 30*8);                                         \
-  rsave (63, 48*RSIZE + 31*8)
-
-/* Describe where the VMX regs are saved.  */
-#ifdef CONFIG_ALTIVEC
-#define EH_FRAME_VMX \
-  vsave_msr0 ( 0);                                                     \
-  vsave_msr1 ( 1);                                                     \
-  vsave_msr1 ( 2);                                                     \
-  vsave_msr1 ( 3);                                                     \
-  vsave_msr1 ( 4);                                                     \
-  vsave_msr1 ( 5);                                                     \
-  vsave_msr1 ( 6);                                                     \
-  vsave_msr1 ( 7);                                                     \
-  vsave_msr1 ( 8);                                                     \
-  vsave_msr1 ( 9);                                                     \
-  vsave_msr1 (10);                                                     \
-  vsave_msr1 (11);                                                     \
-  vsave_msr1 (12);                                                     \
-  vsave_msr1 (13);                                                     \
-  vsave_msr1 (14);                                                     \
-  vsave_msr1 (15);                                                     \
-  vsave_msr1 (16);                                                     \
-  vsave_msr1 (17);                                                     \
-  vsave_msr1 (18);                                                     \
-  vsave_msr1 (19);                                                     \
-  vsave_msr1 (20);                                                     \
-  vsave_msr1 (21);                                                     \
-  vsave_msr1 (22);                                                     \
-  vsave_msr1 (23);                                                     \
-  vsave_msr1 (24);                                                     \
-  vsave_msr1 (25);                                                     \
-  vsave_msr1 (26);                                                     \
-  vsave_msr1 (27);                                                     \
-  vsave_msr1 (28);                                                     \
-  vsave_msr1 (29);                                                     \
-  vsave_msr1 (30);                                                     \
-  vsave_msr1 (31);                                                     \
-  vsave_msr2 (33, 32*16+12);                                           \
-  vsave      (32, 32*16)
-#else
-#define EH_FRAME_VMX
-#endif
-
-.Lcie:
-       .long .Lcie_end - .Lcie_start
-.Lcie_start:
-       .long 0                 /* CIE ID */
-       .byte 1                 /* Version number */
-       .string "zRS"           /* NUL-terminated augmentation string */
-       .uleb128 4              /* Code alignment factor */
-       .sleb128 -4             /* Data alignment factor */
-       .byte 67                /* Return address register column, ap */
-       .uleb128 1              /* Augmentation value length */
-       .byte 0x1b              /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */
-       .byte 0x0c,1,0          /* DW_CFA_def_cfa: r1 ofs 0 */
-       .balign 4
-.Lcie_end:
-
-       .long .Lfde0_end - .Lfde0_start
-.Lfde0_start:
-       .long .Lfde0_start - .Lcie      /* CIE pointer. */
-       .long .Lsig_start - .           /* PC start, length */
-       .long .Lsig_end - .Lsig_start
-       .uleb128 0                      /* Augmentation */
-       EH_FRAME_GEN
-       EH_FRAME_FP
-       EH_FRAME_VMX
-       .balign 4
-.Lfde0_end:
-
-/* We have a different stack layout for rt_sigreturn.  */
-#undef PTREGS
-#define PTREGS 64+16+128+20+28
-
-       .long .Lfde1_end - .Lfde1_start
-.Lfde1_start:
-       .long .Lfde1_start - .Lcie      /* CIE pointer. */
-       .long .Lsigrt_start - .         /* PC start, length */
-       .long .Lsigrt_end - .Lsigrt_start
-       .uleb128 0                      /* Augmentation */
-       EH_FRAME_GEN
-       EH_FRAME_FP
-       EH_FRAME_VMX
-       .balign 4
-.Lfde1_end:
diff --git a/arch/powerpc/kernel/vdso32/sigtramp32.S b/arch/powerpc/kernel/vdso32/sigtramp32.S
new file mode 100644 (file)
index 0000000..0bcc5e5
--- /dev/null
@@ -0,0 +1,295 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Signal trampolines for 32 bits processes in a ppc64 kernel for
+ * use in the vDSO
+ *
+ * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org), IBM Corp.
+ * Copyright (C) 2004 Alan Modra (amodra@au.ibm.com)), IBM Corp.
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/unistd.h>
+#include <asm/vdso.h>
+
+       .text
+
+/* The nop here is a hack.  The dwarf2 unwind routines subtract 1 from
+   the return address to get an address in the middle of the presumed
+   call instruction.  Since we don't have a call here, we artificially
+   extend the range covered by the unwind info by adding a nop before
+   the real start.  */
+       nop
+V_FUNCTION_BEGIN(__kernel_sigtramp32)
+.Lsig_start = . - 4
+       li      r0,__NR_sigreturn
+       sc
+.Lsig_end:
+V_FUNCTION_END(__kernel_sigtramp32)
+
+.Lsigrt_start:
+       nop
+V_FUNCTION_BEGIN(__kernel_sigtramp_rt32)
+       li      r0,__NR_rt_sigreturn
+       sc
+.Lsigrt_end:
+V_FUNCTION_END(__kernel_sigtramp_rt32)
+
+       .section .eh_frame,"a",@progbits
+
+/* Register r1 can be found at offset 4 of a pt_regs structure.
+   A pointer to the pt_regs is stored in memory at the old sp plus PTREGS.  */
+#define cfa_save \
+  .byte 0x0f;                  /* DW_CFA_def_cfa_expression */         \
+  .uleb128 9f - 1f;            /*   length */                          \
+1:                                                                     \
+  .byte 0x71; .sleb128 PTREGS; /*     DW_OP_breg1 */                   \
+  .byte 0x06;                  /*     DW_OP_deref */                   \
+  .byte 0x23; .uleb128 RSIZE;  /*     DW_OP_plus_uconst */             \
+  .byte 0x06;                  /*     DW_OP_deref */                   \
+9:
+
+/* Register REGNO can be found at offset OFS of a pt_regs structure.
+   A pointer to the pt_regs is stored in memory at the old sp plus PTREGS.  */
+#define rsave(regno, ofs) \
+  .byte 0x10;                  /* DW_CFA_expression */                 \
+  .uleb128 regno;              /*   regno */                           \
+  .uleb128 9f - 1f;            /*   length */                          \
+1:                                                                     \
+  .byte 0x71; .sleb128 PTREGS; /*     DW_OP_breg1 */                   \
+  .byte 0x06;                  /*     DW_OP_deref */                   \
+  .ifne ofs;                                                           \
+    .byte 0x23; .uleb128 ofs;  /*     DW_OP_plus_uconst */             \
+  .endif;                                                              \
+9:
+
+/* If msr bit 1<<25 is set, then VMX register REGNO is at offset REGNO*16
+   of the VMX reg struct.  The VMX reg struct is at offset VREGS of
+   the pt_regs struct.  This macro is for REGNO == 0, and contains
+   'subroutines' that the other macros jump to.  */
+#define vsave_msr0(regno) \
+  .byte 0x10;                  /* DW_CFA_expression */                 \
+  .uleb128 regno + 77;         /*   regno */                           \
+  .uleb128 9f - 1f;            /*   length */                          \
+1:                                                                     \
+  .byte 0x30 + regno;          /*     DW_OP_lit0 */                    \
+2:                                                                     \
+  .byte 0x40;                  /*     DW_OP_lit16 */                   \
+  .byte 0x1e;                  /*     DW_OP_mul */                     \
+3:                                                                     \
+  .byte 0x71; .sleb128 PTREGS; /*     DW_OP_breg1 */                   \
+  .byte 0x06;                  /*     DW_OP_deref */                   \
+  .byte 0x12;                  /*     DW_OP_dup */                     \
+  .byte 0x23;                  /*     DW_OP_plus_uconst */             \
+    .uleb128 33*RSIZE;         /*       msr offset */                  \
+  .byte 0x06;                  /*     DW_OP_deref */                   \
+  .byte 0x0c; .long 1 << 25;   /*     DW_OP_const4u */                 \
+  .byte 0x1a;                  /*     DW_OP_and */                     \
+  .byte 0x12;                  /*     DW_OP_dup, ret 0 if bra taken */ \
+  .byte 0x30;                  /*     DW_OP_lit0 */                    \
+  .byte 0x29;                  /*     DW_OP_eq */                      \
+  .byte 0x28; .short 0x7fff;   /*     DW_OP_bra to end */              \
+  .byte 0x13;                  /*     DW_OP_drop, pop the 0 */         \
+  .byte 0x23; .uleb128 VREGS;  /*     DW_OP_plus_uconst */             \
+  .byte 0x22;                  /*     DW_OP_plus */                    \
+  .byte 0x2f; .short 0x7fff;   /*     DW_OP_skip to end */             \
+9:
+
+/* If msr bit 1<<25 is set, then VMX register REGNO is at offset REGNO*16
+   of the VMX reg struct.  REGNO is 1 thru 31.  */
+#define vsave_msr1(regno) \
+  .byte 0x10;                  /* DW_CFA_expression */                 \
+  .uleb128 regno + 77;         /*   regno */                           \
+  .uleb128 9f - 1f;            /*   length */                          \
+1:                                                                     \
+  .byte 0x30 + regno;          /*     DW_OP_lit n */                   \
+  .byte 0x2f; .short 2b - 9f;  /*     DW_OP_skip */                    \
+9:
+
+/* If msr bit 1<<25 is set, then VMX register REGNO is at offset OFS of
+   the VMX save block.  */
+#define vsave_msr2(regno, ofs) \
+  .byte 0x10;                  /* DW_CFA_expression */                 \
+  .uleb128 regno + 77;         /*   regno */                           \
+  .uleb128 9f - 1f;            /*   length */                          \
+1:                                                                     \
+  .byte 0x0a; .short ofs;      /*     DW_OP_const2u */                 \
+  .byte 0x2f; .short 3b - 9f;  /*     DW_OP_skip */                    \
+9:
+
+/* VMX register REGNO is at offset OFS of the VMX save area.  */
+#define vsave(regno, ofs) \
+  .byte 0x10;                  /* DW_CFA_expression */                 \
+  .uleb128 regno + 77;         /*   regno */                           \
+  .uleb128 9f - 1f;            /*   length */                          \
+1:                                                                     \
+  .byte 0x71; .sleb128 PTREGS; /*     DW_OP_breg1 */                   \
+  .byte 0x06;                  /*     DW_OP_deref */                   \
+  .byte 0x23; .uleb128 VREGS;  /*     DW_OP_plus_uconst */             \
+  .byte 0x23; .uleb128 ofs;    /*     DW_OP_plus_uconst */             \
+9:
+
+/* This is where the pt_regs pointer can be found on the stack.  */
+#define PTREGS 64+28
+
+/* Size of regs.  */
+#define RSIZE 4
+
+/* This is the offset of the VMX regs.  */
+#define VREGS 48*RSIZE+34*8
+
+/* Describe where general purpose regs are saved.  */
+#define EH_FRAME_GEN \
+  cfa_save;                                                            \
+  rsave ( 0,  0*RSIZE);                                                        \
+  rsave ( 2,  2*RSIZE);                                                        \
+  rsave ( 3,  3*RSIZE);                                                        \
+  rsave ( 4,  4*RSIZE);                                                        \
+  rsave ( 5,  5*RSIZE);                                                        \
+  rsave ( 6,  6*RSIZE);                                                        \
+  rsave ( 7,  7*RSIZE);                                                        \
+  rsave ( 8,  8*RSIZE);                                                        \
+  rsave ( 9,  9*RSIZE);                                                        \
+  rsave (10, 10*RSIZE);                                                        \
+  rsave (11, 11*RSIZE);                                                        \
+  rsave (12, 12*RSIZE);                                                        \
+  rsave (13, 13*RSIZE);                                                        \
+  rsave (14, 14*RSIZE);                                                        \
+  rsave (15, 15*RSIZE);                                                        \
+  rsave (16, 16*RSIZE);                                                        \
+  rsave (17, 17*RSIZE);                                                        \
+  rsave (18, 18*RSIZE);                                                        \
+  rsave (19, 19*RSIZE);                                                        \
+  rsave (20, 20*RSIZE);                                                        \
+  rsave (21, 21*RSIZE);                                                        \
+  rsave (22, 22*RSIZE);                                                        \
+  rsave (23, 23*RSIZE);                                                        \
+  rsave (24, 24*RSIZE);                                                        \
+  rsave (25, 25*RSIZE);                                                        \
+  rsave (26, 26*RSIZE);                                                        \
+  rsave (27, 27*RSIZE);                                                        \
+  rsave (28, 28*RSIZE);                                                        \
+  rsave (29, 29*RSIZE);                                                        \
+  rsave (30, 30*RSIZE);                                                        \
+  rsave (31, 31*RSIZE);                                                        \
+  rsave (67, 32*RSIZE);                /* ap, used as temp for nip */          \
+  rsave (65, 36*RSIZE);                /* lr */                                \
+  rsave (70, 38*RSIZE)         /* cr */
+
+/* Describe where the FP regs are saved.  */
+#define EH_FRAME_FP \
+  rsave (32, 48*RSIZE +  0*8);                                         \
+  rsave (33, 48*RSIZE +  1*8);                                         \
+  rsave (34, 48*RSIZE +  2*8);                                         \
+  rsave (35, 48*RSIZE +  3*8);                                         \
+  rsave (36, 48*RSIZE +  4*8);                                         \
+  rsave (37, 48*RSIZE +  5*8);                                         \
+  rsave (38, 48*RSIZE +  6*8);                                         \
+  rsave (39, 48*RSIZE +  7*8);                                         \
+  rsave (40, 48*RSIZE +  8*8);                                         \
+  rsave (41, 48*RSIZE +  9*8);                                         \
+  rsave (42, 48*RSIZE + 10*8);                                         \
+  rsave (43, 48*RSIZE + 11*8);                                         \
+  rsave (44, 48*RSIZE + 12*8);                                         \
+  rsave (45, 48*RSIZE + 13*8);                                         \
+  rsave (46, 48*RSIZE + 14*8);                                         \
+  rsave (47, 48*RSIZE + 15*8);                                         \
+  rsave (48, 48*RSIZE + 16*8);                                         \
+  rsave (49, 48*RSIZE + 17*8);                                         \
+  rsave (50, 48*RSIZE + 18*8);                                         \
+  rsave (51, 48*RSIZE + 19*8);                                         \
+  rsave (52, 48*RSIZE + 20*8);                                         \
+  rsave (53, 48*RSIZE + 21*8);                                         \
+  rsave (54, 48*RSIZE + 22*8);                                         \
+  rsave (55, 48*RSIZE + 23*8);                                         \
+  rsave (56, 48*RSIZE + 24*8);                                         \
+  rsave (57, 48*RSIZE + 25*8);                                         \
+  rsave (58, 48*RSIZE + 26*8);                                         \
+  rsave (59, 48*RSIZE + 27*8);                                         \
+  rsave (60, 48*RSIZE + 28*8);                                         \
+  rsave (61, 48*RSIZE + 29*8);                                         \
+  rsave (62, 48*RSIZE + 30*8);                                         \
+  rsave (63, 48*RSIZE + 31*8)
+
+/* Describe where the VMX regs are saved.  */
+#ifdef CONFIG_ALTIVEC
+#define EH_FRAME_VMX \
+  vsave_msr0 ( 0);                                                     \
+  vsave_msr1 ( 1);                                                     \
+  vsave_msr1 ( 2);                                                     \
+  vsave_msr1 ( 3);                                                     \
+  vsave_msr1 ( 4);                                                     \
+  vsave_msr1 ( 5);                                                     \
+  vsave_msr1 ( 6);                                                     \
+  vsave_msr1 ( 7);                                                     \
+  vsave_msr1 ( 8);                                                     \
+  vsave_msr1 ( 9);                                                     \
+  vsave_msr1 (10);                                                     \
+  vsave_msr1 (11);                                                     \
+  vsave_msr1 (12);                                                     \
+  vsave_msr1 (13);                                                     \
+  vsave_msr1 (14);                                                     \
+  vsave_msr1 (15);                                                     \
+  vsave_msr1 (16);                                                     \
+  vsave_msr1 (17);                                                     \
+  vsave_msr1 (18);                                                     \
+  vsave_msr1 (19);                                                     \
+  vsave_msr1 (20);                                                     \
+  vsave_msr1 (21);                                                     \
+  vsave_msr1 (22);                                                     \
+  vsave_msr1 (23);                                                     \
+  vsave_msr1 (24);                                                     \
+  vsave_msr1 (25);                                                     \
+  vsave_msr1 (26);                                                     \
+  vsave_msr1 (27);                                                     \
+  vsave_msr1 (28);                                                     \
+  vsave_msr1 (29);                                                     \
+  vsave_msr1 (30);                                                     \
+  vsave_msr1 (31);                                                     \
+  vsave_msr2 (33, 32*16+12);                                           \
+  vsave      (32, 32*16)
+#else
+#define EH_FRAME_VMX
+#endif
+
+.Lcie:
+       .long .Lcie_end - .Lcie_start
+.Lcie_start:
+       .long 0                 /* CIE ID */
+       .byte 1                 /* Version number */
+       .string "zRS"           /* NUL-terminated augmentation string */
+       .uleb128 4              /* Code alignment factor */
+       .sleb128 -4             /* Data alignment factor */
+       .byte 67                /* Return address register column, ap */
+       .uleb128 1              /* Augmentation value length */
+       .byte 0x1b              /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */
+       .byte 0x0c,1,0          /* DW_CFA_def_cfa: r1 ofs 0 */
+       .balign 4
+.Lcie_end:
+
+       .long .Lfde0_end - .Lfde0_start
+.Lfde0_start:
+       .long .Lfde0_start - .Lcie      /* CIE pointer. */
+       .long .Lsig_start - .           /* PC start, length */
+       .long .Lsig_end - .Lsig_start
+       .uleb128 0                      /* Augmentation */
+       EH_FRAME_GEN
+       EH_FRAME_FP
+       EH_FRAME_VMX
+       .balign 4
+.Lfde0_end:
+
+/* We have a different stack layout for rt_sigreturn.  */
+#undef PTREGS
+#define PTREGS 64+16+128+20+28
+
+       .long .Lfde1_end - .Lfde1_start
+.Lfde1_start:
+       .long .Lfde1_start - .Lcie      /* CIE pointer. */
+       .long .Lsigrt_start - .         /* PC start, length */
+       .long .Lsigrt_end - .Lsigrt_start
+       .uleb128 0                      /* Augmentation */
+       EH_FRAME_GEN
+       EH_FRAME_FP
+       EH_FRAME_VMX
+       .balign 4
+.Lfde1_end: