Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE]PIC #317

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ endif

CFLAGS += -Iinclude -fno-builtin-malloc

ifneq ($(LIBPHOENIX_NOPIC), y)
CFLAGS += -fpic
endif

OBJS :=
# crt0.o should have all necessary initialization + call to main()
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/v7a/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# Author: Pawel Pisarczyk
#

OBJS += $(addprefix $(PREFIX_O)arch/arm/v7a/, syscalls.o reboot.o)
OBJS += $(addprefix $(PREFIX_O)arch/arm/v7a/, syscalls.o reboot.o tls.o)
48 changes: 48 additions & 0 deletions arch/arm/v7a/tls.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Phoenix-RTOS
*
* libphoenix
*
* tls access function
*
* Copyright 2023 Phoenix Systems
* Author: Hubert Badocha
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/


/* NOTE:
* When libphoenix is compiled as a PIC, even when linked into a static NOPIC binary,
* compiler generates accesses to TLS as calls to this function.
* This functions is simple version just for static binaries purposes,
* in dynamic binaries dynamic linker handles TLS accesses. */


/* typedef struct {
* unsigned long ti_moduleid;
* unsigned long ti_tlsoffset;
* } TLS_index;
*
* void *__tls_get_addr(TLS_index *ti) */
.thumb
.syntax unified

.text

