From 09d2c06752f8151b1eaa9aba9dac09f33378a404 Mon Sep 17 00:00:00 2001 From: Hubert Badocha Date: Fri, 1 Dec 2023 18:49:42 +0100 Subject: [PATCH 1/3] libphoenix: compile with FPIC by default JIRA: RTOS-664 --- Makefile | 3 +++ arch/armv7a/Makefile | 2 +- arch/armv7a/tls.S | 41 +++++++++++++++++++++++++++++++++++++++++ arch/riscv64/Makefile | 2 +- arch/riscv64/tls.S | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 arch/armv7a/tls.S create mode 100644 arch/riscv64/tls.S diff --git a/Makefile b/Makefile index acbcfeab..dbdc21b6 100644 --- a/Makefile +++ b/Makefile @@ -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() diff --git a/arch/armv7a/Makefile b/arch/armv7a/Makefile index 9be5def5..18d77f0f 100644 --- a/arch/armv7a/Makefile +++ b/arch/armv7a/Makefile @@ -5,5 +5,5 @@ # Author: Pawel Pisarczyk # -OBJS += $(addprefix $(PREFIX_O)arch/armv7a/, syscalls.o jmp.o signal.o string.o reboot.o) +OBJS += $(addprefix $(PREFIX_O)arch/armv7a/, syscalls.o jmp.o signal.o string.o reboot.o tls.o) CRT0_OBJS += $(addprefix $(PREFIX_O)arch/armv7a/, _start.o) diff --git a/arch/armv7a/tls.S b/arch/armv7a/tls.S new file mode 100644 index 00000000..e9e86136 --- /dev/null +++ b/arch/armv7a/tls.S @@ -0,0 +1,41 @@ +/* + * 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) */ +.globl __tls_get_addr; +.type __tls_get_addr, %function; +__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 diff --git a/arch/riscv64/Makefile b/arch/riscv64/Makefile index 54310c15..5d3600c2 100644 --- a/arch/riscv64/Makefile +++ b/arch/riscv64/Makefile @@ -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/, _start.o) diff --git a/arch/riscv64/tls.S b/arch/riscv64/tls.S new file mode 100644 index 00000000..765ead8e --- /dev/null +++ b/arch/riscv64/tls.S @@ -0,0 +1,39 @@ +/* + * 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) */ +.globl __tls_get_addr; +.type __tls_get_addr, %function; +__tls_get_addr: + /* Access ti_tlsoffset. */ + ld a0, 8(a0) + /* GCC expects that Dynamic Thread Vector pointer points at TLS block start + 0x800 */ + li t0, 0x800 + add a0, a0, t0 + add a0, a0, tp + ret +.size __tls_get_addr, .-__tls_get_addr From 8523b5418bb9b41c334c25d94edca38b507b9ccf Mon Sep 17 00:00:00 2001 From: Hubert Badocha Date: Sun, 10 Dec 2023 22:41:09 +0100 Subject: [PATCH 2/3] ia32: support PIE in asm In PIE on ia32 function calls should be made using GOT. JIRA: RTOS-664 --- arch/ia32/jmp.S | 188 +++++++++++++++++++++++++-------------------- arch/ia32/signal.S | 26 +++++-- 2 files changed, 123 insertions(+), 91 deletions(-) diff --git a/arch/ia32/jmp.S b/arch/ia32/jmp.S index 13351d97..4d6152ba 100644 --- a/arch/ia32/jmp.S +++ b/arch/ia32/jmp.S @@ -5,43 +5,55 @@ * * 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 /* 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 +_setjmp: + __SETJMP + /* Set no mask indicator */ + movl $0, 24(%edx) + /* Store result (0) */ + xorl %eax, %eax ret .size _setjmp, .-_setjmp @@ -49,44 +61,36 @@ _setjmp: .globl setjmp .type setjmp, %function 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 + /* 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) +#else + pushl %ebx + + call .l1 +.l1: + popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+(.-.l1), %ebx + + 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 $0, %eax ret .size setjmp, .-setjmp @@ -94,38 +98,52 @@ setjmp: .globl _longjmp .type _longjmp, %function _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 - + movl 8(%esp), %edx /* Call proper setjmp */ - test %edx, %edx - jne setjmp - jmp _setjmp + test %edx, %edx + jz _setjmp + jmp setjmp .size sigsetjmp, .-sigsetjmp diff --git a/arch/ia32/signal.S b/arch/ia32/signal.S index 38131c99..b9c6f2d8 100644 --- a/arch/ia32/signal.S +++ b/arch/ia32/signal.S @@ -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. * @@ -21,12 +21,26 @@ .type _signal_trampoline, %function _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 From a90a1f983337d86838a6a1f413540731de4bf444 Mon Sep 17 00:00:00 2001 From: Hubert Badocha Date: Tue, 12 Dec 2023 00:47:36 +0100 Subject: [PATCH 3/3] Setup nightly workflow and no lint --- .github/workflows/ci.yml | 2 ++ .github/workflows/lint.yml | 17 ----------------- 2 files changed, 2 insertions(+), 17 deletions(-) delete mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88a5beda..fdc5f12f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,6 @@ on: jobs: call-ci: uses: phoenix-rtos/phoenix-rtos-project/.github/workflows/ci-submodule.yml@master + with: + nightly: true secrets: inherit diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 4da9c56a..00000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,17 +0,0 @@ -# vim:sw=2:ts=2 -name: lint - -# on events -on: - push: - branches: - - master - - 'feature/*' - pull_request: - branches: - - master - - 'feature/*' - -jobs: - call-lint: - uses: phoenix-rtos/phoenix-rtos-project/.github/workflows/lint.yml@master