devel
Threads by month
- ----- 2025 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
June 2024
- 5 participants
- 5 discussions
Hi,
I released uClibc-ng 1.0.49 on Saturday.
Many gcc 14.1.0 fixes were added thanks to Dmitry and Max.
Xtensa FDPIC support was added by Max.
git shortlog v1.0.49...v1.0.48
Dmitry Chestnykh (6):
Correct uClibc compilation.
Fix uClibc build for nds32 with gcc-14.
Fix riscv32 build with gcc-14.
riscv32: Fix `struct ucontext` definition.
Fix wrong `struct ucontext_t` typedef for all arches.
Cast to proper types inside atomic macroses.
Fabrice Fontaine (1):
libc/sysdeps/linux/common/utime.c: fix riscv32 build
Joe Damato (1):
epoll.h: Add epoll ioctls
Max Filippov (9):
iconv: fix type mismatches
ldso: FDPIC: fix type mismatches
ldso: arm: fix build with gcc-14
malloc/memalign: avoid integer overflow
fix kernel_stat64 definition
linuxthreads: enable unwinding over signal frames
xtensa: use compiler-provided XCHAL macros
xtensa: make _init and _fini hidden
xtensa: add FDPIC support
Waldemar Brodkorb (9):
futimesat: add missing header
sparc64: Fix incorrect sigreturn stub function implementation
csky: allow time64
m68k: fix noMMU ELF compile with gcc 14.x
Revert "nds32: sync with binutils 2.37, gcc 11.2 and linux 5.10.93 changes"
m68k: fix for m68000 cpu
config: make ctor/dtor visible again
config: enable TIME64 by default
bump version for 1.0.49 release
Yuriy Kolerov (1):
libc: cast free() argument to void * in wchar.c
best regards
Waldemar
3
2

