diff options
52 files changed, 913 insertions, 97 deletions
@@ -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 b814449b4..454b6ddb8 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -545,7 +545,7 @@ config LDSO_LD_LIBRARY_PATH If unsure, simply say Y here. config UCLIBC_CTOR_DTOR - bool + bool "Support global constructors and destructors" default y help If you wish to build uClibc with support for global constructor @@ -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. @@ -1028,6 +1028,7 @@ config UCLIBC_USE_TIME64 bool "Use *time64 syscalls instead of 32bit ones (if possible)" depends on TARGET_arc || \ TARGET_arm || \ + TARGET_csky || \ TARGET_i386 || \ TARGET_m68k || \ TARGET_microblaze || \ @@ -1039,8 +1040,7 @@ config UCLIBC_USE_TIME64 TARGET_sh || \ TARGET_xtensa # TODO: add support for other architectures - default y if TARGET_riscv32 - default n + default y help Replace 32bit syscalls to their 64/time64 analog if possible. diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch index 1ae5134b9..c13497893 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/extra/Configs/Config.nds32 b/extra/Configs/Config.nds32 index 8bac9e679..2ed6a32b7 100644 --- a/extra/Configs/Config.nds32 +++ b/extra/Configs/Config.nds32 @@ -11,6 +11,7 @@ config FORCE_OPTIONS_FOR_ARCH bool default y select ARCH_ANY_ENDIAN + select ARCH_HAS_DEPRECATED_SYSCALLS select ARCH_HAS_MMU select ARCH_HAS_UCONTEXT diff --git a/include/atomic.h b/include/atomic.h index 267aff5d5..3adcfbc5f 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -54,15 +54,15 @@ and following args. */ #define __atomic_val_bysize(pre, post, mem, ...) \ ({ \ - __typeof (*mem) __atg1_result; \ + __typeof ((__typeof (*(mem))) *(mem)) __atg1_result; \ if (sizeof (*mem) == 1) \ - __atg1_result = pre##_8_##post (mem, __VA_ARGS__); \ + __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_8_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 2) \ - __atg1_result = pre##_16_##post (mem, __VA_ARGS__); \ + __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_16_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 4) \ - __atg1_result = pre##_32_##post (mem, __VA_ARGS__); \ + __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_32_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 8) \ - __atg1_result = pre##_64_##post (mem, __VA_ARGS__); \ + __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_64_##post (mem, __VA_ARGS__); \ else \ abort (); \ __atg1_result; \ @@ -71,13 +71,13 @@ ({ \ int __atg2_result; \ if (sizeof (*mem) == 1) \ - __atg2_result = pre##_8_##post (mem, __VA_ARGS__); \ + __atg2_result = (int) pre##_8_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 2) \ - __atg2_result = pre##_16_##post (mem, __VA_ARGS__); \ + __atg2_result = (int) pre##_16_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 4) \ - __atg2_result = pre##_32_##post (mem, __VA_ARGS__); \ + __atg2_result = (int) pre##_32_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 8) \ - __atg2_result = pre##_64_##post (mem, __VA_ARGS__); \ + __atg2_result = (int) pre##_64_##post (mem, __VA_ARGS__); \ else \ abort (); \ __atg2_result; \ diff --git a/include/elf.h b/include/elf.h index c2efa9978..1e7c89615 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/include/net/ppp_defs.h b/include/net/ppp_defs.h index f8924c4f2..904d1933c 100644 --- a/include/net/ppp_defs.h +++ b/include/net/ppp_defs.h @@ -4,7 +4,7 @@ #define __need_time_t #include <time.h> -#include <asm/types.h> +#include <sys/types.h> #include <linux/ppp_defs.h> #endif /* net/ppp_defs.h */ diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c index 4c268356f..9c9a3e8ca 100644 --- a/ldso/ldso/arm/elfinterp.c +++ b/ldso/ldso/arm/elfinterp.c @@ -92,7 +92,7 @@ unsigned long _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_offet) *got_entry = funcval; #endif - return got_entry; + return (unsigned long)got_entry; } #else unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) @@ -362,7 +362,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, unsigned long reloc_value = *reloc_addr; if (symbol_addr) - reloc_value = (unsigned long) _dl_funcdesc_for(symbol_addr + reloc_value, sym_ref.tpnt->loadaddr.got_value); + reloc_value = (unsigned long) _dl_funcdesc_for((void *)(symbol_addr + reloc_value), sym_ref.tpnt->loadaddr.got_value); else /* Relocation against an undefined weak symbol: @@ -429,7 +429,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, { struct funcdesc_value *dst = (struct funcdesc_value *) reloc_addr; - dst->entry_point = DL_RELOC_ADDR(tpnt->loadaddr, dst->entry_point); + dst->entry_point = (void *)DL_RELOC_ADDR(tpnt->loadaddr, dst->entry_point); dst->got_value = tpnt->loadaddr.got_value; } break; diff --git a/ldso/ldso/xtensa/dl-inlines.h b/ldso/ldso/xtensa/dl-inlines.h new file mode 100644 index 000000000..8fdf6eb48 --- /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 c9350c0f2..2a453752a 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 6b908989a..5aa3e177f 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,17 +168,48 @@ 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--) + { Elf32_Addr *const reloc_addr = (Elf32_Addr *) (load_off + rpnt->r_offset); *reloc_addr += load_off + rpnt->r_addend; rpnt++; } } +#endif diff --git a/ldso/ldso/xtensa/dl-tlsdesc.S b/ldso/ldso/xtensa/dl-tlsdesc.S index 426f2180b..1a8eacff2 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 e38a02666..d97f23435 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/misc/internals/reloc_static_pie.c b/libc/misc/internals/reloc_static_pie.c index 81af7d666..cb2c4df87 100644 --- a/libc/misc/internals/reloc_static_pie.c +++ b/libc/misc/internals/reloc_static_pie.c @@ -21,7 +21,7 @@ #include <dl-elf.h> #include <ldso.h> -#if defined(__mips__) || defined(__xtensa__) +#if defined(__m68k__) || defined(__mips__) || defined(__xtensa__) #include <dl-startup.h> #endif diff --git a/libc/stdlib/malloc/memalign.c b/libc/stdlib/malloc/memalign.c index 665f20cfb..54f6dbc6c 100644 --- a/libc/stdlib/malloc/memalign.c +++ b/libc/stdlib/malloc/memalign.c @@ -11,6 +11,7 @@ * Written by Miles Bader <miles@gnu.org> */ +#include <errno.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> @@ -38,6 +39,11 @@ memalign (size_t alignment, size_t size) unsigned long tot_addr, tot_end_addr, addr, end_addr; struct heap_free_area **heap = &__malloc_heap; + if (unlikely(size > PTRDIFF_MAX)) { + __set_errno(ENOMEM); + return NULL; + } + /* Make SIZE something we like. */ size = HEAP_ADJUST_SIZE (size); diff --git a/libc/sysdeps/linux/aarch64/sys/ucontext.h b/libc/sysdeps/linux/aarch64/sys/ucontext.h index 5f75cbbf3..1a27f918b 100644 --- a/libc/sysdeps/linux/aarch64/sys/ucontext.h +++ b/libc/sysdeps/linux/aarch64/sys/ucontext.h @@ -45,10 +45,10 @@ typedef elf_fpregset_t fpregset_t; typedef struct sigcontext mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; __sigset_t uc_sigmask; unsigned char __reserved[128]; diff --git a/libc/sysdeps/linux/common-generic/bits/kernel_stat.h b/libc/sysdeps/linux/common-generic/bits/kernel_stat.h index 7a97bb4d7..e874a4a9f 100644 --- a/libc/sysdeps/linux/common-generic/bits/kernel_stat.h +++ b/libc/sysdeps/linux/common-generic/bits/kernel_stat.h @@ -18,7 +18,7 @@ * However that requires more #ifndef in relevant wrappers, * further uglifying them */ -#define kernel_stat64 stat +#define kernel_stat64 stat64 #endif /* _BITS_STAT_STRUCT_H */ diff --git a/libc/sysdeps/linux/common/not-cancel.h b/libc/sysdeps/linux/common/not-cancel.h index e4fb1d7fe..426edcc46 100644 --- a/libc/sysdeps/linux/common/not-cancel.h +++ b/libc/sysdeps/linux/common/not-cancel.h @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sysdep.h> +#include <time.h> #ifdef NOT_IN_libc @@ -114,6 +115,7 @@ extern __typeof(pause) __pause_nocancel; # define nanosleep_not_cancel(requested_time, remaining) \ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining) #else +extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining); # define nanosleep_not_cancel(requested_time, remaining) \ __nanosleep_nocancel (requested_time, remaining) #endif 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 diff --git a/libc/sysdeps/linux/common/utime.c b/libc/sysdeps/linux/common/utime.c index e4ac0b269..c716388e8 100644 --- a/libc/sysdeps/linux/common/utime.c +++ b/libc/sysdeps/linux/common/utime.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <utime.h> -#if defined __NR_utimensat && !defined __NR_utime +#if (defined(__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utime # include <fcntl.h> # include <stddef.h> @@ -51,7 +51,7 @@ int utime(const char *file, const struct utimbuf *times) } #endif -#if (defined __NR_utimensat && !defined __NR_utime) || \ +#if ((defined(__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utime) || \ defined __NR_utime || defined __NR_utimes libc_hidden_def(utime) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index fa6f90e55..5816c7890 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -8,6 +8,7 @@ #include <sys/syscall.h> #include <sys/stat.h> +#include <stdint.h> #if defined(__UCLIBC_USE_TIME64__) #include "internal/time64_helpers.h" @@ -28,7 +29,7 @@ int utimensat(int fd, const char *path, const struct timespec times[2], int flag } }; - return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? (uintptr_t) &__times64 : 0, flags); } #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) diff --git a/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h b/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h index 3f5dab80c..1b866cb90 100644 --- a/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h +++ b/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h @@ -17,9 +17,6 @@ /* can your target use syscall6() for mmap ? */ #undef __UCLIBC_MMAP_HAS_6_ARGS__ -/* does your target use statx */ -#define __UCLIBC_HAVE_STATX__ - #ifdef __CSKYABIV2__ #undef __UCLIBC_SYSCALL_ALIGN_64BIT__ #else diff --git a/libc/sysdeps/linux/m68k/clone.S b/libc/sysdeps/linux/m68k/clone.S index 24071235b..a83d90a98 100644 --- a/libc/sysdeps/linux/m68k/clone.S +++ b/libc/sysdeps/linux/m68k/clone.S @@ -35,12 +35,14 @@ __clone: /* Sanity check arguments. */ - movel #-EINVAL, %d0 - movel 4(%sp), %a0 /* no NULL function pointers */ - tstl %a0 + movel #-EINVAL, %d0 + movel 4(%sp), %d1 /* no NULL function pointers */ + movel %d1, %a0 + tstl %d1 beq.w __syscall_error_trampoline - movel 8(%sp), %a1 /* no NULL stack pointers */ - tstl %a1 + movel 8(%sp), %d1 /* no NULL stack pointers */ + movel %d1, %a1 + tstl %d1 beq.w __syscall_error_trampoline /* Allocate space and copy the argument onto the new stack. */ diff --git a/libc/sysdeps/linux/nds32/Makefile.arch b/libc/sysdeps/linux/nds32/Makefile.arch index c7627b847..caf163844 100644 --- a/libc/sysdeps/linux/nds32/Makefile.arch +++ b/libc/sysdeps/linux/nds32/Makefile.arch @@ -2,6 +2,6 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. CSRC-y := brk.c prctl.c mremap.c -SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S sysdep.S +SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S vfork.S sysdep.S CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c swapcontext.c SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S diff --git a/libc/sysdeps/linux/nds32/bits/kernel_types.h b/libc/sysdeps/linux/nds32/bits/kernel_types.h index 6b142d2e5..1b6ae4d1b 100644 --- a/libc/sysdeps/linux/nds32/bits/kernel_types.h +++ b/libc/sysdeps/linux/nds32/bits/kernel_types.h @@ -14,13 +14,13 @@ typedef unsigned short __kernel_dev_t; typedef unsigned long __kernel_ino_t; -typedef unsigned int __kernel_mode_t; +typedef unsigned short __kernel_mode_t; typedef unsigned short __kernel_nlink_t; typedef long __kernel_off_t; typedef int __kernel_pid_t; -typedef int __kernel_ipc_pid_t; -typedef unsigned int __kernel_uid_t; -typedef unsigned int __kernel_gid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; @@ -34,11 +34,19 @@ typedef unsigned short __kernel_gid16_t; typedef unsigned int __kernel_uid32_t; typedef unsigned int __kernel_gid32_t; -typedef __kernel_uid_t __kernel_old_uid_t; -typedef __kernel_gid_t __kernel_old_gid_t; -typedef unsigned int __kernel_old_dev_t; +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef __kernel_dev_t __kernel_old_dev_t; typedef long __kernel_long_t; typedef unsigned long __kernel_ulong_t; __extension__ typedef long long __kernel_loff_t; +typedef struct { +#ifdef __USE_ALL + int val[2]; +#else + int __val[2]; +#endif +} __kernel_fsid_t; + #endif /* __ARCH_NDS32_POSIX_TYPES_H */ diff --git a/libc/sysdeps/linux/nds32/bits/syscalls.h b/libc/sysdeps/linux/nds32/bits/syscalls.h index 50e30db7d..a5cdda18a 100644 --- a/libc/sysdeps/linux/nds32/bits/syscalls.h +++ b/libc/sysdeps/linux/nds32/bits/syscalls.h @@ -37,7 +37,8 @@ #define Y(x) X(x) #define LIB_SYSCALL __NR_syscall -#define __issue_syscall(syscall_name) "syscall 0x0;\n" +#define __issue_syscall(syscall_name) \ +" syscall " Y(syscall_name) "; \n" #undef INTERNAL_SYSCALL_ERROR_P #define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (val) >= 0xfffff001u) diff --git a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h index 8499e99b4..5b85f4d23 100644 --- a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h +++ b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h @@ -20,7 +20,7 @@ static inline uintptr_t __attribute__ ((unused)) _jmpbuf_sp (__jmp_buf regs) { - uintptr_t sp = &(regs)[0].__regs[__JMP_BUF_SP]; + uintptr_t sp = (uintptr_t) &(regs)[0].__regs[__JMP_BUF_SP]; return sp; } diff --git a/libc/sysdeps/linux/nds32/sys/ucontext.h b/libc/sysdeps/linux/nds32/sys/ucontext.h index ea86a3ad0..0d7422aab 100644 --- a/libc/sysdeps/linux/nds32/sys/ucontext.h +++ b/libc/sysdeps/linux/nds32/sys/ucontext.h @@ -36,10 +36,10 @@ typedef struct sigcontext mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { - unsigned long int __uc_flags; - struct ucontext_t *uc_link; + unsigned long int uc_flags; + struct ucontext *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; __sigset_t uc_sigmask; diff --git a/libc/sysdeps/linux/nds32/vfork.S b/libc/sysdeps/linux/nds32/vfork.S new file mode 100644 index 000000000..ab32135fc --- /dev/null +++ b/libc/sysdeps/linux/nds32/vfork.S @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2016-2017 Andes Technology, Inc. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. + Contributed by Philip Blundell <philb@gnu.org>. + + 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. + + 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 + Lesser 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; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ + +ENTRY (__vfork) +#ifdef PIC +.pic +#endif + +#ifdef __NR_vfork + syscall __NR_vfork + bltz $r0, 2f +1: + ret +2: + sltsi $r1, $r0, -4096 + bnez $r1, 1b; + +# ifdef __ASSUME_VFORK_SYSCALL +# ifdef PIC + pushm $gp, $lp + cfi_adjust_cfa_offset(8) + cfi_rel_offset(gp, 0) + cfi_rel_offset(lp, 4) + mfusr $r15, $PC + sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4) + ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8) + add $gp, $gp, $r15 + + ! r15=C_SYMBOL_NAME(__syscall_error)@PLT + sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT) + ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT) + add $r15, $r15, $gp + + ! jump to SYSCALL_ERROR + jral $r15 + popm $gp, $lp + cfi_adjust_cfa_offset(-8) + cfi_restore(lp) + cfi_restore(gp) + ret +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +# else + /* Check if vfork syscall is known at all. */ + li $r1, -ENOSYS + beq $r0, $r1, 1f + +# ifdef PIC +3: + pushm $gp, $lp + cfi_adjust_cfa_offset(8) + cfi_rel_offset(gp, 0) + cfi_rel_offset(lp, 4) + mfusr $r15, $PC + sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4) + ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8) + add $gp, $gp, $r15 + + ! r15=C_SYMBOL_NAME(__syscall_error)@PLT + sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT) + ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT) + add $r15, $r15, $gp + + ! jump to SYSCALL_ERROR + jral $r15 + popm $gp, $lp + cfi_adjust_cfa_offset(-8) + cfi_restore(lp) + cfi_restore(gp) + ret +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +1: +# endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL + /* If we don't have vfork, fork is close enough. */ + syscall __NR_fork + bgez $r0, 1f + sltsi $r1, $r0, -4096 + bnez $r1, 1f + +# ifdef PIC + b 3b +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +1: + ret + +#elif !defined __NR_vfork +# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined" +#endif + +PSEUDO_END (__vfork) +weak_alias (__vfork, vfork) +libc_hidden_def (vfork) diff --git a/libc/sysdeps/linux/riscv32/sys/ucontext.h b/libc/sysdeps/linux/riscv32/sys/ucontext.h index 2893ff359..308ccb8c2 100644 --- a/libc/sysdeps/linux/riscv32/sys/ucontext.h +++ b/libc/sysdeps/linux/riscv32/sys/ucontext.h @@ -83,10 +83,10 @@ typedef struct mcontext_t } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; sigset_t uc_sigmask; /* There's some padding here to allow sigset_t to be expanded in the diff --git a/libc/sysdeps/linux/riscv64/sys/ucontext.h b/libc/sysdeps/linux/riscv64/sys/ucontext.h index 2893ff359..308ccb8c2 100644 --- a/libc/sysdeps/linux/riscv64/sys/ucontext.h +++ b/libc/sysdeps/linux/riscv64/sys/ucontext.h @@ -83,10 +83,10 @@ typedef struct mcontext_t } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; sigset_t uc_sigmask; /* There's some padding here to allow sigset_t to be expanded in the diff --git a/libc/sysdeps/linux/tile/sys/ucontext.h b/libc/sysdeps/linux/tile/sys/ucontext.h index ed2c27b58..068da8c4a 100644 --- a/libc/sysdeps/linux/tile/sys/ucontext.h +++ b/libc/sysdeps/linux/tile/sys/ucontext.h @@ -82,10 +82,10 @@ typedef struct } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __ctx(uc_flags); - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; sigset_t uc_sigmask; diff --git a/libc/sysdeps/linux/xtensa/__start_context.S b/libc/sysdeps/linux/xtensa/__start_context.S index a30d7b618..e6ce93347 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 000000000..19bb247b8 --- /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/bits/xtensa-config.h b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h index b99928b1e..bfcd571d2 100644 --- a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h +++ b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h @@ -32,21 +32,41 @@ macros. */ #undef XCHAL_HAVE_NSA +#ifdef __XCHAL_HAVE_NSA +#define XCHAL_HAVE_NSA __XCHAL_HAVE_NSA +#else #define XCHAL_HAVE_NSA 1 +#endif #undef XCHAL_HAVE_LOOPS +#ifdef __XCHAL_HAVE_LOOPS +#define XCHAL_HAVE_LOOPS __XCHAL_HAVE_LOOPS +#else #define XCHAL_HAVE_LOOPS 1 +#endif /* Assume the maximum number of AR registers. This currently only affects the __window_spill function, and it is always safe to flush extra. */ #undef XCHAL_NUM_AREGS +#ifdef __XCHAL_NUM_AREGS +#define XCHAL_NUM_AREGS __XCHAL_NUM_AREGS +#else #define XCHAL_NUM_AREGS 64 +#endif #undef XCHAL_HAVE_S32C1I +#ifdef __XCHAL_HAVE_S32C1I +#define XCHAL_HAVE_S32C1I __XCHAL_HAVE_S32C1I +#else #define XCHAL_HAVE_S32C1I 1 +#endif #undef XCHAL_HAVE_EXCLUSIVE +#ifdef __XCHAL_HAVE_EXCLUSIVE +#define XCHAL_HAVE_EXCLUSIVE __XCHAL_HAVE_EXCLUSIVE +#else #define XCHAL_HAVE_EXCLUSIVE 0 +#endif #endif /* !XTENSA_CONFIG_H */ diff --git a/libc/sysdeps/linux/xtensa/clone.S b/libc/sysdeps/linux/xtensa/clone.S index ebfdcc1f6..a11044cd0 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 3fa14ae58..a12f82dd6 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 ba804eb45..2923ff09d 100644 --- a/libc/sysdeps/linux/xtensa/crti.S +++ b/libc/sysdeps/linux/xtensa/crti.S @@ -3,6 +3,7 @@ .section .init .align 4 .global _init + .hidden _init .type _init, @function _init: #if defined(__XTENSA_WINDOWED_ABI__) @@ -10,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 @@ -17,6 +22,7 @@ _init: .section .fini .align 4 .global _fini + .hidden _fini .type _fini, @function _fini: #if defined(__XTENSA_WINDOWED_ABI__) @@ -24,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 a3598da1a..6f797e8bd 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 000000000..697ef91ab --- /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@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 7588a91b3..4cc644552 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 da26a0130..0a8f7116f 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 4df7cc049..72915ef8d 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 b8152fdd8..d629c11a8 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 a215edc6d..40b38e98c 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 80b3f30fc..d05741027 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/linuxthreads/Makefile.in b/libpthread/linuxthreads/Makefile.in index ffdd5d4eb..cc2a5f285 100644 --- a/libpthread/linuxthreads/Makefile.in +++ b/libpthread/linuxthreads/Makefile.in @@ -16,6 +16,8 @@ libpthread_OUT := $(top_builddir)libpthread/linuxthreads -include $(libpthread_DIR)/sysdeps/$(TARGET_ARCH)/Makefile.arch +CFLAGS-signals.c = -fexceptions -fasynchronous-unwind-tables + libpthread_SRC := \ attr.c cancel.c condvar.c errno.c events.c join.c lockfile.c manager.c \ mutex.c pt-machine.c ptfork.c pthread.c ptlongjmp.c \ diff --git a/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h b/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h index bbdb0739c..6d7c4d70a 100644 --- a/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h +++ b/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sysdep.h> +#include <time.h> /* Uncancelable open. */ #if defined __NR_openat && !defined __NR_open @@ -104,6 +105,7 @@ extern int __openat64_nocancel (int fd, const char *fname, int oflag, # define nanosleep_not_cancel(requested_time, remaining) \ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining) #else +extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining); # define nanosleep_not_cancel(requested_time, remaining) \ __nanosleep_nocancel (requested_time, remaining) #endif diff --git a/libpthread/nptl/sysdeps/nds32/dl-tls.h b/libpthread/nptl/sysdeps/nds32/dl-tls.h index 3b11e7f42..f0107cacb 100644 --- a/libpthread/nptl/sysdeps/nds32/dl-tls.h +++ b/libpthread/nptl/sysdeps/nds32/dl-tls.h @@ -50,7 +50,7 @@ struct tlsdesc_dynamic_arg extern void *__tls_get_addr (tls_index *ti); extern ptrdiff_t attribute_hidden - _dl_tlsdesc_return(struct tlsdesc_dynamic_arg *); + _dl_tlsdesc_return(struct tlsdesc *); extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset); extern ptrdiff_t attribute_hidden diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h index bbdb0739c..6d7c4d70a 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sysdep.h> +#include <time.h> /* Uncancelable open. */ #if defined __NR_openat && !defined __NR_open @@ -104,6 +105,7 @@ extern int __openat64_nocancel (int fd, const char *fname, int oflag, # define nanosleep_not_cancel(requested_time, remaining) \ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining) #else +extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining); # define nanosleep_not_cancel(requested_time, remaining) \ __nanosleep_nocancel (requested_time, remaining) #endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch index 6f1734871..a3719a3fb 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 adc02d74a..5fc4ea2d0 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 |