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 <richard.henderson@linaro.org>
This commit is contained in:
parent
00cc2934b2
commit
e34136d930
@ -1187,6 +1187,14 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
|
|||||||
#define USE_ELF_CORE_DUMP
|
#define USE_ELF_CORE_DUMP
|
||||||
#define ELF_EXEC_PAGESIZE 4096
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef TARGET_LOONGARCH64
|
#ifdef TARGET_LOONGARCH64
|
||||||
|
@ -273,7 +273,14 @@ static void elfN(process)(FILE *outf, void *buf, bool need_bswap)
|
|||||||
errors++;
|
errors++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PT_LOPROC + 3:
|
||||||
|
if (ehdr->e_machine == EM_PPC64) {
|
||||||
|
break; /* DT_PPC64_OPT: integer bitmask */
|
||||||
|
}
|
||||||
|
goto do_default;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
do_default:
|
||||||
/* This is probably something target specific. */
|
/* This is probably something target specific. */
|
||||||
fprintf(stderr, "VDSO has unknown DYNAMIC entry (%lx)\n",
|
fprintf(stderr, "VDSO has unknown DYNAMIC entry (%lx)\n",
|
||||||
(unsigned long)tag);
|
(unsigned long)tag);
|
||||||
|
20
linux-user/ppc/Makefile.vdso
Normal file
20
linux-user/ppc/Makefile.vdso
Normal file
@ -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 $<
|
@ -3,3 +3,15 @@ syscall_nr_generators += {
|
|||||||
arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ],
|
arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ],
|
||||||
output: '@BASENAME@_nr.h')
|
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])
|
||||||
|
@ -21,14 +21,7 @@
|
|||||||
#include "user-internals.h"
|
#include "user-internals.h"
|
||||||
#include "signal-common.h"
|
#include "signal-common.h"
|
||||||
#include "linux-user/trace.h"
|
#include "linux-user/trace.h"
|
||||||
|
#include "vdso-asmoffset.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
|
|
||||||
|
|
||||||
/* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
|
/* 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. */
|
on 64-bit PPC, sigcontext and mcontext are one and the same. */
|
||||||
@ -73,6 +66,16 @@ struct target_mcontext {
|
|||||||
#endif
|
#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. */
|
/* See arch/powerpc/include/asm/sigcontext.h. */
|
||||||
struct target_sigcontext {
|
struct target_sigcontext {
|
||||||
target_ulong _unused[4];
|
target_ulong _unused[4];
|
||||||
@ -161,6 +164,7 @@ struct target_ucontext {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined(TARGET_PPC64)
|
||||||
/* See arch/powerpc/kernel/signal_32.c. */
|
/* See arch/powerpc/kernel/signal_32.c. */
|
||||||
struct target_sigframe {
|
struct target_sigframe {
|
||||||
struct target_sigcontext sctx;
|
struct target_sigcontext sctx;
|
||||||
@ -168,6 +172,10 @@ struct target_sigframe {
|
|||||||
int32_t abigap[56];
|
int32_t abigap[56];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QEMU_BUILD_BUG_ON(offsetof(struct target_sigframe, mctx)
|
||||||
|
!= offsetof_sigframe_mcontext);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
|
|
||||||
#define TARGET_TRAMP_SIZE 6
|
#define TARGET_TRAMP_SIZE 6
|
||||||
@ -184,6 +192,10 @@ struct target_rt_sigframe {
|
|||||||
char abigap[288];
|
char abigap[288];
|
||||||
} __attribute__((aligned(16)));
|
} __attribute__((aligned(16)));
|
||||||
|
|
||||||
|
QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe,
|
||||||
|
uc.tuc_sigcontext.mcontext)
|
||||||
|
!= offsetof_rt_sigframe_mcontext);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
struct target_rt_sigframe {
|
struct target_rt_sigframe {
|
||||||
@ -192,6 +204,9 @@ struct target_rt_sigframe {
|
|||||||
int32_t abigap[56];
|
int32_t abigap[56];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QEMU_BUILD_BUG_ON(offsetof(struct target_rt_sigframe, uc.tuc_mcontext)
|
||||||
|
!= offsetof_rt_sigframe_mcontext);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
|
70
linux-user/ppc/vdso-32.ld
Normal file
70
linux-user/ppc/vdso-32.ld
Normal file
@ -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
|
||||||
|
}
|
BIN
linux-user/ppc/vdso-32.so
Executable file
BIN
linux-user/ppc/vdso-32.so
Executable file
Binary file not shown.
68
linux-user/ppc/vdso-64.ld
Normal file
68
linux-user/ppc/vdso-64.ld
Normal file
@ -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
|
||||||
|
}
|
BIN
linux-user/ppc/vdso-64.so
Executable file
BIN
linux-user/ppc/vdso-64.so
Executable file
Binary file not shown.
BIN
linux-user/ppc/vdso-64le.so
Executable file
BIN
linux-user/ppc/vdso-64le.so
Executable file
Binary file not shown.
20
linux-user/ppc/vdso-asmoffset.h
Normal file
20
linux-user/ppc/vdso-asmoffset.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Size of dummy stack frame allocated when calling signal handler.
|
||||||
|
* See arch/powerpc/include/asm/ptrace.h.
|
||||||
|
*/
|
||||||
|
#ifdef TARGET_ABI32
|
||||||
|
# define SIGNAL_FRAMESIZE 64
|
||||||
|
#else
|
||||||
|
# define SIGNAL_FRAMESIZE 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TARGET_ABI32
|
||||||
|
# define offsetof_sigframe_mcontext 0x20
|
||||||
|
# define offsetof_rt_sigframe_mcontext 0x140
|
||||||
|
# define offsetof_mcontext_fregs 0xc0
|
||||||
|
# define offsetof_mcontext_vregs 0x1d0
|
||||||
|
#else
|
||||||
|
# define offsetof_rt_sigframe_mcontext 0xe8
|
||||||
|
# define offsetof_mcontext_fregs 0x180
|
||||||
|
# define offsetof_mcontext_vregs_ptr 0x288
|
||||||
|
#endif
|
239
linux-user/ppc/vdso.S
Normal file
239
linux-user/ppc/vdso.S
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
* PowerPC linux replacement vdso.
|
||||||
|
*
|
||||||
|
* Copyright 2023 Linaro, Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/unistd.h>
|
||||||
|
#include <asm/errno.h>
|
||||||
|
|
||||||
|
#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
|
Loading…
Reference in New Issue
Block a user