17 Jun '24
From: Yuriy Kolerov <ykolerov(a)synopsys.com>
iconv_close() accepts iconv_t type (which is void *) and passes
it to free() which accepts void *. However, GCC 14 raises a
-Wint-conversion warning if it is not casted to void * because
GCC cannot unwind typedef of iconv_t.
Signed-off-by: Yuriy Kolerov <ykolerov(a)synopsys.com>
---
libc/misc/wchar/wchar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/misc/wchar/wchar.c b/libc/misc/wchar/wchar.c
index 2714d47d7..782b67f93 100644
--- a/libc/misc/wchar/wchar.c
+++ b/libc/misc/wchar/wchar.c
@@ -1298,7 +1298,7 @@ iconv_t weak_function iconv_open(const char *tocode, const char *fromcode)
int weak_function iconv_close(iconv_t cd)
{
- free(cd);
+ free((void *) cd);
return 0;
}
--
2.39.2
2
1
This change implements Xtensa FDPIC ABI as specified in the first
version of the following document:
https://github.com/jcmvbkbc/xtensa-abi/blob/master/fdpic-xtensa.txt
Signed-off-by: Max Filippov <jcmvbkbc(a)gmail.com>
---
The toolchain components matching the libc are available in
the following repositories with the tag xtensa-fdpic-abi-spec-1.4:
https://github.com/jcmvbkbc/binutils-gdb-xtensa/tree/xtensa-fdpic-abi-spec-…
https://github.com/jcmvbkbc/gcc-xtensa/tree/xtensa-fdpic-abi-spec-1.4
---
Changes v1->v2:
- add missing ';' after FDPIC_LOAD_JUMPTARGET in the SYSCALL_ERROR_HANDLER
It suppressed the following callx instruction resulting in occasional
crashes on error return from certain syscalls
- add -DUSE___THREAD to ASFLAGS in nptl/.../xtensa/Makefile.arch to
generate direct access to errno in assembly code using
SYSCALL_ERROR_HANDLER
- drop patch 2 from the series
---
Rules.mak | 4 +
extra/Configs/Config.in | 2 +-
extra/Configs/Config.in.arch | 2 +-
include/elf.h | 6 +-
ldso/ldso/xtensa/dl-inlines.h | 1 +
ldso/ldso/xtensa/dl-startup.h | 91 +++++++++++++-
ldso/ldso/xtensa/dl-sysdep.h | 66 +++++++++-
ldso/ldso/xtensa/dl-tlsdesc.S | 10 +-
ldso/ldso/xtensa/elfinterp.c | 114 +++++++++++++----
libc/sysdeps/linux/xtensa/__start_context.S | 6 +-
libc/sysdeps/linux/xtensa/bits/elf-fdpic.h | 117 ++++++++++++++++++
libc/sysdeps/linux/xtensa/clone.S | 6 +
libc/sysdeps/linux/xtensa/crt1.S | 81 ++++++++++++
libc/sysdeps/linux/xtensa/crti.S | 8 ++
libc/sysdeps/linux/xtensa/crtn.S | 6 +
libc/sysdeps/linux/xtensa/crtreloc.c | 105 ++++++++++++++++
libc/sysdeps/linux/xtensa/getcontext.S | 1 +
libc/sysdeps/linux/xtensa/makecontext.c | 5 +
libc/sysdeps/linux/xtensa/setcontext.S | 1 +
libc/sysdeps/linux/xtensa/setjmp.S | 3 +-
libc/sysdeps/linux/xtensa/swapcontext.S | 1 +
libc/sysdeps/linux/xtensa/sysdep.h | 48 ++++++-
.../unix/sysv/linux/xtensa/Makefile.arch | 2 +
libpthread/nptl/sysdeps/xtensa/dl-tls.h | 33 +++--
24 files changed, 673 insertions(+), 46 deletions(-)
create mode 100644 ldso/ldso/xtensa/dl-inlines.h
create mode 100644 libc/sysdeps/linux/xtensa/bits/elf-fdpic.h
create mode 100644 libc/sysdeps/linux/xtensa/crtreloc.c
diff --git a/Rules.mak b/Rules.mak
index 5be74b86edd4..70d681238b24 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -520,6 +520,10 @@ ifeq ($(TARGET_ARCH),c6x)
CPU_LDFLAGS-y += $(CPU_CFLAGS)
endif
+ifeq ($(TARGET_ARCH),xtensa)
+ CPU_CFLAGS-$(UCLIBC_FORMAT_FDPIC_ELF) += -mfdpic
+endif
+
$(eval $(call check-gcc-var,$(PIEFLAG_NAME)))
PIEFLAG := $(CFLAG_$(PIEFLAG_NAME))
ifeq ($(PIEFLAG),)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index 3a0136c99628..b2501a4da327 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -615,7 +615,7 @@ config UCLIBC_HAS_THREADS_NATIVE
!TARGET_h8300 && \
!TARGET_hppa && \
!TARGET_ia64 && \
- (ARCH_USE_MMU || TARGET_arm)
+ (ARCH_USE_MMU || TARGET_arm || TARGET_xtensa)
help
If you want to compile uClibc with NPTL support, then answer Y.
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch
index 1ae5134b9df5..c13497893414 100644
--- a/extra/Configs/Config.in.arch
+++ b/extra/Configs/Config.in.arch
@@ -20,7 +20,7 @@ config UCLIBC_FORMAT_ELF
select HAVE_LDSO
config UCLIBC_FORMAT_FDPIC_ELF
bool "FDPIC ELF"
- depends on !ARCH_USE_MMU && (TARGET_bfin || TARGET_frv || TARGET_arm)
+ depends on !ARCH_USE_MMU && (TARGET_bfin || TARGET_frv || TARGET_arm || TARGET_xtensa)
select DOPIC
config UCLIBC_FORMAT_DSBT_ELF
bool "DBST ELF"
diff --git a/include/elf.h b/include/elf.h
index c2efa9978677..1e7c89615a44 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -3588,8 +3588,12 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_XTENSA_TLSDESC_FN 50
#define R_XTENSA_TLSDESC_ARG 51
#define R_XTENSA_TLS_TPOFF 53
+#define R_XTENSA_SYM32 63
+#define R_XTENSA_FUNCDESC 68
+#define R_XTENSA_FUNCDESC_VALUE 69
+#define R_XTENSA_TLSDESC 72
/* Keep this the last entry. */
-#define R_XTENSA_NUM 54
+#define R_XTENSA_NUM 77
/* C6X specific relocs */
#define R_C6000_NONE 0
diff --git a/ldso/ldso/xtensa/dl-inlines.h b/ldso/ldso/xtensa/dl-inlines.h
new file mode 100644
index 000000000000..8fdf6eb48679
--- /dev/null
+++ b/ldso/ldso/xtensa/dl-inlines.h
@@ -0,0 +1 @@
+#include "../fdpic/dl-inlines.h"
diff --git a/ldso/ldso/xtensa/dl-startup.h b/ldso/ldso/xtensa/dl-startup.h
index c9350c0f201e..2a453752acaf 100644
--- a/ldso/ldso/xtensa/dl-startup.h
+++ b/ldso/ldso/xtensa/dl-startup.h
@@ -7,6 +7,68 @@
* Parts taken from glibc/sysdeps/xtensa/dl-machine.h.
*/
+#if defined(__FDPIC__)
+__asm__ (
+ " .text\n"
+ " .align 4\n"
+ " .literal_position\n"
+ " .global _start\n"
+ " .type _start, @function\n"
+ " .hidden _start\n"
+ "_start:\n"
+ " .begin no-transform\n"
+ " _call0 1f\n"
+ "2:\n"
+ " .end no-transform\n"
+ " .align 4\n"
+ "1:\n"
+#if defined(__XTENSA_CALL0_ABI__)
+ " movi a15, 2b\n"
+ " sub a15, a0, a15\n"
+
+ /* Save FDPIC pointers in callee-saved registers */
+ " mov a12, a4\n"
+ " mov a13, a5\n"
+ " mov a14, a6\n"
+
+ /* Call __self_reloc */
+ " mov a2, a5\n"
+ " movi a3, __ROFIXUP_LIST__\n"
+ " add a3, a3, a15\n"
+ " movi a4, __ROFIXUP_END__\n"
+ " add a4, a4, a15\n"
+ " movi a0, __self_reloc\n"
+ " add a0, a0, a15\n"
+ " callx0 a0\n"
+
+ /* call _dl_start */
+ " mov a3, a12\n"
+ " mov a4, a13\n"
+ " mov a5, a14\n"
+ " mov a7, sp\n"
+ " addi sp, sp, -16\n"
+ " mov a6, sp\n"
+ " mov a11, a2\n"
+ /* a13, interpreter map is no longer needed, save interpreter GOT there */
+ " mov a13, a2\n"
+ " movi a0, _dl_start\n"
+ " add a0, a0, a15\n"
+ " callx0 a0\n"
+
+ /* call main */
+ " l32i a0, sp, 0\n"
+ " l32i a11, sp, 4\n"
+ " addi sp, sp, 16\n"
+ " mov a4, a12\n"
+ " movi a5, _dl_fini@GOTOFFFUNCDESC\n"
+ " add a5, a5, a13\n"
+ " mov a6, a14\n"
+ " jx a0\n"
+#else
+#error Unsupported Xtensa ABI
+#endif
+ );
+#else /* __FDPIC__ */
#ifndef L_rcrt1
__asm__ (
" .text\n"
@@ -83,6 +145,7 @@ __asm__ (
" bnez a6, 3b\n"
" j .Lfixup_stack_ret");
#endif
+#endif /* __FDPIC__ */
/* Get a pointer to the argv value. */
#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
@@ -90,7 +153,7 @@ __asm__ (
/* Function calls are not safe until the GOT relocations have been done. */
#define NO_FUNCS_BEFORE_BOOTSTRAP
-#if defined(__ARCH_USE_MMU__)
+#if defined(__ARCH_USE_MMU__) && !defined(__FDPIC__)
#define PERFORM_BOOTSTRAP_GOT(tpnt) \
do { \
xtensa_got_location *got_loc; \
@@ -128,3 +191,29 @@ do { \
} \
} while (0)
#endif
+
+#ifdef __FDPIC__
+#undef DL_START
+#define DL_START(X) \
+static void __attribute__ ((used)) \
+_dl_start (Elf32_Addr dl_boot_got_pointer, \
+ struct elf32_fdpic_loadmap *dl_boot_progmap, \
+ struct elf32_fdpic_loadmap *dl_boot_ldsomap, \
+ Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
+ struct funcdesc_value *dl_main_funcdesc, \
+ X)
+
+/*
+ * Transfer control to the user's application, once the dynamic loader
+ * is done. We return the address of the function's entry point to
+ * _dl_boot, see boot1_arch.h.
+ */
+#define START() do { \
+ struct elf_resolve *exec_mod = _dl_loaded_modules; \
+ dl_main_funcdesc->entry_point = _dl_elf_main; \
+ while (exec_mod->libtype != elf_executable) \
+ exec_mod = exec_mod->next; \
+ dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value; \
+ return; \
+} while (0)
+#endif /* __FDPIC__ */
diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h
index 6b908989a8f1..5aa3e177f3a1 100644
--- a/ldso/ldso/xtensa/dl-sysdep.h
+++ b/ldso/ldso/xtensa/dl-sysdep.h
@@ -26,6 +26,7 @@
in l_info array. */
#define DT_XTENSA(x) (DT_XTENSA_##x - DT_LOPROC + DT_NUM + OS_NUM)
+#ifndef __FDPIC__
typedef struct xtensa_got_location_struct {
Elf32_Off offset;
Elf32_Word length;
@@ -86,6 +87,7 @@ typedef struct xtensa_got_location_struct {
else if (dpnt->d_tag == DT_XTENSA_GOT_LOC_SZ) \
dynamic[DT_XTENSA (GOT_LOC_SZ)] = dpnt->d_un.d_val; \
} while (0)
+#endif
/* Here we define the magic numbers that this dynamic loader should accept. */
#define MAGIC1 EM_XTENSA
@@ -115,10 +117,41 @@ elf_machine_dynamic (void)
return (Elf32_Addr) &_DYNAMIC;
}
+#ifdef __FDPIC__
+
+#define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
+do \
+{ \
+ (piclib) = 2; \
+} \
+while (0)
+
+/* We must force strings used early in the bootstrap into the data
+ segment. */
+#undef SEND_EARLY_STDERR
+#define SEND_EARLY_STDERR(S) \
+ do { /* FIXME: implement */; } while (0)
+
+#undef INIT_GOT
+#include "../fdpic/dl-sysdep.h"
+#undef INIT_GOT
+#define INIT_GOT(GOT_BASE,MODULE) \
+{ \
+ (MODULE)->loadaddr.got_value = (GOT_BASE); \
+ GOT_BASE[0] = ((unsigned long *)&_dl_linux_resolve)[0]; \
+ GOT_BASE[1] = ((unsigned long *)&_dl_linux_resolve)[1]; \
+ GOT_BASE[2] = (unsigned long) MODULE; \
+}
+
+#endif /* __FDPIC__ */
+
/* Return the run-time load address of the shared object. */
static __always_inline Elf32_Addr
elf_machine_load_address (void)
{
+#ifdef __FDPIC__
+ return 0;
+#else
Elf32_Addr addr, tmp;
/* At this point, the runtime linker is being bootstrapped and the GOT
@@ -135,11 +168,41 @@ elf_machine_load_address (void)
: "=a" (addr), "=a" (tmp));
return addr - 3;
+#endif
}
+#ifdef __FDPIC__
+
+/* Need bootstrap relocations */
+#define ARCH_NEEDS_BOOTSTRAP_RELOCS
+
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
+ switch (ELF_R_TYPE((RELP)->r_info)){ \
+ case R_XTENSA_SYM32: \
+ *(REL) = (SYMBOL) + (RELP)->r_addend; \
+ break; \
+ case R_XTENSA_RELATIVE: \
+ case R_XTENSA_NONE: \
+ default: \
+ break; \
+ }
+
static __always_inline void
-elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
+elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
Elf32_Word relative_count)
+{
+ Elf32_Rela *rpnt = (Elf32_Rela *) rel_addr;
+ while (relative_count--)
+ {
+ Elf32_Addr *const reloc_addr = (Elf32_Addr *) DL_RELOC_ADDR(load_off, rpnt->r_offset);
+ *reloc_addr = DL_RELOC_ADDR(load_off, *reloc_addr);
+ rpnt++;
+ }
+}
+#else
+static __always_inline void
+elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
+ Elf32_Word relative_count)
{
Elf32_Rela *rpnt = (Elf32_Rela *) rel_addr;
while (relative_count--)
@@ -149,3 +212,4 @@ elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
rpnt++;
}
}
+#endif
diff --git a/ldso/ldso/xtensa/dl-tlsdesc.S b/ldso/ldso/xtensa/dl-tlsdesc.S
index 426f2180b3c0..1a8eacff20cc 100644
--- a/ldso/ldso/xtensa/dl-tlsdesc.S
+++ b/ldso/ldso/xtensa/dl-tlsdesc.S
@@ -24,6 +24,9 @@
.text
HIDDEN_ENTRY (_dl_tlsdesc_return)
+#ifdef __FDPIC__
+ l32i a2, a2, 4
+#endif
rur.threadptr a3
add a2, a2, a3
abi_ret
@@ -53,7 +56,9 @@ END (_dl_tlsdesc_return)
*/
HIDDEN_ENTRY (_dl_tlsdesc_dynamic)
-
+#ifdef __FDPIC__
+ l32i a2, a2, 4
+#endif
/* dtv_t *dtv = (dtv_t *)THREAD_DTV(); */
rur.threadptr a3
l32i a4, a3, 0
@@ -86,7 +91,8 @@ HIDDEN_ENTRY (_dl_tlsdesc_dynamic)
#elif defined(__XTENSA_CALL0_ABI__)
addi a1, a1, -16
s32i a0, a1, 0
- movi a0, __tls_get_addr
+ movi a0, JUMPTARGET(__tls_get_addr)
+ FDPIC_LOAD_JUMPTARGET(a0, a11, a0)
callx0 a0
l32i a0, a1, 0
addi a1, a1, 16
diff --git a/ldso/ldso/xtensa/elfinterp.c b/ldso/ldso/xtensa/elfinterp.c
index e38a02666477..d97f234353e8 100644
--- a/ldso/ldso/xtensa/elfinterp.c
+++ b/ldso/ldso/xtensa/elfinterp.c
@@ -36,6 +36,13 @@
#include "tlsdeschtab.h"
#endif
+#ifdef __FDPIC__
+unsigned long
+_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
+{
+ return 0;
+}
+#else
unsigned long
_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
{
@@ -83,7 +90,7 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
return (unsigned long) new_addr;
}
-
+#endif
static int
_dl_parse (struct elf_resolve *tpnt, struct r_scope_elem *scope,
@@ -145,8 +152,8 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
int reloc_type;
int symtab_index;
char *symname;
-#if defined USE_TLS && USE_TLS
- struct elf_resolve *tls_tpnt = NULL;
+#if defined USE_TLS && USE_TLS || defined (__FDPIC__)
+ struct elf_resolve *def_mod = NULL;
#endif
struct symbol_ref sym_ref;
ElfW(Addr) *reloc_addr;
@@ -155,7 +162,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
ElfW(Addr) old_val;
#endif
- reloc_addr = (ElfW(Addr) *) (tpnt->loadaddr + rpnt->r_offset);
+ reloc_addr = (ElfW(Addr) *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset);
reloc_type = ELF_R_TYPE (rpnt->r_info);
symtab_index = ELF_R_SYM (rpnt->r_info);
sym_ref.sym = &symtab[symtab_index];
@@ -164,9 +171,17 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
symname = strtab + sym_ref.sym->st_name;
if (symtab_index) {
- symbol_addr = (ElfW(Addr))
- _dl_find_hash (symname, scope, tpnt,
- elf_machine_type_class (reloc_type), &sym_ref);
+ if (ELF_ST_BIND (sym_ref.sym->st_info) == STB_LOCAL) {
+ symbol_addr = (ElfW(Addr))
+ DL_RELOC_ADDR(tpnt->loadaddr,
+ symtab[symtab_index].st_value);
+ sym_ref.tpnt = tpnt;
+ } else {
+ symbol_addr = (ElfW(Addr))
+ _dl_find_hash (symname, scope, tpnt,
+ elf_machine_type_class (reloc_type),
+ &sym_ref);
+ }
/*
* We want to allow undefined references to weak symbols - this might
@@ -182,13 +197,13 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
_dl_debug_lookup (symname, tpnt, &symtab[symtab_index],
&sym_ref, elf_machine_type_class(reloc_type));
}
-#if defined USE_TLS && USE_TLS
- tls_tpnt = sym_ref.tpnt;
+#if defined USE_TLS && USE_TLS || defined (__FDPIC__)
+ def_mod = sym_ref.tpnt;
#endif
} else {
symbol_addr =symtab[symtab_index].st_value;
-#if defined USE_TLS && USE_TLS
- tls_tpnt = tpnt;
+#if defined USE_TLS && USE_TLS || defined (__FDPIC__)
+ def_mod = tpnt;
#endif
}
@@ -202,6 +217,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
case R_XTENSA_GLOB_DAT:
case R_XTENSA_JMP_SLOT:
+ case R_XTENSA_SYM32:
*reloc_addr = symbol_addr + rpnt->r_addend;
break;
@@ -219,19 +235,63 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
break;
case R_XTENSA_RELATIVE:
- *reloc_addr += tpnt->loadaddr + rpnt->r_addend;
+ *reloc_addr += DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_addend);
break;
+#ifdef __FDPIC__
+ case R_XTENSA_FUNCDESC_VALUE:
+ {
+ struct funcdesc_value *dst = (struct funcdesc_value *) reloc_addr;
+
+ dst->entry_point = (void *) (symbol_addr + rpnt->r_addend);
+ dst->got_value = def_mod->loadaddr.got_value;
+ }
+ break;
+ case R_XTENSA_FUNCDESC:
+ if (symbol_addr)
+ *reloc_addr = (unsigned long)
+ _dl_funcdesc_for((void *) (symbol_addr + rpnt->r_addend),
+ sym_ref.tpnt->loadaddr.got_value);
+ else
+ /* Relocation against an undefined weak symbol:
+ set funcdesc to zero. */
+ *reloc_addr = 0;
+ break;
+ case R_XTENSA_TLS_TPOFF:
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
+ *reloc_addr = symbol_addr + rpnt->r_addend + def_mod->l_tls_offset;
+ break;
+ case R_XTENSA_TLSDESC:
+ {
+ struct tlsdesc *td = (struct tlsdesc *) reloc_addr;
+#ifndef SHARED
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
+#else
+ if (!TRY_STATIC_TLS ((struct link_map *) def_mod))
+ {
+ td->entry = _dl_tlsdesc_dynamic;
+ td->argument = _dl_make_tlsdesc_dynamic((struct link_map *) def_mod,
+ symbol_addr + rpnt->r_addend);
+ }
+ else
+#endif
+ {
+ td->entry = _dl_tlsdesc_return;
+ td->argument = (void *) (symbol_addr + rpnt->r_addend + def_mod->l_tls_offset);
+ }
+ }
+ break;
+#else
#if defined USE_TLS && USE_TLS
case R_XTENSA_TLS_TPOFF:
- CHECK_STATIC_TLS((struct link_map *) tls_tpnt);
- *reloc_addr = symbol_addr + tls_tpnt->l_tls_offset + rpnt->r_addend;
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
+ *reloc_addr = symbol_addr + rpnt->r_addend + def_mod->l_tls_offset;
break;
case R_XTENSA_TLSDESC_FN:
#ifndef SHARED
- CHECK_STATIC_TLS((struct link_map *) tls_tpnt);
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
#else
- if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt))
+ if (!TRY_STATIC_TLS ((struct link_map *) def_mod))
*reloc_addr = (ElfW(Addr)) _dl_tlsdesc_dynamic;
else
#endif
@@ -239,25 +299,25 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
break;
case R_XTENSA_TLSDESC_ARG:
#ifndef SHARED
- CHECK_STATIC_TLS((struct link_map *) tls_tpnt);
+ CHECK_STATIC_TLS((struct link_map *) def_mod);
#else
- if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt))
+ if (!TRY_STATIC_TLS ((struct link_map *) def_mod))
*reloc_addr = (ElfW(Addr))
- _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt,
+ _dl_make_tlsdesc_dynamic((struct link_map *) def_mod,
symbol_addr + rpnt->r_addend);
else
#endif
*reloc_addr = symbol_addr + rpnt->r_addend +
- tls_tpnt->l_tls_offset;
+ def_mod->l_tls_offset;
break;
#endif
-
+#endif
default:
return -1; /* Calls _dl_exit(1). */
}
#if defined (__SUPPORT_LD_DEBUG__)
if (_dl_debug_reloc && _dl_debug_detail)
- _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
+ _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %p\n",
old_val, *reloc_addr, reloc_addr);
#endif
@@ -275,7 +335,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
ElfW(Addr) old_val;
#endif
- reloc_addr = (ElfW(Addr) *) (tpnt->loadaddr + rpnt->r_offset);
+ reloc_addr = (ElfW(Addr) *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset);
reloc_type = ELF_R_TYPE (rpnt->r_info);
#if defined (__SUPPORT_LD_DEBUG__)
@@ -286,7 +346,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
case R_XTENSA_JMP_SLOT:
/* Perform a RELATIVE reloc on the GOT entry that transfers
to the stub function. */
- *reloc_addr += tpnt->loadaddr;
+ *reloc_addr = DL_RELOC_ADDR(tpnt->loadaddr, *reloc_addr);
break;
case R_XTENSA_NONE:
break;
@@ -296,7 +356,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope,
#if defined (__SUPPORT_LD_DEBUG__)
if (_dl_debug_reloc && _dl_debug_detail)
- _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
+ _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %p\n",
old_val, *reloc_addr, reloc_addr);
#endif
return 0;
@@ -320,3 +380,7 @@ _dl_parse_relocation_information (struct dyn_elf *rpnt,
return _dl_parse (rpnt->dyn, scope, rel_addr, rel_size,
_dl_do_reloc);
}
+
+#ifndef IS_IN_libdl
+# include "../../libc/sysdeps/linux/xtensa/crtreloc.c"
+#endif
diff --git a/libc/sysdeps/linux/xtensa/__start_context.S b/libc/sysdeps/linux/xtensa/__start_context.S
index a30d7b6188ad..e6ce93347d6d 100644
--- a/libc/sysdeps/linux/xtensa/__start_context.S
+++ b/libc/sysdeps/linux/xtensa/__start_context.S
@@ -22,9 +22,10 @@
* There's no entry instruction, makecontext sets up ucontext_t as if
* getcontext was called above and is about to return here.
* Registers on entry to this function:
- * a12: func to call
+ * a12: func to call (function descriptor in case of FDPIC)
* a13: ucp->uc_link, next context to activate if func returns
* a14: func argc
+ * a15: current GOT pointer (in case of FDPIC)
*/
.literal_position
@@ -46,14 +47,17 @@ ENTRY_PREFIX(__start_context)
addi a1, a1, 16
/* func arguments 6..argc - 1 are now at the top of the stack */
1:
+ FDPIC_LOAD_FUNCDESC (a12, a12)
callx0 a12
beqz a13, 1f
mov a2, a13
movi a4, JUMPTARGET (setcontext)
+ FDPIC_LOAD_JUMPTARGET (a4, a15, a4)
callx0 a4
1:
movi a4, JUMPTARGET (_exit)
movi a2, 0
+ FDPIC_LOAD_JUMPTARGET (a4, a15, a4)
callx0 a4
ill
END(__start_context)
diff --git a/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h b/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h
new file mode 100644
index 000000000000..19bb247b878e
--- /dev/null
+++ b/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h
@@ -0,0 +1,117 @@
+/* Copyright 2003, 2004 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 of the
+License, or (at your option) any later version.
+
+In addition to the permissions in the GNU Lesser General Public
+License, the Free Software Foundation gives you unlimited
+permission to link the compiled version of this file with other
+programs, and to distribute those programs without any restriction
+coming from the use of this file. (The GNU Lesser General Public
+License restrictions do apply in other respects; for example, they
+cover modification of the file, and distribution when not linked
+into another program.)
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_ELF_FDPIC_H
+#define _BITS_ELF_FDPIC_H
+
+/* These data structures are described in the FDPIC ABI extension.
+ The kernel passes a process a memory map, such that for every LOAD
+ segment there is an elf32_fdpic_loadseg entry. A pointer to an
+ elf32_fdpic_loadmap is passed in r7 at start-up, and a pointer to
+ an additional such map is passed in r8 for the interpreter, when
+ there is one. */
+
+#include <elf.h>
+
+/* This data structure represents a PT_LOAD segment. */
+struct elf32_fdpic_loadseg
+{
+ /* Core address to which the segment is mapped. */
+ Elf32_Addr addr;
+ /* VMA recorded in the program header. */
+ Elf32_Addr p_vaddr;
+ /* Size of this segment in memory. */
+ Elf32_Word p_memsz;
+};
+
+struct elf32_fdpic_loadmap {
+ /* Protocol version number, must be zero. */
+ Elf32_Half version;
+ /* Number of segments in this map. */
+ Elf32_Half nsegs;
+ /* The actual memory map. */
+ struct elf32_fdpic_loadseg segs[/*nsegs*/];
+};
+
+struct elf32_fdpic_loadaddr {
+ struct elf32_fdpic_loadmap *map;
+ void *got_value;
+};
+
+/* Map a pointer's VMA to its corresponding address according to the
+ load map. */
+static __always_inline void *
+__reloc_pointer (void *p,
+ const struct elf32_fdpic_loadmap *map)
+{
+ int c;
+
+#if 0
+ if (map->version != 0)
+ /* Crash. */
+ ((void(*)())0)();
+#endif
+
+ /* No special provision is made for NULL. We don't want NULL
+ addresses to go through relocation, so they shouldn't be in
+ .rofixup sections, and, if they're present in dynamic
+ relocations, they shall be mapped to the NULL address without
+ undergoing relocations. */
+
+ for (c = 0;
+ /* Take advantage of the fact that the loadmap is ordered by
+ virtual addresses. In general there will only be 2 entries,
+ so it's not profitable to do a binary search. */
+ c < map->nsegs && p >= (void*)map->segs[c].p_vaddr;
+ c++)
+ {
+ /* This should be computed as part of the pointer comparison
+ above, but we want to use the carry in the comparison, so we
+ can't convert it to an integer type beforehand. */
+ unsigned long offset = (char*)p - (char*)map->segs[c].p_vaddr;
+ /* We only check for one-past-the-end for the last segment,
+ assumed to be the data segment, because other cases are
+ ambiguous in the absence of padding between segments, and
+ rofixup already serves as padding between text and data.
+ Unfortunately, unless we special-case the last segment, we
+ fail to relocate the _end symbol. */
+ if (offset < map->segs[c].p_memsz
+ || (offset == map->segs[c].p_memsz && c + 1 == map->nsegs))
+ return (char*)map->segs[c].addr + offset;
+ }
+
+ /* We might want to crash instead. */
+ return (void*)-1;
+}
+
+# define __RELOC_POINTER(ptr, loadaddr) \
+ (__reloc_pointer ((void*)(ptr), \
+ (loadaddr).map))
+
+void*
+__self_reloc (const struct elf32_fdpic_loadmap *map, void ***p, void ***e);
+
+#endif /* _BITS_ELF_FDPIC_H */
diff --git a/libc/sysdeps/linux/xtensa/clone.S b/libc/sysdeps/linux/xtensa/clone.S
index ebfdcc1f65be..a11044cd0271 100644
--- a/libc/sysdeps/linux/xtensa/clone.S
+++ b/libc/sysdeps/linux/xtensa/clone.S
@@ -81,11 +81,17 @@ ENTRY (__clone)
callx4 a2
#elif defined(__XTENSA_CALL0_ABI__)
mov a2, a9 /* load up the 'arg' parameter */
+#ifdef __FDPIC__
+ mov a12, a11
+ l32i a11, a7, 4
+ l32i a7, a7, 0
+#endif
callx0 a7 /* call the user's function */
/* Call _exit. Note that any return parameter from the user's
function in a2 is seen as inputs to _exit. */
movi a0, JUMPTARGET(_exit)
+ FDPIC_LOAD_JUMPTARGET(a0, a12, a0)
callx0 a0
#else
#error Unsupported Xtensa ABI
diff --git a/libc/sysdeps/linux/xtensa/crt1.S b/libc/sysdeps/linux/xtensa/crt1.S
index 3fa14ae583a9..a12f82dd656b 100644
--- a/libc/sysdeps/linux/xtensa/crt1.S
+++ b/libc/sysdeps/linux/xtensa/crt1.S
@@ -35,6 +35,86 @@
#include <features.h>
+#if defined(__FDPIC__)
+
+/* This is the canonical entry point, usually the first thing in the text
+ segment. When the entry point runs, most register values are unspecified,
+ except for:
+
+ a6 Address of .dynamic section
+ a5 Interpreter map
+ a4 Executable map
+
+ a2 Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ a1 The stack (i.e., a1+16) contains the arguments and environment:
+ a1+0 argc
+ a1+4 argv[0]
+ ...
+ a1+(4*argc) NULL
+ a1+(4*(argc+1)) envp[0]
+ ...
+ NULL
+ */
+ .text
+ .align 4
+ .literal_position
+ .global _start
+ .type _start, @function
+_start:
+#if defined(__XTENSA_CALL0_ABI__)
+
+ .begin no-transform
+ call0 1f
+2:
+ .end no-transform
+ .align 4
+ .literal_position
+1:
+ movi a15, 2b
+ sub a15, a0, a15
+
+ mov a12, a4
+ mov a13, a5
+ mov a14, a6
+ mov a2, a4
+ movi a3, __ROFIXUP_LIST__
+ add a3, a3, a15
+ movi a4, __ROFIXUP_END__
+ add a4, a4, a15
+ movi a0, __self_reloc
+ add a0, a0, a15
+ callx0 a0
+
+ mov a11, a2
+ movi a2, main@GOTOFFFUNCDESC
+ add a2, a2, a11
+ l32i a3, sp, 0 /* argc */
+ addi a4, sp, 4 /* argv */
+ /* a5 is either 0 when static or set by the RTLD to the rtld_fini */
+ mov a7, a13
+ /* unused stack_end argument is what used to be argc */
+ movi a5, _init@GOTOFFFUNCDESC
+ add a5, a5, a11
+ movi a6, _fini@GOTOFFFUNCDESC
+ add a6, a6, a11
+
+ movi a0, __uClibc_main@GOTOFFFUNCDESC
+ add a0, a0, a11
+ l32i a11, a0, 4
+ l32i a0, a0, 0
+ callx0 a0
+ ill
+
+#else
+#error Unsupported Xtensa ABI
+#endif
+
+#else /* defined(__FDPIC__) */
+
#ifndef __UCLIBC_CTOR_DTOR__
.weak _init
.weak _fini
@@ -173,3 +253,4 @@ __data_start:
.long 0
.weak data_start
data_start = __data_start
+#endif /* defined(__FDPIC__) */
diff --git a/libc/sysdeps/linux/xtensa/crti.S b/libc/sysdeps/linux/xtensa/crti.S
index 43e66e30820b..2923ff09d0bb 100644
--- a/libc/sysdeps/linux/xtensa/crti.S
+++ b/libc/sysdeps/linux/xtensa/crti.S
@@ -11,6 +11,10 @@ _init:
#elif defined(__XTENSA_CALL0_ABI__)
addi sp, sp, -16
s32i a0, sp, 0
+#ifdef __FDPIC__
+ s32i a12, sp, 4
+ mov a12, a11
+#endif
#else
#error Unsupported Xtensa ABI
#endif
@@ -26,6 +30,10 @@ _fini:
#elif defined(__XTENSA_CALL0_ABI__)
addi sp, sp, -16
s32i a0, sp, 0
+#ifdef __FDPIC__
+ s32i a12, sp, 4
+ mov a12, a11
+#endif
#else
#error Unsupported Xtensa ABI
#endif
diff --git a/libc/sysdeps/linux/xtensa/crtn.S b/libc/sysdeps/linux/xtensa/crtn.S
index a3598da1a537..6f797e8bdd60 100644
--- a/libc/sysdeps/linux/xtensa/crtn.S
+++ b/libc/sysdeps/linux/xtensa/crtn.S
@@ -4,6 +4,9 @@
#if defined(__XTENSA_WINDOWED_ABI__)
retw
#elif defined(__XTENSA_CALL0_ABI__)
+#ifdef __FDPIC__
+ l32i a12, sp, 4
+#endif
l32i a0, sp, 0
addi sp, sp, 16
ret
@@ -15,6 +18,9 @@
#if defined(__XTENSA_WINDOWED_ABI__)
retw
#elif defined(__XTENSA_CALL0_ABI__)
+#ifdef __FDPIC__
+ l32i a12, sp, 4
+#endif
l32i a0, sp, 0
addi sp, sp, 16
ret
diff --git a/libc/sysdeps/linux/xtensa/crtreloc.c b/libc/sysdeps/linux/xtensa/crtreloc.c
new file mode 100644
index 000000000000..697ef91ab21f
--- /dev/null
+++ b/libc/sysdeps/linux/xtensa/crtreloc.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ written by Alexandre Oliva <aoliva(a)redhat.com>
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 of the
+License, or (at your option) any later version.
+
+In addition to the permissions in the GNU Lesser General Public
+License, the Free Software Foundation gives you unlimited
+permission to link the compiled version of this file with other
+programs, and to distribute those programs without any restriction
+coming from the use of this file. (The GNU Lesser General Public
+License restrictions do apply in other respects; for example, they
+cover modification of the file, and distribution when not linked
+into another program.)
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef __FDPIC__
+
+#include <sys/types.h>
+#include <link.h>
+
+/* This file is to be compiled into crt object files, to enable
+ executables to easily self-relocate. */
+
+/* Compute the runtime address of pointer in the range [p,e), and then
+ map the pointer pointed by it. */
+static __always_inline void ***
+reloc_range_indirect (void ***p, void ***e,
+ const struct elf32_fdpic_loadmap *map)
+{
+ while (p < e)
+ {
+ if (*p != (void **)-1)
+ {
+ void *ptr = __reloc_pointer (*p, map);
+
+ if (ptr != (void *)-1)
+ {
+ unsigned long off = ((unsigned long)ptr & 3) * 8;
+ unsigned long *pa = (unsigned long *)((unsigned long)ptr & -4);
+ unsigned long v2;
+ void *pt;
+
+ if (off)
+ {
+ unsigned long v0, v1;
+#ifdef __XTENSA_EB__
+ v0 = pa[1]; v1 = pa[0];
+ v2 = (v1 >> (32 - off)) | (v0 << off);
+#else /* __XTENSA_EL__ */
+ v0 = pa[0]; v1 = pa[1];
+ v2 = (v0 << (32 - off)) | (v1 >> off);
+#endif
+ pt = (void *)((v1 << (32 - off)) | (v0 >> off));
+ }
+ else
+ pt = *(void**)ptr;
+ pt = __reloc_pointer (pt, map);
+ if (off)
+ {
+ unsigned long v = (unsigned long)pt;
+#ifdef __XTENSA_EB__
+ pa[0] = (v2 << (32 - off)) | (v >> off);
+ pa[1] = (v << (32 - off)) | (v2 >> off);
+#else /* __XTENSA_EL__ */
+ pa[0] = (v2 >> (32 - off)) | (v << off);
+ pa[1] = (v >> (32 - off)) | (v2 << off);
+#endif
+ }
+ else
+ *(void**)ptr = pt;
+ }
+ }
+ p++;
+ }
+ return p;
+}
+
+/* Call __reloc_range_indirect for the given range except for the last
+ entry, whose contents are only relocated. It's expected to hold
+ the GOT value. */
+attribute_hidden void*
+__self_reloc (const struct elf32_fdpic_loadmap *map,
+ void ***p, void ***e)
+{
+ p = reloc_range_indirect (p, e-1, map);
+
+ if (p >= e)
+ return (void*)-1;
+
+ return __reloc_pointer (*p, map);
+}
+
+#endif /* __FDPIC__ */
diff --git a/libc/sysdeps/linux/xtensa/getcontext.S b/libc/sysdeps/linux/xtensa/getcontext.S
index 7588a91b33b3..4cc644552d42 100644
--- a/libc/sysdeps/linux/xtensa/getcontext.S
+++ b/libc/sysdeps/linux/xtensa/getcontext.S
@@ -33,6 +33,7 @@ ENTRY(__getcontext)
addi a4, a2, UCONTEXT_SIGMASK
movi a2, SIG_BLOCK
movi a5, JUMPTARGET (sigprocmask)
+ FDPIC_LOAD_JUMPTARGET (a5, a11, a5)
jx a5
END(__getcontext)
#elif defined(__XTENSA_WINDOWED_ABI__)
diff --git a/libc/sysdeps/linux/xtensa/makecontext.c b/libc/sysdeps/linux/xtensa/makecontext.c
index da26a0130325..0a8f7116fef2 100644
--- a/libc/sysdeps/linux/xtensa/makecontext.c
+++ b/libc/sysdeps/linux/xtensa/makecontext.c
@@ -73,7 +73,12 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
sp -= 4 * (argc + 2);
sp &= -16;
+#ifdef __FDPIC__
+ ucp->uc_mcontext.sc_pc = ((unsigned long *) __start_context)[0];
+ ucp->uc_mcontext.sc_a[15] = ((unsigned long *) __start_context)[1];
+#else
ucp->uc_mcontext.sc_pc = (unsigned long) __start_context;
+#endif
ucp->uc_mcontext.sc_a[1] = sp;
ucp->uc_mcontext.sc_a[12] = (unsigned long) func;
ucp->uc_mcontext.sc_a[13] = (unsigned long) ucp->uc_link;
diff --git a/libc/sysdeps/linux/xtensa/setcontext.S b/libc/sysdeps/linux/xtensa/setcontext.S
index 4df7cc049006..72915ef8d74e 100644
--- a/libc/sysdeps/linux/xtensa/setcontext.S
+++ b/libc/sysdeps/linux/xtensa/setcontext.S
@@ -28,6 +28,7 @@ ENTRY(__setcontext)
movi a4, 0
movi a2, SIG_SETMASK
movi a5, JUMPTARGET (sigprocmask)
+ FDPIC_LOAD_JUMPTARGET (a5, a11, a5)
callx0 a5
bnez a2, .Lerror
diff --git a/libc/sysdeps/linux/xtensa/setjmp.S b/libc/sysdeps/linux/xtensa/setjmp.S
index b8152fdd8bac..d629c11a8c41 100644
--- a/libc/sysdeps/linux/xtensa/setjmp.S
+++ b/libc/sysdeps/linux/xtensa/setjmp.S
@@ -155,7 +155,8 @@ ENTRY (__sigsetjmp)
s32i a14, a2, 16
s32i a15, a2, 20
mov a12, a2
- movi a0, __sigjmp_save
+ movi a0, JUMPTARGET(__sigjmp_save)
+ FDPIC_LOAD_JUMPTARGET(a0, a11, a0)
callx0 a0
l32i a0, a12, 0
l32i a12, a12, 8
diff --git a/libc/sysdeps/linux/xtensa/swapcontext.S b/libc/sysdeps/linux/xtensa/swapcontext.S
index a215edc6d54a..40b38e98ca01 100644
--- a/libc/sysdeps/linux/xtensa/swapcontext.S
+++ b/libc/sysdeps/linux/xtensa/swapcontext.S
@@ -36,6 +36,7 @@ ENTRY(__swapcontext)
addi a4, a2, UCONTEXT_SIGMASK
movi a2, SIG_SETMASK
movi a5, JUMPTARGET (sigprocmask)
+ FDPIC_LOAD_JUMPTARGET (a5, a11, a5)
callx0 a5
bnez a2, .Lerror
diff --git a/libc/sysdeps/linux/xtensa/sysdep.h b/libc/sysdeps/linux/xtensa/sysdep.h
index 80b3f30fcc5d..d05741027c07 100644
--- a/libc/sysdeps/linux/xtensa/sysdep.h
+++ b/libc/sysdeps/linux/xtensa/sysdep.h
@@ -75,13 +75,27 @@
#define LITERAL_POSITION .literal_position
#undef JUMPTARGET
-#ifdef __PIC__
+#if defined(__FDPIC__)
+#define JUMPTARGET(name) name##@GOTOFFFUNCDESC
+#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc) \
+ l32i a11, funcdesc, 4; \
+ l32i call_target, funcdesc, 0
+
+#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)\
+ add call_target, got_base, jumptarget; \
+ FDPIC_LOAD_FUNCDESC(call_target, call_target)
+
+#elif defined(__PIC__)
/* The "@PLT" suffix is currently a no-op for non-shared linking, but
it doesn't hurt to use it conditionally for PIC code in case that
changes someday. */
#define JUMPTARGET(name) name##@PLT
+#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc)
+#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)
#else
#define JUMPTARGET(name) name
+#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc)
+#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)
#endif
#ifndef FRAMESIZE
@@ -153,6 +167,21 @@
#if defined _LIBC_REENTRANT
# if defined USE___THREAD
+#ifdef __FDPIC__
+# define SYSCALL_ERROR_ERRNO errno
+# define SYSCALL_ERROR_HANDLER \
+0: rur a4, THREADPTR; \
+ movi a3, SYSCALL_ERROR_ERRNO@GOTTPOFF; \
+ .reloc ., R_XTENSA_TLS_TPOFF_PTR, SYSCALL_ERROR_ERRNO; \
+ add a3, a3, a11; \
+ .reloc ., R_XTENSA_TLS_TPOFF_LOAD, SYSCALL_ERROR_ERRNO; \
+ l32i a3, a3, 0; \
+ neg a2, a2; \
+ add a4, a4, a3; \
+ s32i a2, a4, 0; \
+ movi a2, -1; \
+ j .Lpseudo_end;
+#else
# define SYSCALL_ERROR_ERRNO errno
# define SYSCALL_ERROR_HANDLER \
0: rur a4, THREADPTR; \
@@ -162,13 +191,14 @@
s32i a2, a4, 0; \
movi a2, -1; \
j .Lpseudo_end;
+#endif
# else /* !USE___THREAD */
#if defined(__XTENSA_WINDOWED_ABI__)
# define SYSCALL_ERROR_HANDLER \
0: neg a2, a2; \
mov a6, a2; \
- movi a4, __errno_location@PLT; \
+ movi a4, JUMPTARGET(__errno_location); \
callx4 a4; \
s32i a2, a6, 0; \
movi a2, -1; \
@@ -179,7 +209,8 @@
addi a1, a1, -16; \
s32i a0, a1, 0; \
s32i a2, a1, 4; \
- movi a0, __errno_location@PLT; \
+ movi a0, JUMPTARGET(__errno_location); \
+ FDPIC_LOAD_JUMPTARGET(a0, a11, a0); \
callx0 a0; \
l32i a0, a1, 0; \
l32i a3, a1, 4; \
@@ -193,12 +224,23 @@
# endif /* !USE___THREAD */
#else /* !_LIBC_REENTRANT */
+#ifdef __FDPIC__
+#define SYSCALL_ERROR_HANDLER \
+0: movi a4, errno@GOT; \
+ add a4, a4, a11; \
+ l32i a4, a4, 0; \
+ neg a2, a2; \
+ s32i a2, a4, 0; \
+ movi a2, -1; \
+ j .Lpseudo_end;
+#else
#define SYSCALL_ERROR_HANDLER \
0: movi a4, errno; \
neg a2, a2; \
s32i a2, a4, 0; \
movi a2, -1; \
j .Lpseudo_end;
+#endif /* __FDPIC__ */
#endif /* _LIBC_REENTRANT */
#endif /* __ASSEMBLER__ */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch
index 6f17348713ad..a3719a3fb3af 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch
@@ -9,3 +9,5 @@ CFLAGS-OMIT-fork.c = -DNOT_IN_libc -DIS_IN_libpthread
ASFLAGS-syscall.S = -D_LIBC_REENTRANT
ASFLAGS-mmap.S = -D_LIBC_REENTRANT
+
+ASFLAGS += -DUSE___THREAD
diff --git a/libpthread/nptl/sysdeps/xtensa/dl-tls.h b/libpthread/nptl/sysdeps/xtensa/dl-tls.h
index adc02d74a55c..5fc4ea2d05c8 100644
--- a/libpthread/nptl/sysdeps/xtensa/dl-tls.h
+++ b/libpthread/nptl/sysdeps/xtensa/dl-tls.h
@@ -28,6 +28,29 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+/* Type used as the argument in a TLS descriptor for a symbol that
+ needs dynamic TLS offsets. */
+struct tlsdesc_dynamic_arg
+{
+ tls_index tlsinfo;
+ size_t gen_count;
+};
+
+#ifdef __FDPIC__
+/* Type used to represent a TLS descriptor. */
+struct tlsdesc
+{
+ ptrdiff_t (*entry)(struct tlsdesc *);
+ void *argument;
+};
+
+extern ptrdiff_t attribute_hidden
+ _dl_tlsdesc_return(struct tlsdesc *);
+
+extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
+extern ptrdiff_t attribute_hidden
+ _dl_tlsdesc_dynamic(struct tlsdesc *);
+#else
/* Type used to represent a TLS descriptor. */
struct tlsdesc
{
@@ -39,19 +62,11 @@ struct tlsdesc
ptrdiff_t (*entry)(struct tlsdesc *);
};
-/* Type used as the argument in a TLS descriptor for a symbol that
- needs dynamic TLS offsets. */
-struct tlsdesc_dynamic_arg
-{
- tls_index tlsinfo;
- size_t gen_count;
-};
-
extern ptrdiff_t attribute_hidden
_dl_tlsdesc_return(struct tlsdesc_dynamic_arg *);
extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
extern ptrdiff_t attribute_hidden
_dl_tlsdesc_dynamic(struct tlsdesc_dynamic_arg *);
-
+#endif
#endif
--
2.39.2
2
1
add two ioctls to get and set struct epoll_params to allow users to
control epoll based busy polling of network sockets.
added to uapi in commit 18e2bf0edf4dd88d9656ec92395aa47392e85b61 (Linux
kernel 6.9 and newer).
Signed-off-by: Joe Damato <jdamato(a)fastly.com>
---
libc/sysdeps/linux/common/sys/epoll.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/libc/sysdeps/linux/common/sys/epoll.h b/libc/sysdeps/linux/common/sys/epoll.h
index 5551bed0d..5138d77a9 100644
--- a/libc/sysdeps/linux/common/sys/epoll.h
+++ b/libc/sysdeps/linux/common/sys/epoll.h
@@ -19,6 +19,7 @@
#define _SYS_EPOLL_H 1
#include <stdint.h>
+#include <sys/ioctl.h>
#include <sys/types.h>
/* Get __sigset_t. */
@@ -87,6 +88,19 @@ struct epoll_event
epoll_data_t data; /* User data variable */
} __EPOLL_PACKED;
+struct epoll_params
+{
+ uint32_t busy_poll_usecs;
+ uint16_t busy_poll_budget;
+ uint8_t prefer_busy_poll;
+
+ /* pad the struct to a multiple of 64bits */
+ uint8_t __pad;
+};
+
+#define EPOLL_IOC_TYPE 0x8A
+#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params)
+#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params)
__BEGIN_DECLS
--
2.25.1
2
1
This series adds FDPIC ABI support as specified in the revision 1 of the
https://github.com/jcmvbkbc/xtensa-abi/blob/master/fdpic-xtensa.txt
This implementation conflicts with the changes made for ARM FDPIC and it
reverts the conflicting change. Reverting the corresponding change in
the gcc is required to keep the ARM FDPIC port functional.
Max Filippov (2):
xtensa: add FDPIC support
Revert "Allow to generate PIE 'static' binary"
Rules.mak | 4 +
extra/Configs/Config.in | 2 +-
extra/Configs/Config.in.arch | 2 +-
include/elf.h | 6 +-
ldso/ldso/xtensa/dl-inlines.h | 1 +
ldso/ldso/xtensa/dl-startup.h | 91 ++++++++++++++-
ldso/ldso/xtensa/dl-sysdep.h | 66 ++++++++++-
ldso/ldso/xtensa/dl-tlsdesc.S | 10 +-
ldso/ldso/xtensa/elfinterp.c | 114 ++++++++++++++-----
libc/misc/internals/__uClibc_main.c | 45 --------
libc/sysdeps/linux/xtensa/__start_context.S | 6 +-
libc/sysdeps/linux/xtensa/bits/elf-fdpic.h | 117 ++++++++++++++++++++
libc/sysdeps/linux/xtensa/clone.S | 6 +
libc/sysdeps/linux/xtensa/crt1.S | 81 ++++++++++++++
libc/sysdeps/linux/xtensa/crti.S | 8 ++
libc/sysdeps/linux/xtensa/crtn.S | 6 +
libc/sysdeps/linux/xtensa/crtreloc.c | 105 ++++++++++++++++++
libc/sysdeps/linux/xtensa/getcontext.S | 1 +
libc/sysdeps/linux/xtensa/makecontext.c | 5 +
libc/sysdeps/linux/xtensa/setcontext.S | 1 +
libc/sysdeps/linux/xtensa/setjmp.S | 3 +-
libc/sysdeps/linux/xtensa/swapcontext.S | 1 +
libc/sysdeps/linux/xtensa/sysdep.h | 48 +++++++-
libpthread/nptl/sysdeps/xtensa/dl-tls.h | 33 ++++--
24 files changed, 671 insertions(+), 91 deletions(-)
create mode 100644 ldso/ldso/xtensa/dl-inlines.h
create mode 100644 libc/sysdeps/linux/xtensa/bits/elf-fdpic.h
create mode 100644 libc/sysdeps/linux/xtensa/crtreloc.c
--
2.39.2
2
18