diff options
author | Roland McGrath <roland@hack.frob.com> | 2015-04-17 09:02:19 -0700 |
---|---|---|
committer | Roland McGrath <roland@hack.frob.com> | 2015-04-17 09:02:19 -0700 |
commit | d1e44df1fa5fefd8a083f6c1e909bbcdc97c6438 (patch) | |
tree | a76176eca62c0907dd7f135979312c8e55ad06a5 | |
parent | f70925993ada98039250d46c62fb89c168b8f9d6 (diff) | |
download | glibc-d1e44df1fa5fefd8a083f6c1e909bbcdc97c6438.zip glibc-d1e44df1fa5fefd8a083f6c1e909bbcdc97c6438.tar.gz glibc-d1e44df1fa5fefd8a083f6c1e909bbcdc97c6438.tar.bz2 |
Add arm-nacl port.
127 files changed, 5120 insertions, 0 deletions
@@ -1,3 +1,10 @@ +2015-04-17 Roland McGrath <roland@hack.frob.com> + + Add preliminary port to Google Native Client on ARM. + * abi-tags (.*-.*-nacl.*): New entry. + * sysdeps/arm/nacl: New directory. + * sysdeps/nacl: New directory. + 2015-04-16 David S. Miller <davem@davemloft.net> * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Make use of @@ -28,5 +28,7 @@ .*-.*-syllable.* 5 2.0.0 # just an arbitrary value +.*-.*-nacl.* 6 42.0.0 # earliest compatible Chromium version + # There is no catch-all default here because every supported OS that uses # ELF must have its own unique ABI tag. diff --git a/sysdeps/arm/nacl/Implies b/sysdeps/arm/nacl/Implies new file mode 100644 index 0000000..2294208 --- /dev/null +++ b/sysdeps/arm/nacl/Implies @@ -0,0 +1,2 @@ +arm/nptl +init_array diff --git a/sysdeps/arm/nacl/Makefile b/sysdeps/arm/nacl/Makefile new file mode 100644 index 0000000..c922659 --- /dev/null +++ b/sysdeps/arm/nacl/Makefile @@ -0,0 +1,33 @@ +# Makefile fragment for ARM/NaCl configurations. + +# Copyright (C) 2015 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. + +# 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, see +# <http://www.gnu.org/licenses/>. + +# sysdeps/nacl/Makefile needs this set to the architecture suffix used in +# the NaCl SDK. +nacl-sdk-arch = arm + +# We don't really support TLSDESC, even though the compiler thinks it does. +have-arm-tls-desc = no + +ifeq ($(subdir),csu) +sysdep_routines += aeabi_read_tp +endif + +ifeq ($(subdir),elf) +sysdep-rtld-routines += aeabi_read_tp +endif diff --git a/sysdeps/arm/nacl/____longjmp_chk.S b/sysdeps/arm/nacl/____longjmp_chk.S new file mode 100644 index 0000000..f950f17 --- /dev/null +++ b/sysdeps/arm/nacl/____longjmp_chk.S @@ -0,0 +1,47 @@ +/* longjmp that validates stack addresses. ARM/NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + + .section .rodata.str1.1,"aMS",%progbits,1 + .type longjmp_msg,%object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + + .text + +/* We don't have sigaltstack and so any longjmp must be to an outer frame. */ +.macro check_sp reg + cmp sp, \reg + bls .Lok +#ifdef PIC + movw r0, #:lower16:longjmp_msg-(.LPIC0+8) + movt r0, #:upper16:longjmp_msg-(.LPIC0+8) +.LPIC0: add r0, r0, pc +#else + movw r0, #:lower16:longjmp_msg + movt r0, #:upper16:longjmp_msg +#endif + b HIDDEN_JUMPTARGET(__fortify_fail) +.Lok: +.endm + +#define CHECK_SP(reg) check_sp reg +#define __longjmp ____longjmp_chk +#include <__longjmp.S> diff --git a/sysdeps/arm/nacl/aeabi_read_tp.S b/sysdeps/arm/nacl/aeabi_read_tp.S new file mode 100644 index 0000000..153e6db --- /dev/null +++ b/sysdeps/arm/nacl/aeabi_read_tp.S @@ -0,0 +1,44 @@ +/* ARM EABI helper function for reading the thread pointer. NaCl version. + Copyright (C) 2015 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* GCC will emit calls to this routine under -mtp=soft. */ + + .hidden __aeabi_read_tp +ENTRY (__aeabi_read_tp) + ldr r0, [r9] + sfi_bx lr +END (__aeabi_read_tp) diff --git a/sysdeps/arm/nacl/arm-features.h b/sysdeps/arm/nacl/arm-features.h new file mode 100644 index 0000000..b00cfdb --- /dev/null +++ b/sysdeps/arm/nacl/arm-features.h @@ -0,0 +1,43 @@ +/* Macros to test for CPU features on ARM. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _NACL_ARM_FEATURES_H +#define _NACL_ARM_FEATURES_H 1 + +#ifdef __SOFTFP__ +# error NaCl should always have VFP enabled +#endif + +/* NaCl does not support iWMMXt at all. */ +#define ARM_ASSUME_NO_IWMMXT 1 + +/* NaCl does not allow instructions to target the pc register. */ +#define ARM_ALWAYS_BX 1 + +/* Computed branch targets must be bundle-aligned, which is to 16 bytes. */ +#define ARM_BX_ALIGN_LOG2 4 + +/* Two-register addressing modes are never allowed. */ +#define ARM_NO_INDEX_REGISTER 1 + +/* Only ARM mode code is allowed, never Thumb mode. */ +#define NO_THUMB + +#include_next <arm-features.h> + +#endif /* arm-features.h */ diff --git a/sysdeps/arm/nacl/dl-machine.h b/sysdeps/arm/nacl/dl-machine.h new file mode 100644 index 0000000..81f3755 --- /dev/null +++ b/sysdeps/arm/nacl/dl-machine.h @@ -0,0 +1,53 @@ +/* Machine-dependent ELF dynamic relocation inline functions. ARM/NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef dl_machine_h + +/* This is only needed for handling TEXTRELs and NaCl will never + support TEXTRELs at all. */ +#define CLEAR_CACHE(start, end) __builtin_trap () + +#endif + +/* The rest is just machine-specific. + This #include is outside the #ifndef because the parts of + dl-machine.h used only by dynamic-link.h are outside the guard. */ +#include <sysdeps/arm/dl-machine.h> + +#ifdef dl_machine_h + +/* Initial entry point code for the dynamic linker. + The C function `_dl_start' is the real entry point; + its return value is the user program's entry point. */ +#undef RTLD_START +#define RTLD_START asm ("\ +.text\n\ +.globl _start\n\ +.type _start, %function\n\ +.p2align 4\n\ +_start:\n\ + @ r0 has the pointer to the info block (see nacl_startup.h)\n\ + mov r1, sp @ Save stack base for __libc_stack_end.\n\ + push {r0-r3} @ Push those, maintaining alignment to 16.\n\ + mov r0, sp @ Pointer to {info, sp} is argument.\n\ + sfi_bl _dl_start\n\ + pop {r1-r4} @ Restore stack, getting info block into r1.\n\ + mov lr, #0 @ Return address for noreturn call.\n\ + b _dl_start_user"); + +#endif diff --git a/sysdeps/arm/nacl/dl-trampoline.S b/sysdeps/arm/nacl/dl-trampoline.S new file mode 100644 index 0000000..47bc0ca --- /dev/null +++ b/sysdeps/arm/nacl/dl-trampoline.S @@ -0,0 +1,278 @@ +/* PLT trampolines. ARM/NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + + .syntax unified + .text + +@ Change &GOT[n+3] into 8*n. Note relocs are 8 bytes each. +.macro compute_reloc_arg pltgot, got2 + sub r1, \pltgot, \got2 @ r1 = &GOT[n+3] - &GOT[2] = 4*(n-1) + sub r1, r1, #4 @ r1 = 4*n + add r1, r1, r1 @ r1 *= 2 = 8*n +.endm + + CFI_SECTIONS + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, %function + .p2align 4 +_dl_runtime_resolve: + cfi_startproc + cfi_adjust_cfa_offset (8) + + @ We get called with: + @ lr contains the return address from this call + @ stack[1] contains &GOT[n+3] (pointer to function) + @ stack[0] points to &GOT[2] + + ldr ip, [sp] @ ip gets &GOT[2] + + @ Save the argument registers and the return address. + @ r4 doesn't need to be saved, but it makes the total + @ adjustment to sp (including the two words pushed by + @ the PLT code) an even eight words, so sp stays aligned. + push {r0-r4, lr} + cfi_adjust_cfa_offset (24) + cfi_rel_offset (r0, 0) + cfi_rel_offset (r1, 4) + cfi_rel_offset (r2, 8) + cfi_rel_offset (r3, 12) + cfi_rel_offset (r4, 16) + cfi_rel_offset (lr, 20) + + ldr r1, [sp, #28] @ r1 gets &GOT[n+3] + + @ Get the 'struct link_map *' for the first argument to _dl_fixup. + sfi_breg ip, ldr r0, [\B, #-4] + + @ Get the reloc offset for the second argument to _dl_fixup. + compute_reloc_arg r1, ip + + @ This does the real work, and returns the real call target. + sfi_bl _dl_fixup + mov ip, r0 + + @ Restore the saved registers. + pop {r0-r4, lr} + cfi_adjust_cfa_offset (-24) + cfi_restore (r0) + cfi_restore (r1) + cfi_restore (r2) + cfi_restore (r3) + cfi_restore (r4) + cfi_restore (lr) + + @ Now compensate for the two words pushed by the PLT code. + sfi_sp add sp, #8 + cfi_adjust_cfa_offset (-8) + + @ Finally, jump to the newfound call target. + sfi_bx ip + + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + +#ifndef PROF + .globl _dl_runtime_profile + .type _dl_runtime_profile, #function + .p2align 4 +_dl_runtime_profile: + cfi_startproc + cfi_adjust_cfa_offset (8) + + @ We get called with: + @ lr contains the return address from this call + @ stack[1] contains &GOT[n+3] (pointer to function) + @ stack[0] points to &GOT[2] + + @ Stack layout: + @ sp + 204 framesize returned from pltenter + @ sp + 12 La_arm_regs + @ sp + 4 Saved two arguments to _dl_profile_fixup + @ sp + 0 outgoing argument to _dl_profile_fixup + @ For now, we only save the general purpose registers. +# define PLTEXIT_ARGS 4 +# define LA_ARM_REGS (PLTEXIT_ARGS + 8) +# define LA_ARM_REGS_SIZE (4 * (4 + 1 + 1 + 42)) +# define PLTENTER_FRAMESIZE (LA_ARM_REGS + LA_ARM_REGS_SIZE) +# define FRAMESIZE (((PLTENTER_FRAMESIZE + 4) + 15) & -16) + + @ The NaCl ABI requires that sp be aligned to 16 bytes at call + @ sites. Assuming that was met on entry to the PLT, sp is + @ now exactly 8 bytes misaligned. + sfi_sp sub sp, #(FRAMESIZE - 8) + cfi_def_cfa_offset (FRAMESIZE) + + @ Store the argument registers in La_arm_regs. + strd r0, r1, [sp, #LA_ARM_REGS] + cfi_offset (r0, LA_ARM_REGS + 0) + cfi_offset (r1, LA_ARM_REGS + 4) + strd r2, r3, [sp, #(LA_ARM_REGS + 8)] + cfi_offset (r2, LA_ARM_REGS + 8) + cfi_offset (r3, LA_ARM_REGS + 12) + + ldr ip, [sp, #(FRAMESIZE - 8)] @ ip gets &GOT[2] + ldr r3, [sp, #(FRAMESIZE - 4)] @ r3 gets &GOT[n+3] + + @ Recover the incoming sp and lr and save those in La_arm_regs. + add r0, sp, #FRAMESIZE + mov r1, lr + strd r0, r1, [sp, #(LA_ARM_REGS + 16)] + cfi_offset (sp, LA_ARM_REGS + 16) + cfi_offset (lr, LA_ARM_REGS + 20) + + @ Get the 'struct link_map *' for the first arg to _dl_profile_fixup. + sfi_breg ip, ldr r0, [\B, #-4] + + @ Get the reloc offset for the second argument to _dl_profile_fixup. + compute_reloc_arg r3, ip + + @ The third argument is the original return address, still in lr. + mov r2, lr + + @ Compute the fourth argument, the La_arm_regs pointer. + add r3, sp, #PLTEXIT_ARGS + + @ Compute the fifth argument, the address of the 'framesize' + @ out parameter, and store it at the top of the stack. + add ip, sp, #PLTENTER_FRAMESIZE + str ip, [sp] + + @ Save away the first two arguments, which we will need + @ again for _dl_call_pltexit, below. + strd r0, r1, [sp, #PLTEXIT_ARGS] + + @ This does the real work, and returns the real call target. + sfi_bl _dl_profile_fixup + + @ The address to call is now in r0. + + @ Check whether we're wrapping this function, + @ i.e. if the framesize out parameter is >= 0. + ldr ip, [sp, #PLTENTER_FRAMESIZE] + cmp ip, #0 + bge 1f + cfi_remember_state + + @ Save _dl_profile_fixup's return value: the real call target. + mov ip, r0 + + @ Restore the registers from the La_arm_regs (perhaps as modified + @ by audit modules' pltenter functions). + add r1, sp, #LA_ARM_REGS + sfi_sp sfi_breg r1, ldmia \B, {r0-r3, sp, lr} + cfi_def_cfa_offset (0) + cfi_restore (r0) + cfi_restore (r1) + cfi_restore (r2) + cfi_restore (r3) + cfi_restore (sp) + cfi_restore (lr) + + @ Finally, jump to the newfound call target. + sfi_bx ip + +1: cfi_restore_state + @ The new frame size is in ip. + + @ Save the fp in the stack slot previously used for the fifth + @ argument to _dl_profile_fixup. + str fp, [sp] + cfi_offset (fp, 0) + + @ Save the result of _dl_profile_fixup, the real call target. + @ We'll reuse the stack slot just used for the 'framesize' + @ out parameter to _dl_profile_fixup. + str r0, [sp, #PLTENTER_FRAMESIZE] + + @ Stack layout: + @ fp + 264 call target + @ fp + 72 La_arm_regs + @ fp + 68 Saved two arguments to _dl_profile_fixup + @ fp + 64 saved fp + @ fp + 0 La_arm_retval + @ sp..fp copied incoming stack space (plus alignment) + @ For now, we only save the general purpose registers. +# define FP_LA_ARM_RETVAL 0 +# define LA_ARM_RETVAL_SIZE (4 * (4 + 12)) +# define FP_SAVED_FP LA_ARM_RETVAL_SIZE +# define FP_PLTEXIT_ARGS (FP_SAVED_FP + 4) +# define FP_LA_ARM_REGS (FP_PLTEXIT_ARGS + 8) +# define FP_CALL_TARGET (FP_LA_ARM_REGS + LA_ARM_REGS_SIZE) +# define FP_FRAMESIZE (FP_CALL_TARGET + 4) + + sub fp, sp, #(FP_FRAMESIZE - FRAMESIZE) + cfi_def_cfa (fp, FP_FRAMESIZE) + + sub r1, fp, ip + @ This doesn't need sfi_sp because we just include the + @ sandboxing mask along with the alignment mask. + bic sp, r1, #0xc000000f + + @ Copy the stack arguments. The audit modules' pltenter + @ function(s) decided how much needs to be copied. + @ Load the sp as modified by pltenter functions, rather + @ than what we think the incoming sp was (fp + FP_FRAMESIZE). + sfi_breg fp, ldr r1, [\B, #(FP_LA_ARM_REGS + 16)] + mov r0, sp + mov r2, ip + sfi_bl memcpy + + @ Load up the arguments from La_arm_regs and call the user's function. + sfi_breg fp, ldr ip, [\B, #FP_CALL_TARGET] + sfi_breg fp, ldrd r0, r1, [\B, #FP_LA_ARM_REGS] + sfi_breg fp, ldrd r2, r3, [\B, #(FP_LA_ARM_REGS + 8)] + sfi_blx ip + + @ Stash the return value registers in La_arm_retval. + sfi_breg fp, strd r0, r1, [\B, #FP_LA_ARM_RETVAL] + sfi_breg fp, strd r2, r3, [\B, #(FP_LA_ARM_RETVAL + 8)] + + @ Call pltexit. We saved the first two arguments earlier--they + @ are the same ones passed to _dl_profile_fixup. The latter two + @ arguments are La_arm_regs and La_arm_retval blocks, respectively. + sfi_breg fp, ldrd r0, r1, [\B, #FP_PLTEXIT_ARGS] + add r2, fp, #FP_LA_ARM_REGS + add r3, fp, #FP_LA_ARM_RETVAL + sfi_bl _dl_call_pltexit + + @ Reload the saved return value registers for the caller. + sfi_breg fp, ldrd r0, r1, [\B, #FP_LA_ARM_RETVAL] + sfi_breg fp, ldrd r2, r3, [\B, #(FP_LA_ARM_RETVAL + 8)] + + @ Unwind the frame. + sfi_sp mov sp, fp + cfi_def_cfa_register (sp) + ldr fp, [sp, #FP_SAVED_FP] + cfi_restore (fp) + @ Reload the lr and sp values from La_arm_regs, where they + @ might have been modified by pltenter functions, rather than + @ computing what we think the incoming value was. + ldr lr, [sp, #(FP_LA_ARM_REGS + 20)] + cfi_restore (lr) + sfi_sp ldr sp, [sp, #(FP_LA_ARM_REGS + 16)] + cfi_def_cfa_offset (0) + + @ Finally, return to the caller. + sfi_bx lr + + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile +#endif + .previous diff --git a/sysdeps/arm/nacl/include/bits/setjmp.h b/sysdeps/arm/nacl/include/bits/setjmp.h new file mode 100644 index 0000000..41830e5 --- /dev/null +++ b/sysdeps/arm/nacl/include/bits/setjmp.h @@ -0,0 +1,38 @@ +/* Private jmp_buf-related definitions. NaCl/ARM version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _INCLUDE_BITS_SETJMP_H +#define _INCLUDE_BITS_SETJMP_H 1 + +#ifndef __ASSEMBLER__ +/* Get the public declarations. */ +# include <sysdeps/arm/bits/setjmp.h> +#endif + +/* Register list for a ldm/stm instruction to load/store + the general registers from a __jmp_buf. + + The generic ARM definition includes r9 (v6), which is not + permitted under NaCl. We add r3 even though it's call-clobbered, + just to keep the size the same as the generic version. */ +#define JMP_BUF_REGLIST {r3, v1-v5, sl, fp} + +/* Index of __jmp_buf where the sp register resides. */ +#define __JMP_BUF_SP 0 + +#endif /* include/bits/setjmp.h */ diff --git a/sysdeps/arm/nacl/shlib-versions b/sysdeps/arm/nacl/shlib-versions new file mode 100644 index 0000000..9d94784 --- /dev/null +++ b/sysdeps/arm/nacl/shlib-versions @@ -0,0 +1,4 @@ +# Library=version Earliest symbol set (optional) +# --------------- ------------------------------ + +ld=ld-nacl-arm.so.1 diff --git a/sysdeps/arm/nacl/start.c b/sysdeps/arm/nacl/start.c new file mode 100644 index 0000000..25f6fd7 --- /dev/null +++ b/sysdeps/arm/nacl/start.c @@ -0,0 +1 @@ +#include <sysdeps/nacl/start.c> diff --git a/sysdeps/arm/nacl/sysdep.h b/sysdeps/arm/nacl/sysdep.h new file mode 100644 index 0000000..951df32 --- /dev/null +++ b/sysdeps/arm/nacl/sysdep.h @@ -0,0 +1,69 @@ +/* Assembler macros for ARM/NaCl. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _ARM_NACL_SYSDEP_H +#define _ARM_NACL_SYSDEP_H 1 + +#ifdef __ASSEMBLER__ + +# ifndef NO_THUMB +# define NO_THUMB +# endif +# define ARM_SFI_MACROS 1 + +/* The compiler driver primes the assembler with a standard set of + macros that includes sfi_breg and sfi_sp. The sfi_pld macro is + redundant with sfi_breg, but libc code uses it so as not to run + afoul of the assembler's parsing bug in versions prior to 2.23.2. + NaCl never uses an assembler that has this bug. */ + +.macro sfi_pld basereg, offset=#0 + sfi_breg \basereg, pld [\basereg, \offset] +.endm + +#endif + +#include <sysdeps/arm/sysdep.h> + +#ifdef __ASSEMBLER__ + +# undef eabi_fnstart +# define eabi_fnstart +# undef eabi_fnend +# define eabi_fnend +# undef eabi_save +# define eabi_save(...) +# undef eabi_cantunwind +# define eabi_cantunwind +# undef eabi_pad +# define eabi_pad(n) + +/* NaCl has its own special way of getting the thread pointer. */ +# undef GET_TLS +# define GET_TLS(tmp) ldr r0, [r9] + +/* Rather than macroizing the code any more, we can just define a few + mnemonics as macros here. */ +# define bl sfi_bl +# define bx sfi_bx +# define blx sfi_blx +# define bxeq sfi_bxeq /* Only condition now in use. */ + +#endif /* __ASSEMBLER__ */ + +#endif /* sysdep.h */ diff --git a/sysdeps/arm/nacl/tls.h b/sysdeps/arm/nacl/tls.h new file mode 100644 index 0000000..646e7a9 --- /dev/null +++ b/sysdeps/arm/nacl/tls.h @@ -0,0 +1,2 @@ +#include <sysdeps/arm/nptl/tls.h> +#include <sysdeps/nacl/tls.h> diff --git a/sysdeps/nacl/Implies b/sysdeps/nacl/Implies new file mode 100644 index 0000000..0448f3f --- /dev/null +++ b/sysdeps/nacl/Implies @@ -0,0 +1,3 @@ +nptl +posix +gnu diff --git a/sysdeps/nacl/Makefile b/sysdeps/nacl/Makefile new file mode 100644 index 0000000..b51156b --- /dev/null +++ b/sysdeps/nacl/Makefile @@ -0,0 +1,135 @@ +# Makefile fragment for NaCl configurations. + +# Copyright (C) 2015 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. + +# 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, see +# <http://www.gnu.org/licenses/>. + +# The libthread_db code does not compile for NaCl because there is no +# sys/procfs.h supplying the register layout types. But since libthread_db +# will probably never be useful for NaCl, just elide the directory rather +# than implementing stuff to make it compile (and never get used). +subdirs := $(filter-out nptl_db,$(subdirs)) +sorted-subdirs := $(filter-out nptl_db,$(sorted-subdirs)) + +# The (required) --with-headers option to configure sets sysheaders to the +# location of the native_client/.. source directory. We'll get necessary +# headers directly from there. +naclsrc = $(sysheaders)/native_client/src + +# How to find the directory containing this Makefile. +nacl = $(..)sysdeps/nacl + +# Generate our bits/errno.h with the numbers from NaCl's sys/errno.h file. +nacl-errno = $(naclsrc)/trusted/service_runtime/include/sys/errno.h + +bits-errno = $(common-objpfx)bits/errno.h +$(bits-errno): $(common-objpfx)stamp-errnos ; +$(common-objpfx)stamp-errnos: $(nacl)/errnos.awk $(..)manual/errno.texi \ + $(nacl-errno) + $(make-target-directory) + $(AWK) -f $^ > $(bits-errno)-tmp +# Make it unwritable so noone will edit it by mistake. + -chmod a-w $(bits-errno)-tmp + $(move-if-change) $(bits-errno)-tmp $(bits-errno) + touch $@ +common-generated += stamp-errnos bits/errno.h +before-compile += $(bits-errno) + +# Massage NaCl's irt.h (and irt_dev.h) into something we can use. +# See irt.sed for details. +nacl-irt.h = $(common-objpfx)nacl-irt.h +$(nacl-irt.h): $(nacl)/irt.sed \ + $(naclsrc)/untrusted/irt/irt.h \ + $(naclsrc)/untrusted/irt/irt_dev.h + sed -f $^ > $@.new + mv -f $@.new $@ +common-generated += nacl-irt.h +before-compile += $(nacl-irt.h) + +$(common-objpfx)nacl-interfaces.v.i: $(nacl)/nacl-interfaces.mk.in \ + $(nacl)/nacl-interface-list.h +-include $(common-objpfx)nacl-interfaces.v +common-generated += nacl-interfaces.v +before-compile += $(common-objpfx)nacl-interfaces.v + +nacl-all-interfaces = $(nacl-mandatory-interfaces) $(nacl-optional-interfaces) +nacl-interface-routines = $(nacl-all-interfaces:%=nacl-interface-%) + +define nacl-interface-table-command +(echo '#define INTERFACE_CATEGORY $1'; \ + echo '#define INTERFACE_MODULE $(firstword $(subst -, ,$*))'; \ + echo '#define INTERFACE_TYPE $(word 2,$(subst -, ,$*))'; \ + echo '#define INTERFACE_STRING $(nacl-$*-string)'; \ + echo '#include "nacl-interface-table.c"' \ +) > $@T +mv -f $@T $@ +endef + +nacl-interface-pattern = $(objpfx)nacl-interface-%.c + +$(nacl-mandatory-interfaces:%=$(nacl-interface-pattern)): \ + $(nacl-interface-pattern): $(nacl)/Makefile $(common-objpfx)nacl-interfaces.v + $(make-target-directory) + $(call nacl-interface-table-command,mandatory) +$(nacl-optional-interfaces:%=$(nacl-interface-pattern)): \ + $(nacl-interface-pattern): $(nacl)/Makefile $(common-objpfx)nacl-interfaces.v + $(make-target-directory) + $(call nacl-interface-table-command,optional) + +nacl-routines-of = $(filter nacl-interface-$1-%,$(nacl-interface-routines)) + + +# Run the NaCl code validator on binaries after we link them, so the +# build does not succeed with any binary that won't pass validation. +# Moving the file around makes sure that we don't leave a target +# appearing complete after it fails validation. +define after-link +mv -f $1 $1.prevalidation +$(nacl)/nacl-after-link.sh '${READELF}' $1.prevalidation +mv -f $1.prevalidation $1 +endef + +# The test wrapper script takes care of running things under NaCl's sel_ldr. +test-wrapper-env-only = $(nacl)/nacl-test-wrapper.sh --arch=$(nacl-sdk-arch) +test-wrapper-env = $(test-wrapper-env-only) +test-wrapper = $(test-wrapper-env) -- + +ifeq ($(subdir),csu) +sysdep_routines += nacl_interface_query \ + nacl-interfaces $(call nacl-routines-of,libc) +endif + +ifeq ($(subdir),elf) +sysdep-dl-routines += $(call nacl-routines-of,rtld) +sysdep-rtld-routines += nacl-interfaces $(call nacl-routines-of,rtld) +endif + +ifeq ($(subdir),io) +sysdep_routines += xstatconv +endif + +ifeq ($(subdir),nptl) +# We do not need any wrappers in libpthread. +libpthread-routines := $(filter-out ptw-%,$(libpthread-routines)) +endif + +ifeq ($(subdir),misc) +# We reuse the Linux file since the bits match. The file lives in the +# top-level source tree so we can use it without reference to any +# sysdeps/.../linux/ directories, but it's still a sysdeps decision to +# install it. +sysdep_headers += bits/mman-linux.h +endif diff --git a/sysdeps/nacl/Subdirs b/sysdeps/nacl/Subdirs new file mode 100644 index 0000000..5d570b9 --- /dev/null +++ b/sysdeps/nacl/Subdirs @@ -0,0 +1,3 @@ +inet +resolv +nss diff --git a/sysdeps/nacl/Versions b/sysdeps/nacl/Versions new file mode 100644 index 0000000..4ac56c2 --- /dev/null +++ b/sysdeps/nacl/Versions @@ -0,0 +1,21 @@ +ld { + GLIBC_PRIVATE { + __nacl_irt_*; + } +} + +libc { + GLIBC_2.22 { + nacl_interface_query; + } + + GLIBC_PRIVATE { + # These are used by libpthread. + __libc_write; + __libc_open; + __libc_close; + __libc_fork; + + __nacl_irt_*; + } +} diff --git a/sysdeps/nacl/_exit.c b/sysdeps/nacl/_exit.c new file mode 100644 index 0000000..6006e26 --- /dev/null +++ b/sysdeps/nacl/_exit.c @@ -0,0 +1,34 @@ +/* _exit -- low-level program termination. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <stdlib.h> +#include <nacl-interfaces.h> + +void +_exit (int status) +{ + __nacl_irt_basic.exit (status); + + /* That never returns unless something is severely and unrecoverably wrong. + If it ever does, try to make sure we crash. */ + while (1) + __builtin_trap (); +} +libc_hidden_def (_exit) +weak_alias (_exit, _Exit) diff --git a/sysdeps/nacl/access.c b/sysdeps/nacl/access.c new file mode 100644 index 0000000..531a999 --- /dev/null +++ b/sysdeps/nacl/access.c @@ -0,0 +1,28 @@ +/* Check file access permission. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Test for access to FILE. */ +int +__access (const char *file, int type) +{ + return NACL_CALL (__nacl_irt_dev_filename.access (file, type), 0); +} +weak_alias (__access, access) diff --git a/sysdeps/nacl/backtrace.c b/sysdeps/nacl/backtrace.c new file mode 100644 index 0000000..27ce597 --- /dev/null +++ b/sysdeps/nacl/backtrace.c @@ -0,0 +1 @@ +#include <sysdeps/x86_64/backtrace.c> diff --git a/sysdeps/nacl/bits/dirent.h b/sysdeps/nacl/bits/dirent.h new file mode 100644 index 0000000..571ac0c --- /dev/null +++ b/sysdeps/nacl/bits/dirent.h @@ -0,0 +1,52 @@ +/* Directory entry structure `struct dirent'. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _DIRENT_H +# error "Never use <bits/dirent.h> directly; include <dirent.h> instead." +#endif + +/* Note that __ino_t and __ino64_t are the same type. + Likewise __off_t and __off64_t are the same type. */ + +struct dirent + { + __ino_t d_ino; /* File serial number. */ + __off_t d_off; /* File position of this entry. */ + unsigned short int d_reclen; /* Length of the whole `struct dirent'. */ + + /* Only this member is in the POSIX standard. */ + char d_name[256]; /* We must not include limits.h! */ + }; + +#ifdef __USE_LARGEFILE64 +/* This is completely identical to `struct dirent'. */ +struct dirent64 + { + __ino_t d_ino; /* File serial number. */ + __off_t d_off; /* File position of this entry. */ + unsigned short int d_reclen; /* Length of the whole `struct dirent'. */ + + /* Only this member is in the POSIX standard. */ + char d_name[256]; /* We must not include limits.h! */ + }; +#endif + +#define d_fileno d_ino /* Backwards compatibility. */ + +#define _DIRENT_HAVE_D_RECLEN 1 +#define _DIRENT_MATCHES_DIRENT64 1 diff --git a/sysdeps/nacl/bits/fcntl.h b/sysdeps/nacl/bits/fcntl.h new file mode 100644 index 0000000..ceef8df --- /dev/null +++ b/sysdeps/nacl/bits/fcntl.h @@ -0,0 +1,149 @@ +/* O_*, F_*, FD_* bit values. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _FCNTL_H +#error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." +#endif + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 00100 /* Create file if it doesn't exist. */ +#define O_EXCL 00200 /* Fail if file already exists. */ +#define O_TRUNC 01000 /* Truncate file to zero length. */ +#define O_NOCTTY 0 /* Don't assign a controlling terminal. */ +#define O_ASYNC 020000 /* Send SIGIO to owner when data is ready. */ +#define O_FSYNC 010000 /* Synchronous writes. */ +#define O_SYNC O_FSYNC +#ifdef __USE_MISC +# define O_SHLOCK XXX /* Open with shared file lock. */ +# define O_EXLOCK XXX /* Open with shared exclusive lock. */ +#endif +#ifdef __USE_XOPEN2K8 +# define O_DIRECTORY 00200000 /* Must be a directory. */ +# define O_NOFOLLOW 00400000 /* Do not follow links. */ +# define O_CLOEXEC 02000000 /* Set close_on_exec. */ +#endif +#if defined __USE_POSIX199309 || defined __USE_UNIX98 +# define O_DSYNC O_SYNC /* Synchronize data. */ +# define O_RSYNC O_SYNC /* Synchronize read operations. */ +#endif + +/* All opens support large file sizes, so there is no flag bit for this. */ +#ifdef __USE_LARGEFILE64 +# define O_LARGEFILE 0 +#endif + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 02000 /* Writes append to the file. */ +#define O_NONBLOCK 04000 /* Non-blocking I/O. */ + +#ifdef __USE_MISC +# define O_NDELAY O_NONBLOCK +#endif + +#ifdef __USE_MISC +/* Bits in the file status flags returned by F_GETFL. + These are all the O_* flags, plus FREAD and FWRITE, which are + independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was + given to `open'. */ +# define FREAD 1 +# define FWRITE 2 + +/* Traditional BSD names the O_* bits. */ +# define FASYNC O_ASYNC +# define FFSYNC O_FSYNC +# define FSYNC O_SYNC +# define FAPPEND O_APPEND +# define FNDELAY O_NDELAY +#endif + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#if defined __USE_UNIX98 || defined __USE_XOPEN2K8 +#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ +#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ +#endif +#define F_GETLK 7 /* Get record locking info. */ +#define F_SETLK 8 /* Set record locking info (non-blocking). */ +#define F_SETLKW 9 /* Set record locking info (blocking). */ +/* Not necessary, we always have 64-bit offsets. */ +#define F_GETLK64 F_GETLK /* Get record locking info. */ +#define F_SETLK64 F_SETLK /* Set record locking info (non-blocking). */ +#define F_SETLKW64 F_SETLKW/* Set record locking info (blocking). */ +#ifdef __USE_XOPEN2K8 +# define F_DUPFD_CLOEXEC 12 /* Duplicate file descriptor with + close-on-exec set. */ +#endif + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <bits/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; + +#ifdef __USE_LARGEFILE64 +/* Note this matches struct flock exactly. */ +struct flock64 + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; +#endif + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + +/* Advice to `posix_fadvise'. */ +#ifdef __USE_XOPEN2K +# define POSIX_FADV_NORMAL 0 /* No further special treatment. */ +# define POSIX_FADV_RANDOM 1 /* Expect random page references. */ +# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ +# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ +# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ +# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ +#endif diff --git a/sysdeps/nacl/bits/local_lim.h b/sysdeps/nacl/bits/local_lim.h new file mode 100644 index 0000000..950a237 --- /dev/null +++ b/sysdeps/nacl/bits/local_lim.h @@ -0,0 +1,64 @@ +/* Minimum guaranteed maximum values for system limits. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#define NAME_MAX 255 + +#define PATH_MAX 4096 + +#define NGROUPS_MAX 65536 + +/* The number of data keys per process. */ +#define _POSIX_THREAD_KEYS_MAX 128 +/* This is the value this implementation supports. */ +#define PTHREAD_KEYS_MAX 1024 + +/* Controlling the iterations of destructors for thread-specific data. */ +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 +/* Number of iterations this implementation does. */ +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +/* The number of threads per process. */ +#define _POSIX_THREAD_THREADS_MAX 64 +/* We have no predefined limit on the number of threads. */ +#undef PTHREAD_THREADS_MAX + +/* Maximum amount by which a process can descrease its asynchronous I/O + priority level. */ +#define AIO_PRIO_DELTA_MAX 20 + +/* Minimum size for a thread. We are free to choose a reasonable value. */ +#define PTHREAD_STACK_MIN 131072 + +/* Maximum number of timer expiration overruns. */ +#define DELAYTIMER_MAX 2147483647 + +/* Maximum tty name length. */ +#define TTY_NAME_MAX 32 + +/* Maximum login name length. This is arbitrary. */ +#define LOGIN_NAME_MAX 256 + +/* Maximum host name length. */ +#define HOST_NAME_MAX 64 + +/* Maximum message queue priority level. */ +#define MQ_PRIO_MAX 32768 + +/* Maximum value the semaphore can have. */ +#define SEM_VALUE_MAX (2147483647) diff --git a/sysdeps/nacl/bits/mman.h b/sysdeps/nacl/bits/mman.h new file mode 100644 index 0000000..2d5fdfc --- /dev/null +++ b/sysdeps/nacl/bits/mman.h @@ -0,0 +1,24 @@ +/* Definitions for POSIX memory map interface. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_MMAN_H +# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead." +#endif + +/* NaCl uses the Linux bits for this. */ +#include <bits/mman-linux.h> diff --git a/sysdeps/nacl/bits/param.h b/sysdeps/nacl/bits/param.h new file mode 100644 index 0000000..17eb1ee --- /dev/null +++ b/sysdeps/nacl/bits/param.h @@ -0,0 +1,23 @@ +/* Old-style Unix parameters and limits. NaCl version. + Copyright (C) 2012 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_PARAM_H +# error "Never use <bits/param.h> directly; include <sys/param.h> instead." +#endif + +#define EXEC_PAGESIZE 0x10000 diff --git a/sysdeps/nacl/bits/posix_opt.h b/sysdeps/nacl/bits/posix_opt.h new file mode 100644 index 0000000..2a5d6fd --- /dev/null +++ b/sysdeps/nacl/bits/posix_opt.h @@ -0,0 +1,210 @@ +/* Define POSIX options for NaCl. + Copyright (C) 2015 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. + + 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; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_POSIX_OPT_H +#define _BITS_POSIX_OPT_H 1 + +/* Job control is supported. (Not really, but the APIs exist.) */ +#define _POSIX_JOB_CONTROL 1 + +/* Processes have a saved set-user-ID and a saved set-group-ID. */ +#define _POSIX_SAVED_IDS 1 + +/* Priority scheduling is supported. ??? */ +#define _POSIX_PRIORITY_SCHEDULING 200809L + +/* Synchronizing file data is supported. ??? */ +#define _POSIX_SYNCHRONIZED_IO 200809L + +/* The fsync function is present. */ +#define _POSIX_FSYNC 200809L + +/* Mapping of files to memory is supported. */ +#define _POSIX_MAPPED_FILES 200809L + +/* Locking of all memory is not supported. */ +#define _POSIX_MEMLOCK -1 + +/* Locking of ranges of memory is not supported. */ +#define _POSIX_MEMLOCK_RANGE -1 + +/* Setting of memory protections is supported. */ +#define _POSIX_MEMORY_PROTECTION 200809L + +/* Some filesystems allow all users to change file ownership. */ +#define _POSIX_CHOWN_RESTRICTED 0 + +/* `c_cc' member of 'struct termios' structure can be disabled by + using the value _POSIX_VDISABLE. ??? */ +#define _POSIX_VDISABLE '\0' + +/* Filenames are not silently truncated. */ +#define _POSIX_NO_TRUNC 1 + +/* X/Open realtime support is not fully available. This requires the + following set of POSIX.1 features, not all of which NaCl supports: + _POSIX_FSYNC + _POSIX_MEMLOCK + _POSIX_MEMLOCK_RANGE + _POSIX_MESSAGE_PASSING + _POSIX_PRIORITIZED_IO + _POSIX_PRIORITY_SCHEDULING + _POSIX_SHARED_MEMORY_OBJECTS + _POSIX_SYNCHRONIZED_IO + */ +#define _XOPEN_REALTIME -1 + +/* X/Open thread realtime support is not available. This requires the + following set of POSIX.1 features, none of which NaCl supports: + _POSIX_THREAD_PRIO_INHERIT + _POSIX_THREAD_PRIO_PROTECT + _POSIX_THREAD_PRIORITY_SCHEDULING + _POSIX_THREAD_ROBUST_PRIO_INHERIT + _POSIX_THREAD_ROBUST_PRIO_PROTECT + */ +#define _XOPEN_REALTIME_THREADS -1 + +/* XPG4.2 shared memory is not supported. + ??? What is this? shm* interfaces? +*/ +#define _XOPEN_SHM -1 + +/* POSIX threads are supported. */ +#define _POSIX_THREADS 200809L + +/* We have the reentrant functions described in POSIX. */ +#define _POSIX_REENTRANT_FUNCTIONS 1 +#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L + +/* We do not provide priority scheduling for threads. */ +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +/* We support user-defined stack sizes. */ +#define _POSIX_THREAD_ATTR_STACKSIZE 200809L + +/* We support user-defined stacks. */ +#define _POSIX_THREAD_ATTR_STACKADDR 200809L + +/* We do not support priority inheritence. */ +#define _POSIX_THREAD_PRIO_INHERIT -1 + +/* We do not support priority protection. */ +#define _POSIX_THREAD_PRIO_PROTECT -1 + +#ifdef __USE_XOPEN2K8 +/* We do not support priority inheritence for robust mutexes. */ +# define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1 + +/* We do not support priority protection for robust mutexes. */ +# define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1 +#endif + +/* We support POSIX.1b semaphores. */ +#define _POSIX_SEMAPHORES 200809L + +/* Real-time signals are supported. ??? */ +#define _POSIX_REALTIME_SIGNALS 200809L + +/* We support asynchronous I/O. */ +#define _POSIX_ASYNCHRONOUS_IO 200809L +#define _POSIX_ASYNC_IO 1 +/* Alternative name for Unix98. */ +#define _LFS_ASYNCHRONOUS_IO 1 +/* Support for prioritization is not available. */ +#define _POSIX_PRIORITIZED_IO -1 + +/* The LFS support in asynchronous I/O is also available. */ +#define _LFS64_ASYNCHRONOUS_IO 1 + +/* The rest of the LFS is also available. */ +#define _LFS_LARGEFILE 1 +#define _LFS64_LARGEFILE 1 +#define _LFS64_STDIO 1 + +/* POSIX shared memory objects are implemented. */ +#define _POSIX_SHARED_MEMORY_OBJECTS 200809L + +/* Process CPU-time clocks are not supported. */ +#define _POSIX_CPUTIME -1 + +/* Thread CPU-time locks are supported. */ +#define _POSIX_THREAD_CPUTIME 200809L + +/* GNU libc provides regular expression handling. */ +#define _POSIX_REGEXP 1 + +/* Reader/Writer locks are available. */ +#define _POSIX_READER_WRITER_LOCKS 200809L + +/* We have a POSIX shell. */ +#define _POSIX_SHELL 1 + +/* We support the Timeouts option. */ +#define _POSIX_TIMEOUTS 200809L + +/* We support spinlocks. */ +#define _POSIX_SPIN_LOCKS 200809L + +/* The `spawn' function family is supported. */ +#define _POSIX_SPAWN 200809L + +/* We have POSIX timers. */ +#define _POSIX_TIMERS 200809L + +/* The barrier functions are available. */ +#define _POSIX_BARRIERS 200809L + +/* POSIX message queues are not available. */ +#define _POSIX_MESSAGE_PASSING -1 + +/* Thread process-shared synchronization is not supported. */ +#define _POSIX_THREAD_PROCESS_SHARED -1 + +/* The monotonic clock is available. */ +#define _POSIX_MONOTONIC_CLOCK 200809L + +/* The clock selection interfaces are available. ??? Actually only + clock_nanosleep works, and pthread_condattr_setclock does not. */ +#define _POSIX_CLOCK_SELECTION 200809L + +/* Advisory information interfaces are available. */ +#define _POSIX_ADVISORY_INFO 200809L + +/* IPv6 support is available. */ +#define _POSIX_IPV6 200809L + +/* Raw socket support is available. */ +#define _POSIX_RAW_SOCKETS 200809L + +/* We have at least one terminal. */ +#define _POSIX2_CHAR_TERM 200809L + +/* Neither process nor thread sporadic server interfaces is available. */ +#define _POSIX_SPORADIC_SERVER -1 +#define _POSIX_THREAD_SPORADIC_SERVER -1 + +/* trace.h is not available. */ +#define _POSIX_TRACE -1 +#define _POSIX_TRACE_EVENT_FILTER -1 +#define _POSIX_TRACE_INHERIT -1 +#define _POSIX_TRACE_LOG -1 + +/* Typed memory objects are not available. */ +#define _POSIX_TYPED_MEMORY_OBJECTS -1 + +#endif /* bits/posix_opt.h */ diff --git a/sysdeps/nacl/bits/stat.h b/sysdeps/nacl/bits/stat.h new file mode 100644 index 0000000..0cd3500 --- /dev/null +++ b/sysdeps/nacl/bits/stat.h @@ -0,0 +1,147 @@ +/* 'struct stat' and related definitions. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#if !defined _SYS_STAT_H && !defined _FCNTL_H +# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead." +#endif + +#ifndef _BITS_STAT_H +#define _BITS_STAT_H 1 + +/* Versions of the `struct stat' data structure. */ +#define _STAT_VER_NACL 0 +#define _STAT_VER_LINUX 1 + +#define _STAT_VER _STAT_VER_LINUX + +struct stat + { + __dev_t st_dev; /* Device. */ + __ino_t st_ino; /* File serial number. */ + __nlink_t st_nlink; /* Link count. */ + __mode_t st_mode; /* File mode. */ + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ + int __pad0; + __dev_t st_rdev; /* Device number, if device. */ + __off_t st_size; /* Size of file, in bytes. */ + __blksize_t st_blksize; /* Optimal block size for I/O. */ + __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ +#if defined __USE_MISC || defined __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the + identifier 'timespec' to appear in the <sys/stat.h> header. + Therefore we have to handle the use of this header in strictly + standard-compliant sources special. */ + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +# define st_atime st_atim.tv_sec /* Backward compatibility. */ +# define st_mtime st_mtim.tv_sec +# define st_ctime st_ctim.tv_sec +#else + __time_t st_atime; /* Time of last access. */ + __uint64_t st_atimensec; /* Nsecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + __uint64_t st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + __uint64_t st_ctimensec; /* Nsecs of last status change. */ +#endif + __int64_t __unused[3]; + }; + +#ifdef __USE_LARGEFILE64 +/* Note stat64 has the same shape as stat for NaCl. */ +struct stat64 + { + __dev_t st_dev; /* Device. */ + __ino_t st_ino; /* File serial number. */ + __nlink_t st_nlink; /* Link count. */ + __mode_t st_mode; /* File mode. */ + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ + int __pad0; + __dev_t st_rdev; /* Device number, if device. */ + __off_t st_size; /* Size of file, in bytes. */ + __blksize_t st_blksize; /* Optimal block size for I/O. */ + __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ +# if defined __USE_MISC || defined __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the + identifier 'timespec' to appear in the <sys/stat.h> header. + Therefore we have to handle the use of this header in strictly + standard-compliant sources special. */ + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +# define st_atime st_atim.tv_sec /* Backward compatibility. */ +# define st_mtime st_mtim.tv_sec +# define st_ctime st_ctim.tv_sec +# else + __time_t st_atime; /* Time of last access. */ + __uint64_t st_atimensec; /* Nsecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + __uint64_t st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + __uint64_t st_ctimensec; /* Nsecs of last status change. */ +# endif + __int64_t __unused[3]; + }; +#endif + +/* Tell code we have these members. */ +#define _STATBUF_ST_BLKSIZE 1 +#define _STATBUF_ST_RDEV 1 +/* Nanosecond resolution time values are supported. */ +#define _STATBUF_ST_NSEC 1 + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ + +/* POSIX.1b objects. Note that these macros always evaluate to zero. But + they do it by enforcing the correct use of the macros. */ +#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode) +#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode) +#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode) + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ + +#ifdef __USE_ATFILE +/* XXX missing: UTIME_NOW, UTIME_OMIT */ +#endif + +#endif /* bits/stat.h */ diff --git a/sysdeps/nacl/bits/typesizes.h b/sysdeps/nacl/bits/typesizes.h new file mode 100644 index 0000000..2a29035 --- /dev/null +++ b/sysdeps/nacl/bits/typesizes.h @@ -0,0 +1,71 @@ +/* bits/typesizes.h -- underlying types for *_t. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_H +# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead." +#endif + +#ifndef _BITS_TYPESIZES_H +#define _BITS_TYPESIZES_H 1 + +/* See <bits/types.h> for the meaning of these macros. This file exists so + that <bits/types.h> need not vary across different GNU platforms. */ + +#define __DEV_T_TYPE __UQUAD_TYPE +#define __UID_T_TYPE __U32_TYPE +#define __GID_T_TYPE __U32_TYPE +#define __INO_T_TYPE __UQUAD_TYPE +#define __INO64_T_TYPE __INO_T_TYPE +#define __MODE_T_TYPE __U32_TYPE +#define __NLINK_T_TYPE __UWORD_TYPE +#define __OFF_T_TYPE __SQUAD_TYPE +#define __OFF64_T_TYPE __OFF_T_TYPE +#define __PID_T_TYPE __S32_TYPE +#define __RLIM_T_TYPE __UQUAD_TYPE +#define __RLIM64_T_TYPE __RLIM_T_TYPE +#define __BLKCNT_T_TYPE __SQUAD_TYPE +#define __BLKCNT64_T_TYPE __BLKCNT_T_TYPE +#define __FSBLKCNT_T_TYPE __UQUAD_TYPE +#define __FSBLKCNT64_T_TYPE __FSBLKCNT_T_TYPE +#define __FSFILCNT_T_TYPE __UQUAD_TYPE +#define __FSFILCNT64_T_TYPE __FSFILCNT_T_TYPE +#define __FSWORD_T_TYPE __SWORD_TYPE +#define __ID_T_TYPE __U32_TYPE +#define __CLOCK_T_TYPE __SQUAD_TYPE +#define __TIME_T_TYPE __SQUAD_TYPE +#define __USECONDS_T_TYPE __U32_TYPE +#define __SUSECONDS_T_TYPE __S32_TYPE +#define __DADDR_T_TYPE __S32_TYPE +#define __KEY_T_TYPE __S32_TYPE +#define __CLOCKID_T_TYPE __S32_TYPE +#define __TIMER_T_TYPE void * +#define __BLKSIZE_T_TYPE __SLONGWORD_TYPE +#define __FSID_T_TYPE struct { int __val[2]; } +#define __SSIZE_T_TYPE __SWORD_TYPE +#define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE +#define __SYSCALL_ULONG_TYPE __ULONGWORD_TYPE + +/* All our foo64_t types match their foo_t counterparts. */ +#define __OFF_T_MATCHES_OFF64_T 1 +#define __INO_T_MATCHES_INO64_T 1 + +/* Number of descriptors that can fit in an `fd_set'. */ +#define __FD_SETSIZE 1024 + + +#endif /* bits/typesizes.h */ diff --git a/sysdeps/nacl/brk.c b/sysdeps/nacl/brk.c new file mode 100644 index 0000000..bc103de --- /dev/null +++ b/sysdeps/nacl/brk.c @@ -0,0 +1,93 @@ +/* brk -- Adjust the "break" at the end of initial data. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <libc-internal.h> +#include <stdint.h> +#include <sys/mman.h> +#include <sys/param.h> +#include <unistd.h> + +/* sbrk.c expects this. */ +void *__curbrk; + +static uintptr_t +page_above (void *addr) +{ + return ALIGN_UP ((uintptr_t) addr, EXEC_PAGESIZE); +} + +/* Set the end of the process's data space to ADDR. + Return 0 if successful, -1 if not. */ +int +__brk (void *addr) +{ + /* The NaCl sysbrk call is deprecated, so we do not use it here. Other + libc code expects that __sbrk can be used at least a little bit, so + rather than a plain stub we have a minimal __brk implementation here. + It just uses mmap/munmap to grow or shrink the break area, punting as + soon as mmap fails to use the same contiguous area. */ + + if (__glibc_unlikely (__curbrk == NULL)) + { + /* This is the first call. We must initialize the record + of the current position. It starts out at the end of the + main program's data segment. */ + + /* XXX dynamic case??? */ + extern char _end[]; + __curbrk = _end; + } + + if (__glibc_unlikely (addr == NULL)) + /* This is a call just to ensure that __curbrk is set up. */ + return 0; + + uintptr_t old_limit = page_above (__curbrk); + uintptr_t new_limit = page_above (addr); + + if (old_limit > new_limit) + { + /* We're shrinking the old heap enough to release some pages. */ + if (__munmap ((void *) new_limit, old_limit - new_limit) != 0) + return -1; + } + else if (old_limit < new_limit) + { + /* We're growing the old heap enough to need some more pages. + See if they are available. */ + void *new_space = __mmap ((void *) old_limit, new_limit - old_limit, + PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + if (new_space != (void *) old_limit) + { + if (new_space != MAP_FAILED) + { + /* mmap chose some different place for the pages + because the contiguous area was not available. + Oh well. We can't use that. */ + __munmap (new_space, new_limit - old_limit); + __set_errno (ENOMEM); + } + return -1; + } + } + + __curbrk = addr; + return 0; +} +weak_alias (__brk, brk) diff --git a/sysdeps/nacl/chdir.c b/sysdeps/nacl/chdir.c new file mode 100644 index 0000000..e194ae9 --- /dev/null +++ b/sysdeps/nacl/chdir.c @@ -0,0 +1,28 @@ +/* Change current working directory. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Change the current directory to PATH. */ +int +__chdir (const char *path) +{ + return NACL_CALL (__nacl_irt_dev_filename.chdir (path), 0); +} +weak_alias (__chdir, chdir) diff --git a/sysdeps/nacl/check_fds.c b/sysdeps/nacl/check_fds.c new file mode 100644 index 0000000..a6bd8d8 --- /dev/null +++ b/sysdeps/nacl/check_fds.c @@ -0,0 +1,23 @@ +/* Check inherited file descriptors for sanity at startup. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +/* Nothing to do here. */ +void +__libc_check_standard_fds (void) +{ +} diff --git a/sysdeps/nacl/chmod.c b/sysdeps/nacl/chmod.c new file mode 100644 index 0000000..9a8ba09 --- /dev/null +++ b/sysdeps/nacl/chmod.c @@ -0,0 +1,28 @@ +/* Change a file's permissions. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Change the protections of FILE to MODE. */ +int +__chmod (const char *file, mode_t mode) +{ + return NACL_CALL (__nacl_irt_dev_filename.chmod (file, mode), 0); +} +weak_alias (__chmod, chmod) diff --git a/sysdeps/nacl/clock.c b/sysdeps/nacl/clock.c new file mode 100644 index 0000000..e3bf897 --- /dev/null +++ b/sysdeps/nacl/clock.c @@ -0,0 +1,29 @@ +/* Return the time used by the program so far. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <time.h> +#include <nacl-interfaces.h> + + +/* Return the time used by the program so far (user time + system time). */ +clock_t +clock (void) +{ + nacl_abi_clock_t result; + return NACL_CALL (__nacl_irt_basic.clock (&result), result); +} diff --git a/sysdeps/nacl/clock_getres.c b/sysdeps/nacl/clock_getres.c new file mode 100644 index 0000000..4605206 --- /dev/null +++ b/sysdeps/nacl/clock_getres.c @@ -0,0 +1,28 @@ +/* Get the resolution of a clock. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <time.h> +#include <nacl-interfaces.h> + +/* Get resolution of clock. */ +int +__clock_getres (clockid_t clock_id, struct timespec *res) +{ + return NACL_CALL (__nacl_irt_clock.clock_getres (clock_id, res), 0); +} +weak_alias (__clock_getres, clock_getres) diff --git a/sysdeps/nacl/clock_gettime.c b/sysdeps/nacl/clock_gettime.c new file mode 100644 index 0000000..8103ae3 --- /dev/null +++ b/sysdeps/nacl/clock_gettime.c @@ -0,0 +1,29 @@ +/* Get the current value of a clock. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <time.h> +#include <nacl-interfaces.h> + +/* Get current value of CLOCK and store it in TP. */ +int +__clock_gettime (clockid_t clock_id, struct timespec *tp) +{ + return NACL_CALL (__nacl_irt_clock.clock_gettime (clock_id, tp), 0); +} +libc_hidden_def (__clock_gettime) +weak_alias (__clock_gettime, clock_gettime) diff --git a/sysdeps/nacl/close.c b/sysdeps/nacl/close.c new file mode 100644 index 0000000..9f550f9 --- /dev/null +++ b/sysdeps/nacl/close.c @@ -0,0 +1,31 @@ +/* Close a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + + +/* Close the file descriptor FD. */ +int +__close (int fd) +{ + return NACL_CALL (__nacl_irt_fdio.close (fd), 0); +} +libc_hidden_def (__close) +strong_alias (__close, __libc_close) +weak_alias (__close, close) diff --git a/sysdeps/nacl/configure b/sysdeps/nacl/configure new file mode 100644 index 0000000..6bc753b --- /dev/null +++ b/sysdeps/nacl/configure @@ -0,0 +1,18 @@ +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/nacl. + +nacl_probe_file=native_client/src/trusted/service_runtime/include/sys/errno.h + +# sysheaders is set by the --with-headers=... option to configure. +# For NaCl, we require that the option be given and point to the +# native_client/.. source tree directory. +test -n "$sysheaders" || { + as_fn_error $? "must supply --with-headers=DIR with native_client source tree" "$LINENO" 5 +} +test -r "$sysheaders/$nacl_probe_file" || { + as_fn_error $? "$sysheaders does not appear to be a native_client source tree" "$LINENO" 5 +} + +# nscd is extremely useless in the NaCl context. +build_nscd=no +use_nscd=no diff --git a/sysdeps/nacl/configure.ac b/sysdeps/nacl/configure.ac new file mode 100644 index 0000000..2c6f29f --- /dev/null +++ b/sysdeps/nacl/configure.ac @@ -0,0 +1,18 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/nacl. + +nacl_probe_file=native_client/src/trusted/service_runtime/include/sys/errno.h + +# sysheaders is set by the --with-headers=... option to configure. +# For NaCl, we require that the option be given and point to the +# native_client/.. source tree directory. +test -n "$sysheaders" || { + AC_MSG_ERROR([must supply --with-headers=DIR with native_client source tree]) +} +test -r "$sysheaders/$nacl_probe_file" || { + AC_MSG_ERROR([$sysheaders does not appear to be a native_client source tree]) +} + +# nscd is extremely useless in the NaCl context. +build_nscd=no +use_nscd=no diff --git a/sysdeps/nacl/createthread.c b/sysdeps/nacl/createthread.c new file mode 100644 index 0000000..9df4eae --- /dev/null +++ b/sysdeps/nacl/createthread.c @@ -0,0 +1,46 @@ +/* Low-level thread creation for NPTL. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <nacl-interfaces.h> + +/* See the comments in pthread_create.c for the requirements for these + two macros and the create_thread function. */ + +#define START_THREAD_DEFN \ + static void __attribute__ ((noreturn)) start_thread (void) +#define START_THREAD_SELF THREAD_SELF + +/* pthread_create.c defines this using START_THREAD_DEFN + We need a forward declaration here so we can take its address. */ +static void start_thread (void) __attribute__ ((noreturn)); + +static int +create_thread (struct pthread *pd, const struct pthread_attr *attr, + bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran) +{ + pd->stopped_start = stopped_start; + if (__glibc_unlikely (stopped_start)) + /* We make sure the thread does not run far by forcing it to get a + lock. We lock it here too so that the new thread cannot continue + until we tell it to. */ + lll_lock (pd->lock, LLL_PRIVATE); + + TLS_DEFINE_INIT_TP (tp, pd); + + return __nacl_irt_thread.thread_create (&start_thread, stackaddr, tp); +} diff --git a/sysdeps/nacl/dl-map-segments.h b/sysdeps/nacl/dl-map-segments.h new file mode 100644 index 0000000..f305da3 --- /dev/null +++ b/sysdeps/nacl/dl-map-segments.h @@ -0,0 +1,238 @@ +/* Map in a shared object's segments. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <dl-load.h> +#include <errno.h> +#include <stdbool.h> +#include <unistd.h> +#include <libc-internal.h> + + +/* This is basically pread, but with iteration after short reads. */ +static bool +read_in_data (int fd, void *data, size_t len, off_t pos) +{ + if (__glibc_unlikely (__lseek (fd, pos, SEEK_SET) == (off_t) -1)) + return true; + while (len > 0) + { + ssize_t n = __read (fd, data, len); + if (__glibc_unlikely (n < 0)) + return true; + if (__glibc_unlikely (n == 0)) + { + errno = EFTYPE; + return true; + } + data += n; + len -= n; + } + return false; +} + +static const char * +_dl_map_segments (struct link_map *l, int fd, + const ElfW(Ehdr) *header, int type, + const struct loadcmd loadcmds[], size_t nloadcmds, + const size_t maplength, bool has_holes, + struct link_map *loader) +{ + if (__builtin_expect (type, ET_DYN) == ET_DYN) + { + /* This is a position-independent shared object. Let the system + choose where to place it. + + As a refinement, sometimes we have an address that we would + prefer to map such objects at; but this is only a preference, + the OS can do whatever it likes. */ + ElfW(Addr) mappref + = (ELF_PREFERRED_ADDRESS (loader, maplength, + loadcmds[0].mapstart & GLRO(dl_use_load_bias)) + - MAP_BASE_ADDR (l)); + + uintptr_t mapstart; + if (__glibc_likely (loadcmds[0].prot & PROT_EXEC)) + { + /* When there is a code segment, we must use the + allocate_code_data interface to choose a location. */ + + uintptr_t code_size = loadcmds[0].allocend - loadcmds[0].mapstart; + uintptr_t data_offset; + size_t data_size; + + if (__glibc_likely (nloadcmds > 1)) + { + data_offset = loadcmds[1].mapstart - loadcmds[0].mapstart; + data_size = ALIGN_UP (maplength - data_offset, + GLRO(dl_pagesize)); + } + else + { + data_offset = 0; + data_size = 0; + } + + int error = __nacl_irt_code_data_alloc.allocate_code_data + (mappref, code_size, data_offset, data_size, &mapstart); + if (__glibc_unlikely (error)) + { + errno = error; + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + } + } + else + { + /* With no code pages involved, plain mmap works fine. */ + void *mapped = __mmap ((void *) mappref, maplength, + PROT_NONE, MAP_ANON, -1, 0); + if (__glibc_unlikely (mapped == MAP_FAILED)) + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + mapstart = (uintptr_t) mapped; + } + + l->l_addr = mapstart - loadcmds[0].mapstart; + } + + /* Remember which part of the address space this object uses. */ + l->l_map_start = loadcmds[0].mapstart + l->l_addr; + l->l_map_end = l->l_map_start + maplength; + l->l_contiguous = !has_holes; + + /* Now actually map (or read) in each segment. */ + for (const struct loadcmd *c = loadcmds; c < &loadcmds[nloadcmds]; ++c) + if (__glibc_likely (c->mapend > c->mapstart)) + { + /* Unlike POSIX mmap, NaCl's mmap does not reliably handle COW + faults in the remainder of the final partial page. So to get + the expected behavior for the unaligned boundary between data + and bss, it's necessary to allocate the final partial page of + data as anonymous memory rather than mapping it from the file. */ + + size_t maplen = c->mapend - c->mapstart; + if (c->mapend > c->dataend && c->allocend > c->dataend) + maplen = (c->dataend & -GLRO(dl_pagesize)) - c->mapstart; + + /* Map the segment contents from the file. */ + if (__glibc_unlikely (__mmap ((void *) (l->l_addr + c->mapstart), + maplen, c->prot, + MAP_FIXED|MAP_COPY|MAP_FILE, + fd, c->mapoff) + == MAP_FAILED)) + { + switch (errno) + { + case EINVAL: + case ENOTSUP: + case ENOSYS: + break; + default: + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + } + + /* No mmap support for this file. */ + if (c->prot & PROT_EXEC) + { + /* Read the data into a temporary buffer. */ + const size_t len = c->mapend - c->mapstart; + void *data = __mmap (NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0); + if (__glibc_unlikely (data == MAP_FAILED)) + return DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL; + if (read_in_data (fd, data, len, c->mapoff)) + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + /* Now validate and install the code. */ + int error = __nacl_irt_dyncode.dyncode_create + ((void *) (l->l_addr + c->mapstart), data, len); + __munmap (data, len); + if (__glibc_unlikely (error)) + { + errno = error; + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + } + } + else + { + /* Allocate the pages. */ + if (__mmap ((void *) (l->l_addr + c->mapstart), + c->mapend - c->mapstart, c->prot | PROT_WRITE, + MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0) + == MAP_FAILED) + return DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL; + /* Now read in the data. */ + if (read_in_data (fd, (void *) (l->l_addr + c->mapstart), + c->dataend - c->mapstart, c->mapoff)) + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + /* Now that we've filled the pages, reset the page + protections to what they should be. */ + if (!(c->prot & PROT_WRITE) + && __mprotect ((void *) (l->l_addr + c->mapstart), + c->mapend - c->mapstart, c->prot) < 0) + return DL_MAP_SEGMENTS_ERROR_MPROTECT; + } + } + else if (c->allocend > c->dataend) + { + /* Extra zero pages should appear at the end of this segment, + after the data mapped from the file. */ + + uintptr_t allocend = c->mapend; + if (c->mapend > c->dataend) + { + /* The final data page was partial. So we didn't map it in. + Instead, we must allocate an anonymous page to fill. */ + if (c->prot & PROT_WRITE) + /* Do the whole allocation right here. */ + allocend = c->allocend; + if (__mmap ((void *) (l->l_addr + c->mapstart + maplen), + allocend - (c->mapstart + maplen), c->prot, + MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0) + == MAP_FAILED) + return DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL; + if (read_in_data (fd, + (void *) (l->l_addr + c->mapstart + maplen), + c->dataend & (GLRO(dl_pagesize) - 1), + c->mapoff + maplen)) + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + /* Now that we've filled the page, reset its + protections to what they should be. */ + if (!(c->prot & PROT_WRITE) + && __mprotect ((void *) (l->l_addr + c->mapstart + maplen), + c->mapend - (c->mapstart + maplen), + c->prot) < 0) + return DL_MAP_SEGMENTS_ERROR_MPROTECT; + } + + /* Now allocate the pure zero-fill pages. */ + if (allocend < c->allocend + && (__mmap ((void *) (l->l_addr + c->mapstart + allocend), + c->allocend - (c->mapstart + allocend), c->prot, + MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0) + == MAP_FAILED)) + return DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL; + } + + _dl_postprocess_loadcmd (l, header, c); + } + + /* Notify ELF_PREFERRED_ADDRESS that we have to load this one + fixed. */ + ELF_FIXED_ADDRESS (loader, c->mapstart); + + return NULL; +} diff --git a/sysdeps/nacl/dl-osinfo.h b/sysdeps/nacl/dl-osinfo.h new file mode 100644 index 0000000..ee74d9d --- /dev/null +++ b/sysdeps/nacl/dl-osinfo.h @@ -0,0 +1,34 @@ +/* DL_SYSDEP_OSCHECK macro for NaCl. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _DL_OSINFO_H +#define _DL_OSINFO_H 1 + +#include <sysdeps/generic/dl-osinfo.h> + +#include "nacl-interfaces.h" + +#ifndef SHARED +/* This doesn't really have anything to do with the purpose for + which this macro is used in Linux configurations. But it is + called at the right place in __libc_start_main. */ +# define DL_SYSDEP_OSCHECK(fatal) __nacl_initialize_interfaces () +#endif + + +#endif /* dl-osinfo.h */ diff --git a/sysdeps/nacl/dl-sysdep.c b/sysdeps/nacl/dl-sysdep.c new file mode 100644 index 0000000..3e902c2 --- /dev/null +++ b/sysdeps/nacl/dl-sysdep.c @@ -0,0 +1,89 @@ +/* Operating system support for run-time dynamic linker. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifdef SHARED + +# include <assert.h> +# include <ldsodefs.h> +# include <stdint.h> +# include <nacl-interfaces.h> + +/* NaCl's elf32.h is incompatible with the real <elf.h>. */ +# define NATIVE_CLIENT_SRC_INCLUDE_ELF32_H_ +# include <native_client/src/untrusted/nacl/nacl_startup.h> + +/* The RTLD_START code sets up the pointer that gets to these + macros as COOKIE to point to two words: + [0] the argument to the entry point from the system (see nacl_startup.h) + [1] the stack base +*/ + +# define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \ + do { \ + uint32_t *_info = ((void **) (cookie))[0]; \ + (argc) = nacl_startup_argc (_info); \ + (argv) = nacl_startup_argv (_info); \ + (envp) = nacl_startup_envp (_info); \ + (auxp) = nacl_startup_auxv (_info); \ + } while (0) + +# define DL_STACK_END(cookie) (((void **) (cookie))[1]) + +/* This is called from the entry point (_start), defined by the RTLD_START + macro in the machine-specific dl-machine.h file. At this point, dynamic + linking has been completed and the first argument is the application's + entry point. */ +attribute_hidden internal_function __attribute__ ((noreturn)) +void +_dl_start_user (void (*user_entry) (uint32_t info[]), uint32_t info[]) +{ + if (_dl_skip_args > 0) + { + /* There are some arguments that the user program should not see. + Just slide up the INFO pointer so its NACL_STARTUP_ARGV points + to what should now be argv[0], and copy back the earlier fields. */ + assert (nacl_startup_argc (info) >= _dl_skip_args); + assert (NACL_STARTUP_ARGV == 3); + uint32_t envc = info[NACL_STARTUP_ENVC]; + uint32_t argc = info[NACL_STARTUP_ARGC]; + info += _dl_skip_args; + info[NACL_STARTUP_ENVC] = envc; + info[NACL_STARTUP_ARGC] = argc - _dl_skip_args; + } + + /* Pass our finalizer function to the user. */ + info[NACL_STARTUP_FINI] = (uintptr_t) &_dl_fini; + + /* Run initializers. */ + _dl_init (GL(dl_ns)[0]._ns_loaded, + nacl_startup_argc (info), + nacl_startup_argv (info), + nacl_startup_envp (info)); + + /* Call the user's entry point. This should never return. */ + (*user_entry) (info); + + /* Fail clearly just in case it did return. */ + __builtin_trap (); +} + +# define DL_SYSDEP_INIT __nacl_initialize_interfaces () + +#endif /* SHARED */ + +#include <elf/dl-sysdep.c> diff --git a/sysdeps/nacl/dl-sysdep.h b/sysdeps/nacl/dl-sysdep.h new file mode 100644 index 0000000..ade4213 --- /dev/null +++ b/sysdeps/nacl/dl-sysdep.h @@ -0,0 +1,30 @@ +/* System-specific settings for dynamic linker code. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +/* No multiple inclusion protection needed here because it's just macros. + We don't want to use _DL_SYSDEP_H in case we are #include_next'd. */ + +#include_next <dl-sysdep.h> + +/* We use AT_SYSINFO for a different purpose than Linux does, + but we too want to store its value. */ +#define NEED_DL_SYSINFO 1 +#define DL_SYSINFO_DEFAULT 0 + +/* sysdeps/arm/dl-sysdep.h defines this but it does not apply to NaCl. */ +#undef DL_ARGV_NOT_RELRO diff --git a/sysdeps/nacl/dl-unmap-segments.h b/sysdeps/nacl/dl-unmap-segments.h new file mode 100644 index 0000000..02851e7 --- /dev/null +++ b/sysdeps/nacl/dl-unmap-segments.h @@ -0,0 +1,65 @@ +/* Unmap a shared object's segments. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _DL_UNMAP_SEGMENTS_H +#define _DL_UNMAP_SEGMENTS_H 1 + +#include <link.h> +#include <sys/mman.h> + +/* There is always a big gap between the executable segment and the data + segments. Other code segments and data pages lie in there. So we must + unmap each segment individually (except for a codeless module). */ + +static void __always_inline +_dl_unmap_segments (struct link_map *l) +{ + if (l->l_contiguous) + /* Simple case. */ + __munmap ((void *) l->l_map_start, l->l_map_end - l->l_map_start); + else + { + /* Normally l_phdr points into the RODATA segment, which we will + unmap in one iteration of the loop. So we cannot use it directly + throughout. */ + + struct { ElfW(Addr) start, end; } segments[l->l_phnum], *seg = segments; + + for (const ElfW(Phdr) *ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph) + if (ph->p_type == PT_LOAD) + { + seg->start = (l->l_addr + ph->p_vaddr) & -GLRO(dl_pagesize); + seg->end = (l->l_addr + ph->p_vaddr + ph->p_memsz + + GLRO(dl_pagesize) - 1) & -GLRO(dl_pagesize); + if (seg > segments && seg[-1].end == seg->start) + /* Coalesce two adjacent segments into one munmap call. */ + seg[-1].end = seg->end; + else + ++seg; + } + + do + { + --seg; + __munmap ((void *) seg->start, seg->end - seg->start); + } + while (seg > segments); + } +} + +#endif /* dl-unmap-segments.h */ diff --git a/sysdeps/nacl/dl-writev.h b/sysdeps/nacl/dl-writev.h new file mode 100644 index 0000000..e61d9d1 --- /dev/null +++ b/sysdeps/nacl/dl-writev.h @@ -0,0 +1,45 @@ +/* Message-writing for the dynamic linker. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/uio.h> +#include <nacl-interfaces.h> + +/* This is used from only one place: dl-misc.c:_dl_debug_vdprintf. + Hence it's in a header with the expectation it will be inlined. + + This is writev, but with a constraint added and others loosened: + + 1. Under RTLD_PRIVATE_ERRNO, it must not clobber the private errno + when another thread holds the dl_load_lock. + 2. It is not obliged to detect and report errors at all. + 3. It's not really obliged to deliver a single atomic write + (though it may be preferable). */ + +static inline void +_dl_writev (int fd, const struct iovec *iov, size_t niov) +{ + for (size_t i = 0; i < niov; ++i) + { + size_t wrote; + if (__nacl_irt_fdio.write (fd, iov[i].iov_base, iov[i].iov_len, + &wrote) != 0 + || wrote != iov[i].iov_len) + /* The write failed, so don't bother trying any more. */ + break; + } +} diff --git a/sysdeps/nacl/dup.c b/sysdeps/nacl/dup.c new file mode 100644 index 0000000..1f66c52 --- /dev/null +++ b/sysdeps/nacl/dup.c @@ -0,0 +1,30 @@ +/* Duplicate a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + + +/* Duplicate FD, returning a new file descriptor open on the same file. */ +int +__dup (int fd) +{ + int result; + return NACL_CALL (__nacl_irt_fdio.dup (fd, &result), result); +} +weak_alias (__dup, dup) diff --git a/sysdeps/nacl/dup2.c b/sysdeps/nacl/dup2.c new file mode 100644 index 0000000..948a108 --- /dev/null +++ b/sysdeps/nacl/dup2.c @@ -0,0 +1,31 @@ +/* Duplicate a file descriptor to a chosen number. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + + +/* Duplicate FD to FD2, closing the old FD2 and making FD2 be + open the same file as FD is. Return FD2 or -1. */ +int +__dup2 (int fd, int fd2) +{ + return NACL_CALL (__nacl_irt_fdio.dup2 (fd, fd2), fd2); +} +libc_hidden_def (__dup2) +weak_alias (__dup2, dup2) diff --git a/sysdeps/nacl/entry.h b/sysdeps/nacl/entry.h new file mode 100644 index 0000000..e9dc190 --- /dev/null +++ b/sysdeps/nacl/entry.h @@ -0,0 +1,6 @@ +#ifndef __ASSEMBLY__ +# include <stdint.h> +extern void _start (uint32_t info[]) attribute_hidden; +#endif + +#define ENTRY_POINT _start diff --git a/sysdeps/nacl/errnos.awk b/sysdeps/nacl/errnos.awk new file mode 100644 index 0000000..65fa19b --- /dev/null +++ b/sysdeps/nacl/errnos.awk @@ -0,0 +1,87 @@ +# Script to produce bits/errno.h for NaCl. + +# Copyright (C) 2015 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. + +# 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, see +# <http://www.gnu.org/licenses/>. + +BEGIN { maxerrno = 0 } + +$1 == "#define" && $2 ~ /NACL_ABI_E[A-Z0-9_]+/ && $3 ~ /[0-9]+/ { + ename = $2; + sub(/NACL_ABI_/, "", ename); + errno = $3 + 0; + if (errno > maxerrno) maxerrno = errno; + errnos[errno] = ename; + errnos_by_name[ename] = errno; + if ($4 == "/*" && !(ename in errno_text)) { + etext = $5; + for (i = 6; i <= NF && $i != "*/"; ++i) + etext = etext " " $i; + errno_text[ename] = etext; + } + next; +} + +$1 == "@comment" && $2 == "errno.h" { errnoh=1; next } +errnoh == 1 && $1 == "@comment" { + ++errnoh; + etext = $3; + for (i = 4; i <= NF; ++i) + etext = etext " " $i; + next; +} +errnoh == 2 && $1 == "@deftypevr" && $2 == "Macro" && $3 == "int" { + ename = $4; + errno_text[ename] = etext; + next; +} + +function define_errno(errno, ename) { + etext = errno_text[ename]; + if (length(ename) < 8) ename = ename "\t"; + printf "#define\t%s\t%d\t/* %s */\n", ename, errno, etext; +} + +END { + print "\ +/* This file generated by errnos.awk. */\n\ +\n\ +#if !defined __Emath_defined && (defined _ERRNO_H || defined __need_Emath)\n\ +#undef __need_Emath\n\ +#define __Emath_defined 1"; + emath["EDOM"] = emath["EILSEQ"] = emath["ERANGE"] = 1; + for (ename in emath) { + errno = errnos_by_name[ename]; + define_errno(errno, ename); + delete errnos[errno]; + } + print "\ +#endif\n\ +\n\ +#ifdef _ERRNO_H\n"; + + for (i = 1; i <= maxerrno; ++i) + if (i in errnos) define_errno(i, errnos[i]); + + print "\n\ +#define EWOULDBLOCK EAGAIN\n\ +#define ENOTSUP EOPNOTSUPP\n\ +\n\ +extern __thread int errno __attribute__ ((__tls_model__ (\"initial-exec\")));\n\ +#define errno errno\n\ +\n\ +#endif"; +} diff --git a/sysdeps/nacl/euidaccess.c b/sysdeps/nacl/euidaccess.c new file mode 100644 index 0000000..036e736 --- /dev/null +++ b/sysdeps/nacl/euidaccess.c @@ -0,0 +1,27 @@ +/* Check file access permission. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> + +/* Test for access to FILE. */ +int +euidaccess (const char *file, int type) +{ + /* No NaCl process will ever be set-ID, so access and euidaccess are one. */ + return __access (file, type); +} diff --git a/sysdeps/nacl/exit-thread.h b/sysdeps/nacl/exit-thread.h new file mode 100644 index 0000000..a08a5b1 --- /dev/null +++ b/sysdeps/nacl/exit-thread.h @@ -0,0 +1,35 @@ +/* Call to terminate the current thread. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <stddef.h> +#include <nacl-interfaces.h> + +/* This causes the current thread to exit, without affecting other + threads in the process if there are any. If there are no other + threads left, then this has the effect of _exit (0). */ + +static inline void __attribute__ ((noreturn, always_inline, unused)) +__exit_thread (void) +{ + __nacl_irt_thread.thread_exit (NULL); + + /* That never returns unless something is severely and unrecoverably wrong. + If it ever does, try to make sure we crash. */ + while (1) + __builtin_trap (); +} diff --git a/sysdeps/nacl/fchdir.c b/sysdeps/nacl/fchdir.c new file mode 100644 index 0000000..4295bc2 --- /dev/null +++ b/sysdeps/nacl/fchdir.c @@ -0,0 +1,28 @@ +/* Change working directory given a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Change the current directory to FD. */ +int +__fchdir (int fd) +{ + return NACL_CALL (__nacl_irt_dev_fdio.fchdir (fd), 0); +} +weak_alias (__fchdir, fchdir) diff --git a/sysdeps/nacl/fchmod.c b/sysdeps/nacl/fchmod.c new file mode 100644 index 0000000..35d6939 --- /dev/null +++ b/sysdeps/nacl/fchmod.c @@ -0,0 +1,28 @@ +/* Change a file's permissions given a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Change the permissions of the file referenced by FD to MODE. */ +int +__fchmod (int fd, mode_t mode) +{ + return NACL_CALL (__nacl_irt_dev_fdio.fchmod (fd, mode), 0); +} +weak_alias (__fchmod, fchmod) diff --git a/sysdeps/nacl/fdatasync.c b/sysdeps/nacl/fdatasync.c new file mode 100644 index 0000000..cd7a55f --- /dev/null +++ b/sysdeps/nacl/fdatasync.c @@ -0,0 +1,28 @@ +/* Make all changes done to file data actually appear on disk. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Synchronize at least the data part of a file with the underlying + media. */ +int +fdatasync (int fd) +{ + return NACL_CALL (__nacl_irt_dev_fdio.fdatasync (fd), 0); +} diff --git a/sysdeps/nacl/fork.c b/sysdeps/nacl/fork.c new file mode 100644 index 0000000..9f06944 --- /dev/null +++ b/sysdeps/nacl/fork.c @@ -0,0 +1,3 @@ +/* Get the stub, bypassing the "generic" NPTL code. */ +#include <posix/fork.c> +strong_alias (__fork, __libc_fork) diff --git a/sysdeps/nacl/fsync.c b/sysdeps/nacl/fsync.c new file mode 100644 index 0000000..6f6622b --- /dev/null +++ b/sysdeps/nacl/fsync.c @@ -0,0 +1,27 @@ +/* Make all changes done to FD actually appear on disk. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Make all changes done to FD actually appear on disk. */ +int +fsync (int fd) +{ + return NACL_CALL (__nacl_irt_dev_fdio.fsync (fd), 0); +} diff --git a/sysdeps/nacl/ftruncate.c b/sysdeps/nacl/ftruncate.c new file mode 100644 index 0000000..1235f0d --- /dev/null +++ b/sysdeps/nacl/ftruncate.c @@ -0,0 +1,32 @@ +/* Truncate a file. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Truncate the file referenced by FD to LENGTH bytes. */ +int +__ftruncate (int fd, off_t length) +{ + return NACL_CALL (__nacl_irt_dev_fdio.ftruncate (fd, length), 0); +} +weak_alias (__ftruncate, ftruncate) + +/* ftruncate64 is the same as ftruncate. */ +strong_alias (__ftruncate, __ftruncate64) +weak_alias (__ftruncate64, ftruncate64) diff --git a/sysdeps/nacl/ftruncate64.c b/sysdeps/nacl/ftruncate64.c new file mode 100644 index 0000000..e40129a --- /dev/null +++ b/sysdeps/nacl/ftruncate64.c @@ -0,0 +1 @@ +/* ftruncate64 is the same as ftruncate. */ diff --git a/sysdeps/nacl/fxstat.c b/sysdeps/nacl/fxstat.c new file mode 100644 index 0000000..d9f3d20 --- /dev/null +++ b/sysdeps/nacl/fxstat.c @@ -0,0 +1,45 @@ +/* Get stat information from a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +/* Avoid the declaration so the compiler doesn't complain about the alias + with a different type signature. It doesn't know that 'struct stat' + and 'struct stat64' are ABI-compatible. */ +#define __fxstat64 __fxstat64_avoid +#include <sys/stat.h> +#undef __fxstat64 + +#include <errno.h> +#include <stddef.h> + +#include <xstatconv.h> + +#undef fstat + +/* Get information about the file descriptor FD in BUF. */ +int +__fxstat (int vers, int fd, struct stat *buf) +{ + nacl_abi_stat_t abi_buf; + return NACL_CALL (__nacl_irt_fdio.fstat (fd, &abi_buf), + __xstat_conv (vers, &abi_buf, buf)); +} +hidden_def (__fxstat) +weak_alias (__fxstat, _fxstat) + +strong_alias (__fxstat, __fxstat64) +hidden_ver (__fxstat, __fxstat64) diff --git a/sysdeps/nacl/fxstat64.c b/sysdeps/nacl/fxstat64.c new file mode 100644 index 0000000..72aae12 --- /dev/null +++ b/sysdeps/nacl/fxstat64.c @@ -0,0 +1 @@ +/* fxstat.c defines __fxstat64 as an alias. */ diff --git a/sysdeps/nacl/getcwd.c b/sysdeps/nacl/getcwd.c new file mode 100644 index 0000000..ba7e49a --- /dev/null +++ b/sysdeps/nacl/getcwd.c @@ -0,0 +1,56 @@ +/* Get current working directory. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <limits.h> +#include <stdlib.h> +#include <nacl-interfaces.h> + +/* Get the pathname of the current working directory, + and put it in SIZE bytes of BUF. Returns NULL if the + directory couldn't be determined or SIZE was too small. + If successful, returns BUF. In GNU, if BUF is NULL, + an array is allocated with `malloc'; the array is SIZE + bytes long, unless SIZE <= 0, in which case it is as + big as necessary. */ +char * +__getcwd (char *buf, size_t size) +{ + char *use_buf = buf; + + if (buf == NULL) + { + if (size == 0) + size = PATH_MAX; + use_buf = malloc (size); + if (__glibc_unlikely (use_buf == NULL)) + return NULL; + } + + int error = __nacl_irt_dev_filename.getcwd (use_buf, size); + if (__glibc_unlikely (error)) + { + if (use_buf != buf) + free (use_buf); + errno = error; + return NULL; + } + + return use_buf; +} +weak_alias (__getcwd, getcwd) diff --git a/sysdeps/nacl/getdents.c b/sysdeps/nacl/getdents.c new file mode 100644 index 0000000..e022b6b --- /dev/null +++ b/sysdeps/nacl/getdents.c @@ -0,0 +1,29 @@ +/* Read directory entries from a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <dirent.h> +#include <nacl-interfaces.h> + +ssize_t +internal_function +__getdents (int fd, char *buf, size_t nbytes) +{ + size_t nread; + return NACL_CALL (__nacl_irt_fdio.getdents (fd, (void *) buf, nbytes, &nread), + nread); +} diff --git a/sysdeps/nacl/getdents64.c b/sysdeps/nacl/getdents64.c new file mode 100644 index 0000000..7308618 --- /dev/null +++ b/sysdeps/nacl/getdents64.c @@ -0,0 +1 @@ +/* We do not define a getdirentries or getdirentries64 entry point at all. */ diff --git a/sysdeps/nacl/getdtsz.c b/sysdeps/nacl/getdtsz.c new file mode 100644 index 0000000..31c9978 --- /dev/null +++ b/sysdeps/nacl/getdtsz.c @@ -0,0 +1,28 @@ +/* getdtablesize -- Return the limit on file descriptor values. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> + +/* Return the maximum number of file descriptors + the current process could possibly have. */ +int +__getdtablesize (void) +{ + /* There is no actual limit in NaCl, just memory. */ + return -1; +} diff --git a/sysdeps/nacl/getpagesize.c b/sysdeps/nacl/getpagesize.c new file mode 100644 index 0000000..0be1ccf --- /dev/null +++ b/sysdeps/nacl/getpagesize.c @@ -0,0 +1 @@ +#include <sysdeps/unix/getpagesize.c> diff --git a/sysdeps/nacl/getpid.c b/sysdeps/nacl/getpid.c new file mode 100644 index 0000000..1b6d2d5 --- /dev/null +++ b/sysdeps/nacl/getpid.c @@ -0,0 +1,32 @@ +/* Get the process ID of the calling process. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Get the process ID of the calling process. */ +pid_t +__getpid (void) +{ + int pid; + return NACL_CALL (__nacl_irt_dev_getpid.getpid (&pid), pid); +} +libc_hidden_def (__getpid) +weak_alias (__getpid, getpid) +libc_hidden_weak (getpid) diff --git a/sysdeps/nacl/getsysstats.c b/sysdeps/nacl/getsysstats.c new file mode 100644 index 0000000..97a2edb --- /dev/null +++ b/sysdeps/nacl/getsysstats.c @@ -0,0 +1,65 @@ +/* getsysstats - Determine various system internal values. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <sys/sysinfo.h> +#include <nacl-interfaces.h> + +#undef __native_client__ +#include "native_client/src/trusted/service_runtime/include/sys/unistd.h" + + +int +__get_nprocs_conf (void) +{ + int nprocs; + if (__nacl_irt_basic.sysconf (NACL_ABI__SC_NPROCESSORS_ONLN, &nprocs) != 0) + /* On failure (which should be impossible), just report one processor. */ + nprocs = 1; + return nprocs; +} +weak_alias (__get_nprocs_conf, get_nprocs_conf) + +int +__get_nprocs (void) +{ + return __get_nprocs_conf (); +} +weak_alias (__get_nprocs, get_nprocs) + + +long int +__get_phys_pages (void) +{ + /* We have no general way to determine this value. */ + __set_errno (ENOSYS); + return -1; +} +weak_alias (__get_phys_pages, get_phys_pages) +stub_warning (get_phys_pages) + + +long int +__get_avphys_pages (void) +{ + /* We have no general way to determine this value. */ + __set_errno (ENOSYS); + return -1; +} +weak_alias (__get_avphys_pages, get_avphys_pages) +stub_warning (get_avphys_pages) diff --git a/sysdeps/nacl/gettimeofday.c b/sysdeps/nacl/gettimeofday.c new file mode 100644 index 0000000..9fb8dab --- /dev/null +++ b/sysdeps/nacl/gettimeofday.c @@ -0,0 +1,40 @@ +/* Get the current wall clock time. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <sys/time.h> +#include <nacl-interfaces.h> + + +/* Get the current time of day and timezone information, + putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. + Returns 0 on success, -1 on errors. */ +int +__gettimeofday (struct timeval *tv, struct timezone *tz) +{ + if (__glibc_unlikely (tz != NULL)) + { + tz->tz_minuteswest = 0; + tz->tz_dsttime = 0; + } + + return NACL_CALL (__nacl_irt_basic.gettod (tv), 0); +} +libc_hidden_def (__gettimeofday) +weak_alias (__gettimeofday, gettimeofday) +libc_hidden_weak (gettimeofday) diff --git a/sysdeps/nacl/glob.c b/sysdeps/nacl/glob.c new file mode 100644 index 0000000..36d62e8 --- /dev/null +++ b/sysdeps/nacl/glob.c @@ -0,0 +1,26 @@ +/* Do glob searching. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> /* Declares getlogin_r. */ + +/* We do not have getlogin_r in the library at all for NaCl. + Define it away so the glob code does not try to use it. */ +#define getlogin_r(name, len) (ENOSYS) + +/* Fetch the version that defines glob64 as an alias. */ +#include <sysdeps/wordsize-64/glob.c> diff --git a/sysdeps/nacl/glob64.c b/sysdeps/nacl/glob64.c new file mode 100644 index 0000000..adca2d4 --- /dev/null +++ b/sysdeps/nacl/glob64.c @@ -0,0 +1 @@ +#include <sysdeps/wordsize-64/glob64.c> diff --git a/sysdeps/nacl/ifaddrs.c b/sysdeps/nacl/ifaddrs.c new file mode 100644 index 0000000..0e64851 --- /dev/null +++ b/sysdeps/nacl/ifaddrs.c @@ -0,0 +1,2 @@ +/* Bypass the sysdeps/gnu version to get the plain stub. */ +#include <inet/ifaddrs.c> diff --git a/sysdeps/nacl/init-first.c b/sysdeps/nacl/init-first.c new file mode 100644 index 0000000..5830c6f --- /dev/null +++ b/sysdeps/nacl/init-first.c @@ -0,0 +1,27 @@ +/* Initialization code run first thing by the ELF startup code. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifdef SHARED + +# include <nacl-interfaces.h> + +# define VDSO_SETUP __nacl_initialize_interfaces + +#endif + +#include <csu/init-first.c> diff --git a/sysdeps/nacl/iofdopen.c b/sysdeps/nacl/iofdopen.c new file mode 100644 index 0000000..fd5271f --- /dev/null +++ b/sysdeps/nacl/iofdopen.c @@ -0,0 +1,26 @@ +/* Open a stream from a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <fcntl.h> + +/* NaCl does not have a functioning fcntl, so don't use the stub and fail. */ +#undef F_GETFL +#undef F_SETFL +#define __fcntl(...) ???should not be called??? + +#include <libio/iofdopen.c> diff --git a/sysdeps/nacl/irt.sed b/sysdeps/nacl/irt.sed new file mode 100644 index 0000000..0abe177 --- /dev/null +++ b/sysdeps/nacl/irt.sed @@ -0,0 +1,12 @@ +# This sed script massages native_client/src/untrusted/irt/irt.h into +# the nacl-irt.h used to build libc, by rewriting foo_t and struct bar +# to nacl_abi_foo_t and nacl_abi_bar_t (and eliding forward declarations). +# It doesn't perturb any struct CamelCaps cases, since such names will +# be used only in NaCl-specific interfaces. +/^struct \([a-z][a-z]*\);$/d +/^#include "irt\.h"$/d +/(/!b +s/\([a-z0-9_][a-z0-9_]*\)_t\>/nacl_abi_\1_t/g +s/struct \([a-z0-9_][a-z0-9_]*\)/nacl_abi_\1_t/g +s/nacl_abi_\(u*int[3264ptr]*_t\)/\1/g +s/nacl_abi_\(nacl_irt_\)/\1/g diff --git a/sysdeps/nacl/isatty.c b/sysdeps/nacl/isatty.c new file mode 100644 index 0000000..fc1a686 --- /dev/null +++ b/sysdeps/nacl/isatty.c @@ -0,0 +1,38 @@ +/* Determine if a file descriptor refers to a terminal. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Return 1 if FD is a terminal, 0 if not. */ +int +__isatty (int fd) +{ + int result; + int error = __nacl_irt_dev_fdio.isatty (fd, &result); + if (error == 0) + { + if (result) + return 1; + error = ENOTTY; + } + errno = error; + return 0; +} +weak_alias (__isatty, isatty) diff --git a/sysdeps/nacl/kernel-features.h b/sysdeps/nacl/kernel-features.h new file mode 100644 index 0000000..3ae983d --- /dev/null +++ b/sysdeps/nacl/kernel-features.h @@ -0,0 +1,28 @@ +/* Set flags signalling availability of certain operating system features. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +/* This file can define __ASSUME_* macros checked by certain source files. + Almost none of these are used outside of sysdeps/unix/sysv/linux code. + But those referring to POSIX-level features like O_* flags can be. */ + +#define __ASSUME_O_CLOEXEC 1 + +/* +#define __ASSUME_DUP3 1 +#define __ASSUME_ACCEPT4 1 +*/ diff --git a/sysdeps/nacl/ldsodefs.h b/sysdeps/nacl/ldsodefs.h new file mode 100644 index 0000000..383ced5 --- /dev/null +++ b/sysdeps/nacl/ldsodefs.h @@ -0,0 +1,35 @@ +/* Run-time dynamic linker data structures for loaded ELF shared objects. NaCl. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _LDSODEFS_H + +/* Get the real definitions. */ +#include_next <ldsodefs.h> + +/* Now define our stuff. */ + +/* We have the auxiliary vector. */ +#define HAVE_AUX_VECTOR 1 + +/* Used by static binaries to check the auxiliary vector. */ +extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function; + +/* Initialization which is normally done by the dynamic linker. */ +extern void _dl_non_dynamic_init (void) internal_function; + +#endif /* ldsodefs.h */ diff --git a/sysdeps/nacl/libc-start.c b/sysdeps/nacl/libc-start.c new file mode 100644 index 0000000..dadd180 --- /dev/null +++ b/sysdeps/nacl/libc-start.c @@ -0,0 +1,4 @@ +/* We can compute the location of auxv without a loop, so we might as well + pass it in. */ +#define LIBC_START_MAIN_AUXVEC_ARG +#include <csu/libc-start.c> diff --git a/sysdeps/nacl/link.c b/sysdeps/nacl/link.c new file mode 100644 index 0000000..49f071f --- /dev/null +++ b/sysdeps/nacl/link.c @@ -0,0 +1,28 @@ +/* Make a hard link. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Make a link to FROM called TO. */ +int +__link (const char *from, const char *to) +{ + return NACL_CALL (__nacl_irt_dev_filename.link (from, to), 0); +} +weak_alias (__link, link) diff --git a/sysdeps/nacl/lowlevellock-futex.h b/sysdeps/nacl/lowlevellock-futex.h new file mode 100644 index 0000000..8d888a2 --- /dev/null +++ b/sysdeps/nacl/lowlevellock-futex.h @@ -0,0 +1,87 @@ +/* Low-level locking access to futex facilities. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _LOWLEVELLOCK_FUTEX_H +#define _LOWLEVELLOCK_FUTEX_H 1 + +#include <nacl-interfaces.h> +#include <time.h> + + +#pragma GCC diagnostic ignored "-Wunused-value" /* XXX */ + +/* Values for 'private' parameter of locking macros. Note pthreadP.h + optimizes for these exact values, though they are not required. */ +#define LLL_PRIVATE 0 +#define LLL_SHARED 128 + +#define FUTEX_PRIVATE_FLAG 0 /* XXX */ + + +/* Wait while *FUTEXP == VAL for an lll_futex_wake call on FUTEXP. */ +#define lll_futex_wait(futexp, val, private) \ + (- __nacl_irt_futex.futex_wait_abs ((volatile int *) (futexp), val, NULL)) + +/* Wait until a lll_futex_wake call on FUTEXP, or TIMEOUT elapses. */ +#define lll_futex_timed_wait(futexp, val, timeout, private) \ + ({ \ + /* This timeout is relative, but the IRT call wants it absolute. */ \ + const struct timespec *_to = (timeout); \ + struct timespec _ts; \ + int _err = 0; \ + if (_to != NULL \ + && __glibc_likely ((_err = __nacl_irt_clock.clock_gettime \ + (CLOCK_REALTIME, &_ts)) == 0)) \ + { \ + _ts.tv_sec -= _to->tv_sec; \ + _ts.tv_nsec -= _to->tv_nsec; \ + while (_ts.tv_nsec < 0) \ + { \ + _ts.tv_nsec += 1000000000; \ + --_ts.tv_sec; \ + } \ + _to = &_ts; \ + } \ + if (_err == 0) \ + _err = __nacl_irt_futex.futex_wait_abs \ + ((volatile int *) (futexp), val, _to); \ + -_err; \ + }) + +/* Wake up up to NR waiters on FUTEXP. */ +#define lll_futex_wake(futexp, nr, private) \ + ({ \ + int _woken; \ + - __nacl_irt_futex.futex_wake ((volatile int *) (futexp), nr, &_woken); \ + }) + +/* NaCl does not support the requeue operation. The only use of this is in + pthread_cond_broadcast, which handles an error return by falling back to + plain lll_futex_wake. */ +#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \ + ((futexp), (nr_wake), (nr_move), (mutex), (val), (private), -ENOSYS) + +/* NaCl does not support the special wake-unlock operation. The only use + of this is in pthread_cond_signal, which handles an error return by + falling back to plain lll_futex_wake. */ +/* Wake up up to NR_WAKE waiters on FUTEXP and NR_WAKE2 on FUTEXP2. */ +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ + ((futexp), (nr_wake), (nr_wake2), (futexp2), (private), -ENOSYS) + + +#endif /* lowlevellock-futex.h */ diff --git a/sysdeps/nacl/lseek.c b/sysdeps/nacl/lseek.c new file mode 100644 index 0000000..6451eb5 --- /dev/null +++ b/sysdeps/nacl/lseek.c @@ -0,0 +1,43 @@ +/* lseek -- Move the file position of a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + + +/* Seek to OFFSET on FD, starting from WHENCE. */ +off_t +__libc_lseek (int fd, off_t offset, int whence) +{ + off_t result; + int error = __nacl_irt_fdio.seek (fd, offset, whence, &result); + if (error) + { + __set_errno (error); + return -1; + } + return result; +} +libc_hidden_def (__lseek) +weak_alias (__libc_lseek, __lseek) +weak_alias (__libc_lseek, lseek) + +/* Since off64_t is the same as off_t, lseek64 is just an alias. */ +weak_alias (__libc_lseek, __libc_lseek64) +weak_alias (__libc_lseek, __lseek64) +weak_alias (__libc_lseek, lseek64) diff --git a/sysdeps/nacl/lseek64.c b/sysdeps/nacl/lseek64.c new file mode 100644 index 0000000..6f42ee6 --- /dev/null +++ b/sysdeps/nacl/lseek64.c @@ -0,0 +1 @@ +/* lseek.c defines lseek64 as an alias. */ diff --git a/sysdeps/nacl/lxstat.c b/sysdeps/nacl/lxstat.c new file mode 100644 index 0000000..b147085 --- /dev/null +++ b/sysdeps/nacl/lxstat.c @@ -0,0 +1,46 @@ +/* Get stat information from a file name NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +/* Avoid the declaration so the compiler doesn't complain about the alias + with a different type signature. It doesn't know that 'struct stat' + and 'struct stat64' are ABI-compatible. */ +#define __lxstat64 __lxstat64_avoid +#include <sys/stat.h> +#undef __lxstat64 + +#include <errno.h> +#include <stddef.h> + +#include <xstatconv.h> + +#undef lstat + +/* Get file attributes about FILE and put them in BUF. + If FILE is a symbolic link, do not follow it. */ +int +__lxstat (int vers, const char *file, struct stat *buf) +{ + nacl_abi_stat_t abi_buf; + return NACL_CALL (__nacl_irt_dev_filename.lstat (file, &abi_buf), + __xstat_conv (vers, &abi_buf, buf)); +} +hidden_def (__lxstat) +weak_alias (__lxstat, _lxstat) + +strong_alias (__lxstat, __lxstat64) +hidden_ver (__lxstat, __lxstat64) diff --git a/sysdeps/nacl/lxstat64.c b/sysdeps/nacl/lxstat64.c new file mode 100644 index 0000000..ca4ecd2 --- /dev/null +++ b/sysdeps/nacl/lxstat64.c @@ -0,0 +1 @@ +/* lxstat.c defines __lxstat64 as an alias. */ diff --git a/sysdeps/nacl/mkdir.c b/sysdeps/nacl/mkdir.c new file mode 100644 index 0000000..73b4748 --- /dev/null +++ b/sysdeps/nacl/mkdir.c @@ -0,0 +1,28 @@ +/* Make a directory. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/stat.h> +#include <nacl-interfaces.h> + +/* Create a directory named PATH with protections MODE. */ +int +__mkdir (const char *path, mode_t mode) +{ + return NACL_CALL (__nacl_irt_dev_filename.mkdir (path, mode), 0); +} +weak_alias (__mkdir, mkdir) diff --git a/sysdeps/nacl/mmap.c b/sysdeps/nacl/mmap.c new file mode 100644 index 0000000..e9c5326 --- /dev/null +++ b/sysdeps/nacl/mmap.c @@ -0,0 +1,49 @@ +/* Map addresses from a file or anonymous memory. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <sys/mman.h> +#include <nacl-interfaces.h> + + +/* Map addresses starting near ADDR and extending for LEN bytes. From + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or MAP_FAILED + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +__ptr_t +__mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + int error = __nacl_irt_memory.mmap (&addr, len, prot, flags, fd, offset); + if (error) + { + errno = error; + return MAP_FAILED; + } + return addr; +} +weak_alias (__mmap, mmap) + + +/* Since off64_t is the same as off_t, mmap64 is just an alias. */ +strong_alias (__mmap, __mmap64) +weak_alias (__mmap, mmap64) diff --git a/sysdeps/nacl/mmap64.c b/sysdeps/nacl/mmap64.c new file mode 100644 index 0000000..e8775a6 --- /dev/null +++ b/sysdeps/nacl/mmap64.c @@ -0,0 +1 @@ +/* mmap.c defines mmap64 as an alias. */ diff --git a/sysdeps/nacl/mprotect.c b/sysdeps/nacl/mprotect.c new file mode 100644 index 0000000..6fd6a4d --- /dev/null +++ b/sysdeps/nacl/mprotect.c @@ -0,0 +1,33 @@ +/* Change memory protections on pages. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <nacl-interfaces.h> + + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors + (and sets errno). */ + +int +__mprotect (__ptr_t addr, size_t len, int prot) +{ + return NACL_CALL (__nacl_irt_memory.mprotect (addr, len, prot), 0); +} +weak_alias (__mprotect, mprotect) diff --git a/sysdeps/nacl/munmap.c b/sysdeps/nacl/munmap.c new file mode 100644 index 0000000..194e409 --- /dev/null +++ b/sysdeps/nacl/munmap.c @@ -0,0 +1,32 @@ +/* Deallocate a region of pages. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/mman.h> +#include <nacl-interfaces.h> + + +/* Deallocate any mapping for the region starting at ADDR and extending LEN + bytes. Returns 0 if successful, -1 for errors (and sets errno). */ + +int +__munmap (__ptr_t addr, size_t len) +{ + return NACL_CALL (__nacl_irt_memory.munmap (addr, len), 0); +} + +weak_alias (__munmap, munmap) diff --git a/sysdeps/nacl/nacl-after-link.sh b/sysdeps/nacl/nacl-after-link.sh new file mode 100755 index 0000000..199f1b8 --- /dev/null +++ b/sysdeps/nacl/nacl-after-link.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# Script to validate NaCl binaries after linking. + +# Copyright (C) 2015 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. + +# 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, see +# <http://www.gnu.org/licenses/>. + +# See sysdeps/nacl/Makefile for how this script is invoked. +READELF="$1" +binary="$2" + +if [ -z "$NACL_SDK_ROOT" ]; then + echo >&2 "$0: NACL_SDK_ROOT must be set in the environment" + exit 77 +fi + +ncval="${NACL_SDK_ROOT}/tools/ncval" + +if [ ! -x "$ncval" ]; then + echo >&2 "$0: No ncval binary in $ncval" + exit 77 +fi + +"${READELF}" -Wl "$binary" | awk ' +BEGIN { saw_load = saw_text = 0 } +$1 == "LOAD" { + saw_load = 1; + if (/ R.E /) saw_code = 1; +} +END { + exit (saw_code ? 11 : saw_load ? 22 : 1); +} +' +case $? in +11) + # We saw a code segment, so we can try ncval. + ;; +22) + # We saw LOAD segments but none of them were code. + echo >&2 "+++ No code: $binary" + exit 0 + ;; +*) + # Something funny going on. + echo >&2 "*** Failed to analyze: $binary" + exit 2 + ;; +esac + +if "$ncval" "$binary"; then + echo >&2 "+++ Validated: $binary" + exit 0 +else + echo >&2 "*** Validation failed: $binary" + exit 2 +fi diff --git a/sysdeps/nacl/nacl-interface-list.h b/sysdeps/nacl/nacl-interface-list.h new file mode 100644 index 0000000..d098147 --- /dev/null +++ b/sysdeps/nacl/nacl-interface-list.h @@ -0,0 +1,47 @@ +/* List of NaCl interface tables used in libraries. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +NACL_MANDATORY_INTERFACE (rtld, + NACL_IRT_BASIC_v0_1, nacl_irt_basic) +NACL_MANDATORY_INTERFACE (rtld, + NACL_IRT_FDIO_v0_1, nacl_irt_fdio) +NACL_MANDATORY_INTERFACE (rtld, + NACL_IRT_FILENAME_v0_1, nacl_irt_filename) +NACL_MANDATORY_INTERFACE (rtld, + NACL_IRT_MEMORY_v0_3, nacl_irt_memory) +NACL_MANDATORY_INTERFACE (libc, + NACL_IRT_THREAD_v0_1, nacl_irt_thread) +NACL_MANDATORY_INTERFACE (rtld, + NACL_IRT_FUTEX_v0_1, nacl_irt_futex) +NACL_MANDATORY_INTERFACE (rtld, + NACL_IRT_TLS_v0_1, nacl_irt_tls) +NACL_MANDATORY_INTERFACE (libc, + NACL_IRT_RESOURCE_OPEN_v0_1, nacl_irt_resource_open) +NACL_MANDATORY_INTERFACE (rtld, + NACL_IRT_CODE_DATA_ALLOC_v0_1, + nacl_irt_code_data_alloc) +NACL_OPTIONAL_INTERFACE (libc, + NACL_IRT_CLOCK_v0_1, nacl_irt_clock) +NACL_OPTIONAL_INTERFACE (rtld, + NACL_IRT_DYNCODE_v0_1, nacl_irt_dyncode) +NACL_OPTIONAL_INTERFACE (rtld, + NACL_IRT_DEV_GETPID_v0_1, nacl_irt_dev_getpid) +NACL_OPTIONAL_INTERFACE (rtld, + NACL_IRT_DEV_FILENAME_v0_3, nacl_irt_dev_filename) +NACL_OPTIONAL_INTERFACE (libc, + NACL_IRT_DEV_FDIO_v0_3, nacl_irt_dev_fdio) diff --git a/sysdeps/nacl/nacl-interface-table.c b/sysdeps/nacl/nacl-interface-table.c new file mode 100644 index 0000000..e540198 --- /dev/null +++ b/sysdeps/nacl/nacl-interface-table.c @@ -0,0 +1,43 @@ +/* Define one NaCl interface table. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include "nacl-interfaces.h" + +#define PASTE(a, b) PASTE_1 (a, b) +#define PASTE_1(a, b) a##b +#define STRINGIFY(x) STRINGIFY_1 (x) +#define STRINGIFY_1(x) #x + +#if IS_IN (rtld) && PASTE (MODULE_, INTERFACE_MODULE) != MODULE_rtld +# error "This interface is also needed in rtld." +#endif + +#define SECTION(which) \ + section ("nacl_" STRINGIFY (INTERFACE_CATEGORY) "_interface_" #which) + +static const struct nacl_interface PASTE (desc_, INTERFACE_TYPE) + __attribute__ ((used, SECTION (names))) = +{ + .table_size = sizeof (struct INTERFACE_TYPE), + .namelen = sizeof INTERFACE_STRING, + .name = INTERFACE_STRING +}; + +struct INTERFACE_TYPE PASTE (__, INTERFACE_TYPE) + __attribute__ ((SECTION (tables))); +PASTE (INTERFACE_MODULE, _hidden_data_def) (PASTE (__, INTERFACE_TYPE)) diff --git a/sysdeps/nacl/nacl-interfaces.c b/sysdeps/nacl/nacl-interfaces.c new file mode 100644 index 0000000..cb0dcd0 --- /dev/null +++ b/sysdeps/nacl/nacl-interfaces.c @@ -0,0 +1,123 @@ +/* Using NaCl interface tables. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <nacl-interfaces.h> +#include <ldsodefs.h> + + +/* These magic symbols are provided implicitly by the linker to + give us the bounds of the specially-named sections. */ + +extern const struct nacl_interface __start_nacl_mandatory_interface_names[] + attribute_hidden; +extern const struct nacl_interface __stop_nacl_mandatory_interface_names[] + attribute_hidden; + +extern uintptr_t __start_nacl_mandatory_interface_tables[] + attribute_hidden; +extern uintptr_t __stop_nacl_mandatory_interface_tables[] + attribute_hidden; + +/* We use weak references for the optional ones, since they + might not be included at all in any given statically-linked program. */ + +extern const struct nacl_interface __start_nacl_optional_interface_names[] + attribute_hidden __attribute__ ((weak)); +extern const struct nacl_interface __stop_nacl_optional_interface_names[] + attribute_hidden __attribute__ ((weak)); + +extern uintptr_t __start_nacl_optional_interface_tables[] + attribute_hidden __attribute__ ((weak)); +extern uintptr_t __stop_nacl_optional_interface_tables[] + attribute_hidden __attribute__ ((weak)); + +static uintptr_t * +next_nacl_table (uintptr_t *t, const struct nacl_interface *i) +{ + return (void *) t + i->table_size; +} + +static void __attribute__ ((noreturn)) +missing_mandatory_interface (const struct nacl_interface *i) +{ + static const char before[] = + "FATAL: NaCl IRT interface query failed for essential interface \""; + static const char after[] = + "\"\n"; + + if (__nacl_irt_fdio.write != NULL) + { + size_t wrote; + (*__nacl_irt_fdio.write) (2, before, sizeof before - 1, &wrote); + (*__nacl_irt_fdio.write) (2, i->name, i->namelen - 1, &wrote); + (*__nacl_irt_fdio.write) (2, after, sizeof after - 1, &wrote); + } + + if (__nacl_irt_basic.exit != NULL) + (*__nacl_irt_basic.exit) (-1); + + __builtin_trap (); +} + +static void +initialize_mandatory_interfaces (void) +{ + const struct nacl_interface *i = __start_nacl_mandatory_interface_names; + uintptr_t *t = __start_nacl_mandatory_interface_tables; + while (i < __stop_nacl_mandatory_interface_names) + { + if (__nacl_irt_query (i->name, t, i->table_size) != i->table_size) + missing_mandatory_interface (i); + + t = next_nacl_table (t, i); + i = next_nacl_interface (i); + } +} + + +static int +nacl_missing_optional_interface (void) +{ + return ENOSYS; +} + +static void +initialize_optional_interfaces (void) +{ + const struct nacl_interface *i = __start_nacl_optional_interface_names; + uintptr_t *t = __start_nacl_optional_interface_tables; + while (i < __stop_nacl_optional_interface_names) + { + size_t filled = __nacl_irt_query (i->name, t, i->table_size); + if (filled != i->table_size) + for (size_t slot = 0; slot < i->table_size / sizeof *t; ++slot) + t[slot] = (uintptr_t) &nacl_missing_optional_interface; + + t = next_nacl_table (t, i); + i = next_nacl_interface (i); + } +} + + +void attribute_hidden +__nacl_initialize_interfaces (void) +{ + initialize_mandatory_interfaces (); + initialize_optional_interfaces (); +} diff --git a/sysdeps/nacl/nacl-interfaces.h b/sysdeps/nacl/nacl-interfaces.h new file mode 100644 index 0000000..8d28e1a --- /dev/null +++ b/sysdeps/nacl/nacl-interfaces.h @@ -0,0 +1,108 @@ +/* Using NaCl interface tables. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _NACL_INTERFACES_H +#define _NACL_INTERFACES_H 1 + +#include <errno.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +/* <nacl-irt.h> is massaged from native_client/src/untrusted/irt/irt.h so + that it uses nacl_abi_*_t type names. We must define those types first. */ + +/* These are the same in the IRT ABI as in the libc ABI. */ +typedef blksize_t nacl_abi_blksize_t; +typedef dev_t nacl_abi_dev_t; +typedef gid_t nacl_abi_gid_t; +typedef ino_t nacl_abi_ino_t; +typedef mode_t nacl_abi_mode_t; +typedef nlink_t nacl_abi_nlink_t; +typedef size_t nacl_abi_size_t; +typedef time_t nacl_abi_time_t; +typedef uid_t nacl_abi_uid_t; +typedef struct dirent nacl_abi_dirent_t; +typedef struct timeval nacl_abi_timeval_t; +typedef struct timespec nacl_abi_timespec_t; + +/* XXX change clock_t? */ +typedef uint32_t nacl_abi_clock_t; + +typedef int32_t nacl_abi_blkcnt_t; + +/* This is different by design. */ +typedef struct nacl_abi_stat nacl_abi_stat_t; + +#include <nacl-irt.h> + +/* This is how we access the IRT interface-query function. + This formulation makes it usable as if it were a function name. */ +#define __nacl_irt_query (*(TYPE_nacl_irt_query) GLRO(dl_sysinfo)) + + +/* This describes one IRT (or IRT-like) interface that libc uses. + This structure contains no pointers, so it can go into rodata + without relocs. Instead, the actual tables we use for these + interfaces live in a parallel section in writable data. */ +struct nacl_interface { + size_t table_size; + size_t namelen; + char name[]; +}; + +/* Increment for 'const struct nacl_interface *' pointers. */ +static inline const struct nacl_interface * +next_nacl_interface (const struct nacl_interface *i) +{ + uintptr_t align = __alignof (*i); + return (const void *) (((uintptr_t) &i->name[i->namelen] + align - 1) + & -align); +} + +#if IS_IN (libpthread) +# define libpthread_hidden_proto(name) hidden_proto (name) +#else +# define libpthread_hidden_proto(name) +#endif + +#define DECLARE_INTERFACE(module, type) \ + extern struct type __##type; module##_hidden_proto (__##type); + +#define NACL_MANDATORY_INTERFACE(module, id, type) \ + DECLARE_INTERFACE (module, type) +#define NACL_OPTIONAL_INTERFACE(module, id, type) \ + DECLARE_INTERFACE (module, type) +#include "nacl-interface-list.h" +#undef NACL_MANDATORY_INTERFACE +#undef NACL_OPTIONAL_INTERFACE + +extern void __nacl_initialize_interfaces (void) attribute_hidden; + +/* Convenience function for handling IRT call return values. */ +static inline int +__nacl_fail (int err) +{ + errno = err; + return -1; +} + +#define NACL_CALL(err, val) \ + ({ int _err = (err); _err ? __nacl_fail (_err) : (val); }) + +#endif /* nacl-interfaces.h */ diff --git a/sysdeps/nacl/nacl-interfaces.mk.in b/sysdeps/nacl/nacl-interfaces.mk.in new file mode 100644 index 0000000..92ff3c6 --- /dev/null +++ b/sysdeps/nacl/nacl-interfaces.mk.in @@ -0,0 +1,25 @@ +/* Might as well be -*- C -*-. + + This generates a makefile that sets the variable pairs + nacl-MODULE-mandatory-interfaces and nacl-MODULE-optional-interfaces + based on the nacl-interface-list.h list. */ + +%define NACL_MANDATORY_INTERFACE(module, id, type) \ + nacl-mandatory-interfaces += module-type +%define NACL_OPTIONAL_INTERFACE(module, id, type) \ + nacl-optional-interfaces += module-type + +%include "nacl-interface-list.h" + +%undef NACL_MANDATORY_INTERFACE +%undef NACL_OPTIONAL_INTERFACE + +%define NACL_MANDATORY_INTERFACE(module, id, type) \ + nacl-module-type-string := id +%define NACL_OPTIONAL_INTERFACE(module, id, type) \ + nacl-module-type-string := id + +%include "nacl-interface-list.h" + +%undef NACL_MANDATORY_INTERFACE +%undef NACL_OPTIONAL_INTERFACE diff --git a/sysdeps/nacl/nacl-test-wrapper.sh b/sysdeps/nacl/nacl-test-wrapper.sh new file mode 100755 index 0000000..0e05813 --- /dev/null +++ b/sysdeps/nacl/nacl-test-wrapper.sh @@ -0,0 +1,280 @@ +#!/bin/bash +# test-wrapper script for NaCl. + +# Copyright (C) 2015 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. + +# 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, see +# <http://www.gnu.org/licenses/>. + +progname="$(basename "$0")" + +usage="usage: ${progname} --arch=ARCH [VAR=VAL...] COMMAND ..." +help=" +" + +use_bootstrap=true +arch= +env=() +envi=0 +while [ $# -gt 0 ]; do + case "$1" in + + --help) + echo "$usage" + echo "$help" + exit 0 + ;; + + --arch=*) + arch="${1#--arch=}" + shift + ;; + + *=*) + env[envi++]='-E' + env[envi++]="$1" + shift + ;; + + --) + shift + break + ;; + + *) + break + ;; + esac +done + +if [ $# -lt 1 -o -z "$arch" ]; then + echo "$usage" >&2 + echo "Type '${progname} --help' for more detailed help." >&2 + exit 1 +fi + +test_args=("$@") + +if [ -z "$NACL_SDK_ROOT" ]; then + echo >&2 "$0: NACL_SDK_ROOT must be set in the environment" + exit 77 +fi + +# We use a handful of things from the NaCl SDK, or at least +# from a directory matching the layout of the NaCl SDK. +sdk_tools="${NACL_SDK_ROOT}/tools" + +NACL_BOOTSTRAP="${sdk_tools}/nacl_helper_bootstrap_${arch}" +NACL_SEL_LDR="${sdk_tools}/sel_ldr_${arch}" +NACL_IRT="${sdk_tools}/irt_core_${arch}.nexe" +NACL_LOADER="${sdk_tools}/loader_${arch}.nexe" + +if [ ! -x "$NACL_BOOTSTRAP" -o ! -x "$NACL_SEL_LDR" ]; then + echo >&2 "$0: sel_ldr_${arch} and/or nacl_helper_bootstrap_${arch} missing" + echo >&2 "$0: from directory $sdk_tools" + exit 77 +fi + +if [ ! -r "$NACL_IRT" -o ! -r "$NACL_LOADER" ]; then + echo >&2 "$0: irt_core_${arch}.nexe and/or loader_${arch}.nexe missing" + echo >&2 "$0: from directory $sdk_tools" + exit 77 +fi + +# Figure out if we are building for the native machine or not. +# If not, we'll run sel_ldr under qemu. +decide_use_emulator() +{ + local arg + for arg; do + if [[ "$(uname -m)" = "$1" ]]; then + return + fi + done + use_emulator=true +} + +use_emulator=false +case "$arch" in +arm) + decide_use_emulator 'arm*' + emulator=(qemu-arm -cpu cortex-a15 -L "${sdk_tools}/arm_trusted") + ;; +x86_32) + decide_use_emulator 'i?86' 'x86_64*' + emulator=(qemu-i386) + ;; +x86_64) + decide_use_emulator 'x86_64*' + emulator=(qemu-x86_64) + ;; +esac + +if $use_emulator; then + ldr_args=('-Q') + emulator_factor=10 +else + emulator=() + ldr_args=() + emulator_factor=1 +fi + +if $use_bootstrap; then + ldr=( + "${NACL_BOOTSTRAP}" + "${NACL_SEL_LDR}" + '--r_debug=0xXXXXXXXXXXXXXXXX' + '--reserved_at_zero=0xXXXXXXXXXXXXXXXX' + ) +else + ldr=("${NACL_SEL_LDR}") +fi + +static=true +case "$1" in +*/ld-nacl*) static=false ;; +esac + +if $static; then + loader=() +else + loader=(-f "${NACL_LOADER}") +fi + +run_test() +{ + local test_fifo="$1" + local cmd=( + "${emulator[@]}" "${ldr[@]}" -q -S -a "${ldr_args[@]}" -B "${NACL_IRT}" + "${loader[@]}" "${env[@]}" -E TEST_DIRECT="$test_fifo" -- "${test_args[@]}" + ) + if [ "${NACLVERBOSITY:+set}" = set ]; then + "${cmd[@]}" + else + NACLLOG=/dev/null "${cmd[@]}" + fi +} + +temp_files=() +test_fifo= +do_cleanup() +{ + rm -rf "$test_fifo" "${temp_files[@]}" +} +trap do_cleanup EXIT HUP INT TERM + +# Create a named pipe to receive the TEST_DIRECT information from the test +# program. +test_fifo=${TMPDIR:-/tmp}/libc-test-fifo.$$ +rm -f "$test_fifo" +mkfifo "$test_fifo" || { + echo "Cannot create test FIFO '$test_fifo'" + exit 1 +} + +# Run the test in the background, so we can implement a timeout. +# The no-op redirection defeats the default behavior of "< /dev/null" +# for a background command. +run_test "$test_fifo" <&0 & test_pid=$! + +# Set up a short timeout before we read from the FIFO, in case +# the program doesn't actually write to the FIFO at all (it is +# not a test-skeleton.c program, or it dies very early). +no_skeleton=false +script_pid=$$ +trap 'no_skeleton=true' USR1 +(sleep 2; kill -USR1 $script_pid) 2> /dev/null & + +# The test should first write into the FIFO to describe its expectations. +# Our open-for-reading of the FIFO will block until the test starts up and +# opens it for writing. Then our reads will block until the test finishes +# writing out info and closes the FIFO. At that point we will have +# collected (and evaluated) what it emitted. It sets these variables: +# timeout=%u +# timeoutfactor=%u +# exit=%u +# signal=%s +unset exit signal +. "$test_fifo" 2> /dev/null + +# If we got this far, either the 'no_skeleton=true' watchdog already +# fired, or else we don't want it to. +trap '' USR1 + +if $no_skeleton; then + # We hit the timeout, so we didn't get full information about test + # expectations. Reset any partial results we may have gotten. + unset exit signal +else + # Now we know the expected timeout, so we can start the timer running. + ((sleep_time = timeout * timeoutfactor * emulator_factor)) + + # Now start a background subshell to enforce the timeout. + (sleep "$sleep_time"; kill -ALRM $test_pid) 2> /dev/null & +fi + +# This corresponds to '#ifdef EXPECTED_STATUS' in test-skeleton.c. +expected_status() +{ + test "${exit+yes}" = yes +} +# This corresponds to '#ifdef EXPECTED_SIGNAL' in test-skeleton.c. +expected_signal() +{ + test "${signal+yes}" = yes +} +# This corresponds to 'if (WIFEXITED (status))' in test-skeleton.c. +wifexited() +{ + test $test_rc -lt 128 +} + +# Now wait for the test process to finish. +wait $test_pid +test_rc=$? + +# This exactly duplicates the logic in test-skeleton.c. +if wifexited; then + if ! expected_status; then + if ! expected_signal; then + # Simply exit with the return value of the test. */ + exit $test_rc + else + echo "Expected signal '${signal}' from child, got none" + exit 1 + fi + else + if [ $test_rc -ne $exit ]; then + echo "Expected status $exit, got $test_rc" + exit 1 + fi + exit 0 + fi +else + # Process was killed by timer or other signal. + ((test_signal = test_rc > 192 ? 256 - test_rc : test_rc - 128 )) + test_signame=$(kill -l "$test_signal") + if ! expected_signal; then + echo "Didn't expect signal from child; got '${test_signame}'" + exit 1 + else + if [ "$test_signame" != "$signal" ]; then + echo "\ +Incorrect signal from child: got '${test_signame}', need '${signal}'" + exit 1 + fi + exit 0 + fi +fi diff --git a/sysdeps/nacl/nacl_interface_query.c b/sysdeps/nacl/nacl_interface_query.c new file mode 100644 index 0000000..cae876b --- /dev/null +++ b/sysdeps/nacl/nacl_interface_query.c @@ -0,0 +1,49 @@ +/* NaCl function exposing IRT interface query. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <nacl-interfaces.h> +#include <ldsodefs.h> + +#ifdef SHARED + +/* We can define this trivially using IFUNC rather than a wrapper + because we absolutely require that we get the IRT interface query + function pointer via AT_SYSINFO. */ + +extern TYPE_nacl_irt_query nacl_interface_query_ifunc (void) + asm ("nacl_interface_query"); + +TYPE_nacl_irt_query +nacl_interface_query_ifunc (void) +{ + return &__nacl_irt_query; +} +asm (".type nacl_interface_query, %gnu_indirect_function"); + +#else + +/* In the static library, using IFUNC is just extra overhead. */ + +size_t +nacl_interface_query (const char *interface_ident, + void *table, size_t tablesize) +{ + return __nacl_irt_query (interface_ident, table, tablesize); +} + +#endif diff --git a/sysdeps/nacl/nanosleep.c b/sysdeps/nacl/nanosleep.c new file mode 100644 index 0000000..cc60a46 --- /dev/null +++ b/sysdeps/nacl/nanosleep.c @@ -0,0 +1,33 @@ +/* nanosleep -- Sleep for a duration given in nanoseconds. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <time.h> +#include <nacl-interfaces.h> + + +/* Pause execution for a number of nanoseconds. */ +int +__libc_nanosleep (const struct timespec *requested_time, + struct timespec *remaining) +{ + return NACL_CALL (__nacl_irt_basic.nanosleep (requested_time, remaining), 0); +} + +weak_alias (__libc_nanosleep, __nanosleep) +libc_hidden_def (__nanosleep) +weak_alias (__libc_nanosleep, nanosleep) diff --git a/sysdeps/nacl/open.c b/sysdeps/nacl/open.c new file mode 100644 index 0000000..cb4700f --- /dev/null +++ b/sysdeps/nacl/open.c @@ -0,0 +1,52 @@ +/* Open a file by name. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <nacl-interfaces.h> + + +/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, + a third argument is the file protection. */ +int +__libc_open (const char *file, int oflag, ...) +{ + mode_t mode = 0; + + if (oflag & O_CREAT) + { + va_list arg; + va_start (arg, oflag); + mode = va_arg (arg, mode_t); + va_end (arg); + } + + int fd; + return NACL_CALL (__nacl_irt_filename.open (file, oflag, mode, &fd), fd); +} +libc_hidden_def (__libc_open) +weak_alias (__libc_open, __open) +libc_hidden_weak (__open) +weak_alias (__libc_open, open) + +/* open64 is just an alias. */ +strong_alias (__libc_open, __libc_open64) +strong_alias (__libc_open64, __open64) +libc_hidden_def (__open64) +weak_alias (__libc_open64, open64) diff --git a/sysdeps/nacl/open64.c b/sysdeps/nacl/open64.c new file mode 100644 index 0000000..b3e5563 --- /dev/null +++ b/sysdeps/nacl/open64.c @@ -0,0 +1 @@ +/* open.c defines open64 as an alias. */ diff --git a/sysdeps/nacl/preconfigure b/sysdeps/nacl/preconfigure new file mode 100644 index 0000000..c700fbc --- /dev/null +++ b/sysdeps/nacl/preconfigure @@ -0,0 +1,7 @@ +# GNU C Library preconfigure fragment for sysdeps/nacl + +case "$config_machine-$config_os" in +arm*-nacl*) + libc_config_ok=yes + ;; +esac diff --git a/sysdeps/nacl/profil.c b/sysdeps/nacl/profil.c new file mode 100644 index 0000000..701d7ad --- /dev/null +++ b/sysdeps/nacl/profil.c @@ -0,0 +1,2 @@ +/* Side-step sysdeps/posix/profil.c, which uses sigaction and setitimer. */ +#include <gmon/profil.c> diff --git a/sysdeps/nacl/read.c b/sysdeps/nacl/read.c new file mode 100644 index 0000000..fef0c82 --- /dev/null +++ b/sysdeps/nacl/read.c @@ -0,0 +1,32 @@ +/* read -- Read data from a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Read NBYTES into BUF from FD. Return the number read or -1. */ +ssize_t +__libc_read (int fd, void *buf, size_t nbytes) +{ + size_t nread; + return NACL_CALL (__nacl_irt_fdio.read (fd, buf, nbytes, &nread), nread); +} +libc_hidden_def (__libc_read) +weak_alias (__libc_read, __read) +libc_hidden_weak (__read) +weak_alias (__libc_read, read) diff --git a/sysdeps/nacl/readdir.c b/sysdeps/nacl/readdir.c new file mode 100644 index 0000000..a73bfe4 --- /dev/null +++ b/sysdeps/nacl/readdir.c @@ -0,0 +1,11 @@ +/* The compiler complains about aliases with nonmatching type signatures. + The types 'struct dirent' and 'struct dirent64' are actually identical + even though the compiler doesn't consider them to be. So we hide the + declaration from the compiler. */ +#define __readdir64 __avoid___readdir64_declaration +#define readdir64 __avoid_readdir64_declaration +#include <sysdeps/posix/readdir.c> +#undef __readdir64 +#undef readdir64 +strong_alias (__readdir, __readdir64) +weak_alias (__readdir64, readdir64) diff --git a/sysdeps/nacl/readdir64.c b/sysdeps/nacl/readdir64.c new file mode 100644 index 0000000..f4806bf --- /dev/null +++ b/sysdeps/nacl/readdir64.c @@ -0,0 +1 @@ +/* readdir.c defines readdir64 as an alias. */ diff --git a/sysdeps/nacl/readdir64_r.c b/sysdeps/nacl/readdir64_r.c new file mode 100644 index 0000000..c7830de --- /dev/null +++ b/sysdeps/nacl/readdir64_r.c @@ -0,0 +1 @@ +/* readdir_r.c defines readdir64_r as an alias. */ diff --git a/sysdeps/nacl/readdir_r.c b/sysdeps/nacl/readdir_r.c new file mode 100644 index 0000000..3a9a717 --- /dev/null +++ b/sysdeps/nacl/readdir_r.c @@ -0,0 +1,8 @@ +/* The compiler complains about aliases with nonmatching type signatures. + The types 'struct dirent' and 'struct dirent64' are actually identical + even though the compiler doesn't consider them to be. So we hide the + declaration from the compiler. */ +#define readdir64_r __avoid_readdir64_r_declaration +#include <sysdeps/posix/readdir_r.c> +#undef readdir64_r +weak_alias (__readdir_r, readdir64_r) diff --git a/sysdeps/nacl/readlink.c b/sysdeps/nacl/readlink.c new file mode 100644 index 0000000..d1c4cad --- /dev/null +++ b/sysdeps/nacl/readlink.c @@ -0,0 +1,32 @@ +/* Read the contents of a symbolic link. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Read the contents of the symbolic link PATH into no more than + LEN bytes of BUF. The contents are not null-terminated. + Returns the number of characters read, or -1 for errors. */ +ssize_t +__readlink (const char *path, char *buf, size_t len) +{ + size_t nread; + return NACL_CALL (__nacl_irt_dev_filename.readlink (path, buf, len, &nread), + nread); +} +weak_alias (__readlink, readlink) diff --git a/sysdeps/nacl/rename.c b/sysdeps/nacl/rename.c new file mode 100644 index 0000000..8cf1b2f --- /dev/null +++ b/sysdeps/nacl/rename.c @@ -0,0 +1,27 @@ +/* Rename a file. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Rename the file OLD to NEW. */ +int +rename (const char *old, const char *new) +{ + return NACL_CALL (__nacl_irt_dev_filename.rename (old, new), 0); +} diff --git a/sysdeps/nacl/rmdir.c b/sysdeps/nacl/rmdir.c new file mode 100644 index 0000000..917bffd --- /dev/null +++ b/sysdeps/nacl/rmdir.c @@ -0,0 +1,28 @@ +/* Remove a directory. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Remove the directory PATH. */ +int +__rmdir (const char *path) +{ + return NACL_CALL (__nacl_irt_dev_filename.rmdir (path), 0); +} +weak_alias (__rmdir, rmdir) diff --git a/sysdeps/nacl/sched_yield.c b/sysdeps/nacl/sched_yield.c new file mode 100644 index 0000000..c9c7aaa --- /dev/null +++ b/sysdeps/nacl/sched_yield.c @@ -0,0 +1,31 @@ +/* sched_yield -- Yield the processor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <sched.h> +#include <nacl-interfaces.h> + + +/* Yield the processor. */ +int +__sched_yield (void) +{ + return NACL_CALL (__nacl_irt_basic.sched_yield (), 0); +} +libc_hidden_def (__sched_yield) +weak_alias (__sched_yield, sched_yield) diff --git a/sysdeps/nacl/shlib-versions b/sysdeps/nacl/shlib-versions new file mode 100644 index 0000000..c146d31 --- /dev/null +++ b/sysdeps/nacl/shlib-versions @@ -0,0 +1,9 @@ +# DEFAULT Earliest symbol set +# ------- ------------------- +DEFAULT GLIBC_2.22 + +# Library=version Earliest symbol set (optional) +# --------------- ------------------------------ + +libc=0.1 +libm=0.1 diff --git a/sysdeps/nacl/sigaction.c b/sysdeps/nacl/sigaction.c new file mode 100644 index 0000000..898486e --- /dev/null +++ b/sysdeps/nacl/sigaction.c @@ -0,0 +1,11 @@ +#if IS_IN (libpthread) + +/* This placeholder file prevents nptl/sigaction.c from being compiled. + For NaCl, there is no need for a separate sigaction in libpthread. */ + +#else + +/* Get the standard stub. */ +#include <signal/sigaction.c> + +#endif diff --git a/sysdeps/nacl/sprofil.c b/sysdeps/nacl/sprofil.c new file mode 100644 index 0000000..96d4300 --- /dev/null +++ b/sysdeps/nacl/sprofil.c @@ -0,0 +1,2 @@ +/* Side-step sysdeps/posix/sprofil.c, which uses sigaction and setitimer. */ +#include <gmon/sprofil.c> diff --git a/sysdeps/nacl/start.c b/sysdeps/nacl/start.c new file mode 100644 index 0000000..a4b6dd3 --- /dev/null +++ b/sysdeps/nacl/start.c @@ -0,0 +1,73 @@ +/* Entry-point for programs. NaCl version. + Copyright (C) 2015 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <stdint.h> +#include <link.h> + +/* NaCl's elf32.h is incompatible with the real <elf.h>. */ +#define NATIVE_CLIENT_SRC_INCLUDE_ELF32_H_ +#include <native_client/src/untrusted/nacl/nacl_startup.h> + + +/* The application defines this, of course. */ +extern int main (int argc, char **argv, char **envp); + +/* These are defined in libc. */ +extern int __libc_csu_init (int argc, char **argv, char **envp); +extern void __libc_csu_fini (void); +extern void __libc_start_main (int (*main) (int, char **, char **), + int argc, char **argv, ElfW(auxv_t) *auxv, + int (*init) (int, char **, char **), + void (*fini) (void), + void (*rtld_fini) (void), + void *stack_end); + +void +_start (uint32_t info[]) +{ + /* The generic code actually assumes that envp follows argv. */ + + __libc_start_main (&main, + nacl_startup_argc (info), + nacl_startup_argv (info), + nacl_startup_auxv (info), + &__libc_csu_init, &__libc_csu_fini, + nacl_startup_fini (info), + __builtin_frame_address (0)); + + /* That should not return. Make sure we crash if it did. */ + while (1) + __builtin_trap (); +} diff --git a/sysdeps/nacl/symlink.c b/sysdeps/nacl/symlink.c new file mode 100644 index 0000000..1454589 --- /dev/null +++ b/sysdeps/nacl/symlink.c @@ -0,0 +1,28 @@ +/* Make a symbolic link. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Make a symbolic link to FROM called TO. */ +int +__symlink (const char *from, const char *to) +{ + return NACL_CALL (__nacl_irt_dev_filename.symlink (from, to), 0); +} +weak_alias (__symlink, symlink) diff --git a/sysdeps/nacl/tls.h b/sysdeps/nacl/tls.h new file mode 100644 index 0000000..ccf4e83 --- /dev/null +++ b/sysdeps/nacl/tls.h @@ -0,0 +1,41 @@ +/* Definition for thread-local data handling. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _NACL_TLS_H +#define _NACL_TLS_H 1 + +#ifndef __ASSEMBLER__ + +# include <nacl-interfaces.h> + +/* Code to initially initialize the thread pointer. This might need + special attention since 'errno' is not yet available and if the + operation can cause a failure 'errno' must not be touched. */ +# define TLS_INIT_TP(tcbp) \ + ((*__nacl_irt_tls.tls_init) (tcbp) == 0 ? NULL : "tls_init call failed") + +/* Our use of dl_sysinfo is rather different from the Linux syscall + entry-point case. We never need a thread-local copy of the value. */ +# undef SETUP_THREAD_SYSINFO +# undef CHECK_THREAD_SYSINFO +# define SETUP_THREAD_SYSINFO(pd) ((void) (pd)) +# define CHECK_THREAD_SYSINFO(pd) ((void) (pd)) + +#endif /* __ASSEMBLER__ */ + +#endif /* tls.h */ diff --git a/sysdeps/nacl/truncate.c b/sysdeps/nacl/truncate.c new file mode 100644 index 0000000..cdb8ac7 --- /dev/null +++ b/sysdeps/nacl/truncate.c @@ -0,0 +1,32 @@ +/* Truncate a file (by name). NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Truncate PATH to LENGTH bytes. */ +int +__truncate (const char *path, off_t length) +{ + return NACL_CALL (__nacl_irt_dev_filename.truncate (path, length), 0); +} +weak_alias (__truncate, truncate) + +/* truncate64 is the same as truncate. */ +strong_alias (__truncate, __truncate64) +weak_alias (__truncate64, truncate64) diff --git a/sysdeps/nacl/truncate64.c b/sysdeps/nacl/truncate64.c new file mode 100644 index 0000000..729d0d0 --- /dev/null +++ b/sysdeps/nacl/truncate64.c @@ -0,0 +1 @@ +/* truncate64 is the same as truncate. */ diff --git a/sysdeps/nacl/unlink.c b/sysdeps/nacl/unlink.c new file mode 100644 index 0000000..6c872c2 --- /dev/null +++ b/sysdeps/nacl/unlink.c @@ -0,0 +1,28 @@ +/* Remove a file. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Remove the link named NAME. */ +int +__unlink (const char *name) +{ + return NACL_CALL (__nacl_irt_dev_filename.unlink (name), 0); +} +weak_alias (__unlink, unlink) diff --git a/sysdeps/nacl/utimes.c b/sysdeps/nacl/utimes.c new file mode 100644 index 0000000..1f0f08a --- /dev/null +++ b/sysdeps/nacl/utimes.c @@ -0,0 +1,29 @@ +/* Change the access and modification times of a file. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/time.h> +#include <nacl-interfaces.h> + +/* Change the access time of FILE to TVP[0] and + the modification time of FILE to TVP[1]. */ +int +__utimes (const char *file, const struct timeval tvp[2]) +{ + return NACL_CALL (__nacl_irt_dev_filename.utimes (file, tvp), 0); +} +weak_alias (__utimes, utimes) diff --git a/sysdeps/nacl/write.c b/sysdeps/nacl/write.c new file mode 100644 index 0000000..d4063fd --- /dev/null +++ b/sysdeps/nacl/write.c @@ -0,0 +1,33 @@ +/* write -- Write data to a file descriptor. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <unistd.h> +#include <nacl-interfaces.h> + +/* Write NBYTES of BUF to FD. Return the number written, or -1. */ +ssize_t +__libc_write (int fd, const void *buf, size_t nbytes) +{ + size_t wrote; + return NACL_CALL (__nacl_irt_fdio.write (fd, buf, nbytes, &wrote), wrote); +} +libc_hidden_def (__libc_write) + +weak_alias (__libc_write, __write) +libc_hidden_weak (__write) +weak_alias (__libc_write, write) diff --git a/sysdeps/nacl/xstat.c b/sysdeps/nacl/xstat.c new file mode 100644 index 0000000..022cf02 --- /dev/null +++ b/sysdeps/nacl/xstat.c @@ -0,0 +1,45 @@ +/* Get stat information from a file name. NaCl version. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +/* Avoid the declaration so the compiler doesn't complain about the alias + with a different type signature. It doesn't know that 'struct stat' + and 'struct stat64' are ABI-compatible. */ +#define __xstat64 __xstat64_avoid +#include <sys/stat.h> +#undef __xstat64 + +#include <errno.h> +#include <stddef.h> + +#include <xstatconv.h> + +#undef stat + +/* Get file information about FILE in BUF. */ +int +__xstat (int vers, const char *file, struct stat *buf) +{ + nacl_abi_stat_t abi_buf; + return NACL_CALL (__nacl_irt_filename.stat (file, &abi_buf), + __xstat_conv (vers, &abi_buf, buf)); +} +hidden_def (__xstat) +weak_alias (__xstat, _xstat) + +strong_alias (__xstat, __xstat64) +hidden_ver (__xstat, __xstat64) diff --git a/sysdeps/nacl/xstat64.c b/sysdeps/nacl/xstat64.c new file mode 100644 index 0000000..47db9b9 --- /dev/null +++ b/sysdeps/nacl/xstat64.c @@ -0,0 +1 @@ +/* xstat.c defines __xstat64 as an alias. */ diff --git a/sysdeps/nacl/xstatconv.c b/sysdeps/nacl/xstatconv.c new file mode 100644 index 0000000..ecab76c --- /dev/null +++ b/sysdeps/nacl/xstatconv.c @@ -0,0 +1,76 @@ +/* Convert between the NaCl ABI's `struct stat' format, and libc's. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <string.h> +#include <sys/stat.h> +#include <xstatconv.h> + +internal_function +int +__xstat_conv (int vers, const struct nacl_abi_stat *kbuf, void *ubuf) +{ + /* It's kosher enough just to crash here, but there are some + existing NaCl tests that like to see EFAULT, and that's what + making the IRT call with NULL would give. */ + if (__glibc_unlikely (ubuf == NULL)) + { + __set_errno (EFAULT); + return -1; + } + + switch (vers) + { + case _STAT_VER_NACL: + /* Nothing to do. The struct is in the form the NaCl ABI expects. */ + *(struct nacl_abi_stat *) ubuf = *kbuf; + break; + + case _STAT_VER_LINUX: + { + struct stat *buf = ubuf; + + /* Zero-fill the pad/unused fields. */ + memset (buf, 0, sizeof *buf); + + /* Convert from NaCl IRT ABI `struct stat'. */ + buf->st_dev = kbuf->nacl_abi_st_dev; + buf->st_ino = kbuf->nacl_abi_st_ino; + buf->st_mode = kbuf->nacl_abi_st_mode; + buf->st_nlink = kbuf->nacl_abi_st_nlink; + buf->st_uid = kbuf->nacl_abi_st_uid; + buf->st_gid = kbuf->nacl_abi_st_gid; + buf->st_rdev = kbuf->nacl_abi_st_rdev; + buf->st_size = kbuf->nacl_abi_st_size; + buf->st_blksize = kbuf->nacl_abi_st_blksize; + buf->st_blocks = kbuf->nacl_abi_st_blocks; + buf->st_atim.tv_sec = kbuf->nacl_abi_st_atime; + buf->st_atim.tv_nsec = kbuf->nacl_abi_st_atimensec; + buf->st_mtim.tv_sec = kbuf->nacl_abi_st_mtime; + buf->st_mtim.tv_nsec = kbuf->nacl_abi_st_mtimensec; + buf->st_ctim.tv_sec = kbuf->nacl_abi_st_ctime; + buf->st_ctim.tv_nsec = kbuf->nacl_abi_st_ctimensec; + } + break; + + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} diff --git a/sysdeps/nacl/xstatconv.h b/sysdeps/nacl/xstatconv.h new file mode 100644 index 0000000..fb313a2 --- /dev/null +++ b/sysdeps/nacl/xstatconv.h @@ -0,0 +1,32 @@ +/* Convert between the NaCl ABI's `struct stat' format, and libc's. + Copyright (C) 2015 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. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <nacl-interfaces.h> + +#define NACL_IN_TOOLCHAIN_HEADERS + +struct stat; + +/* stat.h uses nacl_abi_off_t, but irt.h defines only nacl_irt_off_t. */ +typedef nacl_irt_off_t nacl_abi_off_t; + +/* We use this header to define struct nacl_abi_stat. */ +#include <native_client/src/trusted/service_runtime/include/bits/stat.h> + +extern int __xstat_conv (int vers, const struct nacl_abi_stat *, void *) + internal_function attribute_hidden; |