.thumb_func
.globl __tls_get_addr;
.type __tls_get_addr, %function;
.align 2
__tls_get_addr:
/* Access ti_tlsoffset. */
ldr r0, [r0, #4]
/* Get thread pointer. */
mrc p15, 0, r1, cr13, cr0, 3
/* GCC expects that TLS block has 8 byte TCB pointer at the begging. */
add r1, r1, #8
add r0, r0, r1
bx lr
.size __tls_get_addr, .-__tls_get_addr
192 changes: 107 additions & 85 deletions arch/ia32/jmp.S
Original file line number Diff line number Diff line change
Expand Up @@ -5,127 +5,149 @@
*
* setjmp, longjmp
*
* Copyright 2018-2019 Phoenix Systems
* Author: Jan Sikorski, Andrzej Glowinski
* Copyright 2018-2019, 2023 Phoenix Systems
* Author: Jan Sikorski, Andrzej Glowinski, Hubert Badocha
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

/* jmp_buf layout:
* esi
* ebx
* edi
* ebp
* esp + 4
* return address
* signal mask indicator (0 - not saved, otherwise saved(GOT addr on PIC))
* signal mask (if saved)
*/

#define __ASSEMBLY__


.text

.globl _setjmp
.type _setjmp, %function
_setjmp:

.macro SETJMP_SAVE_REGS
/* Store registers into jmpbuf */
movl 4(%esp), %edx
movl %ebx, (%edx)
movl %esi, 4(%edx)
movl %edi, 8(%edx)
movl %ebp, 12(%edx)
leal 4(%esp), %ecx
movl (%ecx), %edx
movl %esi, (%edx)
movl %ebx, 4(%edx)
movl %edi, 8(%edx)
movl %ebp, 12(%edx)
/* Store stack pointer pointing before return address */
leal 4(%esp), %ecx
movl %ecx, 16(%edx)
/* Store jump address */
leal (1f), %ecx
movl %ecx, 20(%edx)
movl %ecx, 16(%edx)
/* Store return address */
movl (%esp), %ecx
movl %ecx, 24(%edx)
/* Store result */
movl $0, %eax
ret
1:
/* Jump point. Push return address to stack */
pushl 24(%edx)
movl (%esp), %ecx
movl %ecx, 20(%edx)
.endm


.globl _setjmp
.type _setjmp, %function
.align 4
_setjmp:
SETJMP_SAVE_REGS
/* Set no mask indicator */
movl $0, 24(%edx)
/* Store result (0) */
xorl %eax, %eax
badochov marked this conversation as resolved.
Show resolved Hide resolved
ret
.size _setjmp, .-_setjmp


.globl setjmp
.type setjmp, %function
badochov marked this conversation as resolved.
Show resolved Hide resolved
.align 4
setjmp:
/* Get signal mask */
pushl $0
pushl $0
call signalMask
addl $8, %esp
/* Store registers into jmpbuf */
movl 4(%esp), %edx
movl %ebx, (%edx)
movl %esi, 4(%edx)
movl %edi, 8(%edx)
movl %ebp, 12(%edx)
/* Store stack pointer pointing before return address */
leal 4(%esp), %ecx
movl %ecx, 16(%edx)
/* Store jump address */
leal (1f), %ecx
movl %ecx, 20(%edx)
/* Store return address */
movl (%esp), %ecx
movl %ecx, 24(%edx)
/* Store signal mask */
movl %eax, 28(%edx)
/* Store result */
movl $0, %eax
ret
1:
/* Jump point. Push return address to stack */
pushl 24(%edx)
/* Store longjmp return value */
pushl %eax
/* Restore signal mask */
movl 28(%edx), %ecx
pushl $0xffffffff
pushl %ecx
SETJMP_SAVE_REGS
/* Get signal mask */
#if __pic__ == 0
pushl $0
pushl $0
call signalMask
addl $8, %esp
/* Restore longjmp return value */
popl %eax
addl $8, %esp
/* Store signal mask indicator */
movl $1, 24(%edx)
badochov marked this conversation as resolved.
Show resolved Hide resolved
#else
pushl %ebx

call .l1
.l1:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+(.-.l1), %ebx
badochov marked this conversation as resolved.
Show resolved Hide resolved

pushl $0
pushl $0
call *signalMask@got(%ebx)
addl $8, %esp
/* Save GOT address as an indicator as it will not be 0 */
movl %ebx, 24(%edx)

popl %ebx
#endif
/* Store signal mask */
movl %eax, 28(%edx)
/* Store result (0) */
xorl %eax, %eax
ret
.size setjmp, .-setjmp


.globl _longjmp
.type _longjmp, %function
.align 4
_longjmp:
movl 4(%esp), %edx
movl 8(%esp), %eax
test %eax, %eax
jnz 1f
inc %eax
/* Since esi will be restored later it can be used as a scratch register */
/* Using it allows to safely call signalMask */
movl 4(%esp), %esi
/* Check mask indicator */
/* Since ebx will be restored later it can be used as a scratch register */
/* ebx as the mask indicator is a GOT address in PIC */
movl 24(%esi), %ebx
test %ebx, %ebx
jz 1f
/* Restore signal mask */
pushl $0xffffffff
pushl 28(%esi)

#if __pic__ == 0
call signalMask
#else
call *signalMask@got(%ebx)
#endif

addl $8, %esp
1:
/* Get second argument */
movl 8(%esp), %eax
/* _longjmp shall return 1 if 0 is provided as the second argument */
movl $1, %ecx
test %eax, %eax
cmove %ecx, %eax
/* Restore registers from jmpbuf */
movl (%edx), %ebx
movl 4(%edx), %esi
movl 8(%edx), %edi
movl 12(%edx), %ebp
movl 16(%edx), %esp
/* Restore jump address */
movl 20(%edx), %ecx
/* Jump */
jmp *%ecx
movl 4(%esi), %ebx
movl 8(%esi), %edi
movl 12(%esi), %ebp
movl 16(%esi), %esp
/* Jump point. Push return address to stack */
pushl 20(%esi)
/* At last restore esi */
movl (%esi), %esi
ret
.size _longjmp, .-_longjmp


.globl sigsetjmp
.type sigsetjmp, %function
sigsetjmp:
/* Modify stack frame to skip this function when returning from setjmp */
movl 8(%esp), %edx
movl 4(%esp), %ecx
movl (%esp), %eax
addl $8, %esp
pushl %ecx
pushl %eax

.align 4
movl 8(%esp), %edx
/* Call proper setjmp */
test %edx, %edx
jne setjmp
jmp _setjmp
test %edx, %edx
jz _setjmp
jmp setjmp
.size sigsetjmp, .-sigsetjmp
27 changes: 21 additions & 6 deletions arch/ia32/signal.S
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
*
* Signal trampoline (ia32)
*
* Copyright 2019 Phoenix Systems
* Author: Jan Sikorski
* Copyright 2019, 2023 Phoenix Systems
* Author: Jan Sikorski, Hubert Badocha
*
* This file is part of Phoenix-RTOS.
*
Expand All @@ -19,14 +19,29 @@

.globl _signal_trampoline
.type _signal_trampoline, %function
.align 4
_signal_trampoline:
/* Signal number on stack */
call _signal_handler
#if __pic__ == 0
call _signal_handler
#else
/* ebx will be restored by sigreturn */
call .l1
.l1:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+(.-.l1), %ebx

addl $4, %esp
call *_signal_handler@got(%ebx)
#endif

addl $4, %esp
/* Put old mask on stack */
push %eax
pushl %eax
/* cpu context *, eip, esp on stack */
call sigreturn
#if __pic__ == 0
call sigreturn
#else
call *sigreturn@got(%ebx)
#endif
.size _signal_trampoline, .-_signal_trampoline

2 changes: 1 addition & 1 deletion arch/riscv64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
# Author: Pawel Pisarczyk
#

OBJS += $(addprefix $(PREFIX_O)arch/riscv64/, syscalls.o string.o signal.o reboot.o jmp.o)
OBJS += $(addprefix $(PREFIX_O)arch/riscv64/, syscalls.o string.o signal.o reboot.o jmp.o tls.o)
CRT0_OBJS += $(addprefix $(PREFIX_O)arch/riscv64/, crt0.o)
14 changes: 13 additions & 1 deletion arch/riscv64/jmp.S
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,28 @@
.globl _setjmp
.type _setjmp, %function
_setjmp:
#if __pic__ == 0
mv a1, zero
j sigsetjmp
#else
auipc t0, %pcrel_hi(sigsetjmp)
mv a1, zero
jr t0, %pcrel_lo(setjmp)
#endif
.size _setjmp, .-_setjmp


.globl setjmp
.type setjmp, %function
setjmp:
#if __pic__ == 0
li a1, 1
j sigsetjmp
j sigsetjmp
#else
auipc t0, %pcrel_hi(sigsetjmp)
li a1, 1
jr t0, %pcrel_lo(setjmp)
#endif
.size setjmp, .-setjmp


Expand Down
5 changes: 5 additions & 0 deletions arch/riscv64/syscalls.S
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ sym: \
.globl vfork;
.type vfork, %function;
vfork:
#if __pic__ == 0
j vforksvc
#else
auipc t0, %pcrel_hi(vforksvc)
jr t0, %pcrel_lo(vfork)
#endif
.size vfork, .-vfork


Expand Down
Loading
Loading