aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@hack.frob.com>2015-04-07 16:16:04 -0700
committerRoland McGrath <roland@hack.frob.com>2015-04-07 16:16:04 -0700
commit49a3a2bc136d6ea9f3032d3396c72e980190b68a (patch)
treeb82ce57765baf6cd6527804967e69b38c5437285
parentd3de4b133c3d2a1aef4c4a839648fcd2e6b52f69 (diff)
downloadglibc-roland/nacl-port/master.tar
glibc-roland/nacl-port/master.tar.gz
glibc-roland/nacl-port/master.tar.bz2
glibc-roland/nacl-port/master.zip
Random nits prepping for upstreaming.roland/nacl-port/master
-rw-r--r--abi-tags2
-rw-r--r--sysdeps/arm/nacl/Makefile23
-rw-r--r--sysdeps/arm/nacl/dl-machine.h17
-rw-r--r--sysdeps/nacl/Makefile38
-rw-r--r--sysdeps/nacl/Versions2
-rw-r--r--sysdeps/nacl/____longjmp_chk.c28
-rw-r--r--sysdeps/nacl/_exit.c3
-rw-r--r--sysdeps/nacl/bits/dirent.h2
-rw-r--r--sysdeps/nacl/dl-map-segments.h320
-rw-r--r--sysdeps/nacl/dl-sysdep.c15
-rw-r--r--sysdeps/nacl/errnos.awk21
-rw-r--r--sysdeps/nacl/glob.c26
-rw-r--r--sysdeps/nacl/isatty.c11
-rw-r--r--sysdeps/nacl/ldsodefs.h2
-rwxr-xr-xsysdeps/nacl/nacl-after-link.sh69
-rw-r--r--sysdeps/nacl/nacl-interface-list.h48
-rw-r--r--sysdeps/nacl/nacl-interfaces.c11
-rw-r--r--sysdeps/nacl/rename.c2
-rw-r--r--sysdeps/nacl/shlib-versions6
19 files changed, 398 insertions, 248 deletions
diff --git a/abi-tags b/abi-tags
index 9eaf23e083..930a88942d 100644
--- a/abi-tags
+++ b/abi-tags
@@ -1,4 +1,4 @@
# Configuration ABI OS ABI version
# ------------- ------ -----------
-.*-.*-nacl.* 6 22.0.0
+.*-.*-nacl.* 6 42.0.0
diff --git a/sysdeps/arm/nacl/Makefile b/sysdeps/arm/nacl/Makefile
index 5e56895cbd..c9226595e6 100644
--- a/sysdeps/arm/nacl/Makefile
+++ b/sysdeps/arm/nacl/Makefile
@@ -1,3 +1,26 @@
+# 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
diff --git a/sysdeps/arm/nacl/dl-machine.h b/sysdeps/arm/nacl/dl-machine.h
index b48517bcc0..81f3755b3b 100644
--- a/sysdeps/arm/nacl/dl-machine.h
+++ b/sysdeps/arm/nacl/dl-machine.h
@@ -39,14 +39,15 @@
.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");
+ @ 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/nacl/Makefile b/sysdeps/nacl/Makefile
index 7a26b7f50d..e4c03020c8 100644
--- a/sysdeps/nacl/Makefile
+++ b/sysdeps/nacl/Makefile
@@ -1,3 +1,5 @@
+# Makefile fragment for NaCl configurations.
+
# Copyright (C) 2015 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
@@ -46,6 +48,8 @@ $(common-objpfx)stamp-errnos: $(nacl)/errnos.awk $(..)manual/errno.texi \
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 \
@@ -55,21 +59,6 @@ $(nacl-irt.h): $(nacl)/irt.sed \
common-generated += nacl-irt.h
before-compile += $(nacl-irt.h)
-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
-
-# XXX temp test
-others += hello hellow
-others-static += hello
-
-endif
-
-
$(common-objpfx)nacl-interfaces.v.i: $(nacl)/nacl-interfaces.mk.in \
$(nacl)/nacl-interface-list.h
-include $(common-objpfx)nacl-interfaces.v
@@ -102,6 +91,17 @@ $(nacl-optional-interfaces:%=$(nacl-interface-pattern)): \
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
+
ifeq ($(subdir),csu)
sysdep_routines += nacl_interface_query \
nacl-interfaces $(call nacl-routines-of,libc)
@@ -120,3 +120,11 @@ ifeq ($(subdir),nptl)
# XXX temporary hack
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/Versions b/sysdeps/nacl/Versions
index 32eb77241a..4ac56c2a28 100644
--- a/sysdeps/nacl/Versions
+++ b/sysdeps/nacl/Versions
@@ -5,7 +5,7 @@ ld {
}
libc {
- GLIBC_2.17 {
+ GLIBC_2.22 {
nacl_interface_query;
}
diff --git a/sysdeps/nacl/____longjmp_chk.c b/sysdeps/nacl/____longjmp_chk.c
deleted file mode 100644
index 05ad655559..0000000000
--- a/sysdeps/nacl/____longjmp_chk.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Fortified longjmp. Stub 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 <setjmp.h>
-
-/* We don't have any way to validate the stack pointer.
- So we just do a vanilla longjmp. */
-void
-__attribute__ ((__noreturn__))
-____longjmp_chk (__jmp_buf env, int val)
-{
- __longjmp (env, val);
-}
diff --git a/sysdeps/nacl/_exit.c b/sysdeps/nacl/_exit.c
index 0ec902f9ea..6006e26e55 100644
--- a/sysdeps/nacl/_exit.c
+++ b/sysdeps/nacl/_exit.c
@@ -24,6 +24,9 @@ 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 ();
}
diff --git a/sysdeps/nacl/bits/dirent.h b/sysdeps/nacl/bits/dirent.h
index 3fb19c3eab..571ac0c67b 100644
--- a/sysdeps/nacl/bits/dirent.h
+++ b/sysdeps/nacl/bits/dirent.h
@@ -1,5 +1,5 @@
/* Directory entry structure `struct dirent'. NaCl version.
- Copyright (C) 2012 Free Software Foundation, Inc.
+ 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
diff --git a/sysdeps/nacl/dl-map-segments.h b/sysdeps/nacl/dl-map-segments.h
index d93badf1d3..f305da304a 100644
--- a/sysdeps/nacl/dl-map-segments.h
+++ b/sysdeps/nacl/dl-map-segments.h
@@ -34,12 +34,12 @@ read_in_data (int fd, void *data, size_t len, off_t pos)
{
ssize_t n = __read (fd, data, len);
if (__glibc_unlikely (n < 0))
- return true;
+ return true;
if (__glibc_unlikely (n == 0))
- {
- errno = EFTYPE;
- return true;
- }
+ {
+ errno = EFTYPE;
+ return true;
+ }
data += n;
len -= n;
}
@@ -48,59 +48,63 @@ read_in_data (int fd, void *data, size_t len, off_t pos)
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)
+ 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.
+ 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. */
+ 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));
+ = (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))
- {
- 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;
- }
- }
+ {
+ /* 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
- {
- 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;
- }
+ {
+ /* 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;
}
@@ -110,118 +114,120 @@ _dl_map_segments (struct link_map *l, int fd,
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;
- 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);
+ /* 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
diff --git a/sysdeps/nacl/dl-sysdep.c b/sysdeps/nacl/dl-sysdep.c
index f9af5a3acb..3e902c2cae 100644
--- a/sysdeps/nacl/dl-sysdep.c
+++ b/sysdeps/nacl/dl-sysdep.c
@@ -48,15 +48,15 @@
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_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. */
+ 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];
@@ -71,12 +71,15 @@ _dl_start_user (void (*user_entry) (uint32_t info[]), uint32_t info[])
/* Run initializers. */
_dl_init (GL(dl_ns)[0]._ns_loaded,
- nacl_startup_argc (info),
- nacl_startup_argv (info),
- nacl_startup_envp (info));
+ 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 ()
diff --git a/sysdeps/nacl/errnos.awk b/sysdeps/nacl/errnos.awk
index 35f29719ea..65fa19bd06 100644
--- a/sysdeps/nacl/errnos.awk
+++ b/sysdeps/nacl/errnos.awk
@@ -1,3 +1,22 @@
+# 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]+/ {
@@ -61,7 +80,7 @@ END {
#define EWOULDBLOCK EAGAIN\n\
#define ENOTSUP EOPNOTSUPP\n\
\n\
-extern __thread int errno;\n\
+extern __thread int errno __attribute__ ((__tls_model__ (\"initial-exec\")));\n\
#define errno errno\n\
\n\
#endif";
diff --git a/sysdeps/nacl/glob.c b/sysdeps/nacl/glob.c
index 147bc10132..36d62e807d 100644
--- a/sysdeps/nacl/glob.c
+++ b/sysdeps/nacl/glob.c
@@ -1,6 +1,26 @@
-/* XXX temporary? hack */
-#include <unistd.h>
-#define getlogin_r(name, len) (ENOSYS)
+/* 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/isatty.c b/sysdeps/nacl/isatty.c
index 6e2b01ad94..fc1a686bae 100644
--- a/sysdeps/nacl/isatty.c
+++ b/sysdeps/nacl/isatty.c
@@ -16,6 +16,7 @@
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>
@@ -24,6 +25,14 @@ int
__isatty (int fd)
{
int result;
- return NACL_CALL (__nacl_irt_dev_fdio.isatty (fd, &result), 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/ldsodefs.h b/sysdeps/nacl/ldsodefs.h
index c1cfd12c99..383ced5612 100644
--- a/sysdeps/nacl/ldsodefs.h
+++ b/sysdeps/nacl/ldsodefs.h
@@ -24,7 +24,7 @@
/* Now define our stuff. */
/* We have the auxiliary vector. */
-#define HAVE_AUX_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;
diff --git a/sysdeps/nacl/nacl-after-link.sh b/sysdeps/nacl/nacl-after-link.sh
new file mode 100755
index 0000000000..199f1b89ac
--- /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
index 11ad69ac16..d09814739a 100644
--- a/sysdeps/nacl/nacl-interface-list.h
+++ b/sysdeps/nacl/nacl-interface-list.h
@@ -1,29 +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_IRT_BASIC_v0_1, nacl_irt_basic)
NACL_MANDATORY_INTERFACE (rtld,
- NACL_IRT_FDIO_v0_1, nacl_irt_fdio)
+ NACL_IRT_FDIO_v0_1, nacl_irt_fdio)
NACL_MANDATORY_INTERFACE (rtld,
- NACL_IRT_FILENAME_v0_1, nacl_irt_filename)
+ NACL_IRT_FILENAME_v0_1, nacl_irt_filename)
NACL_MANDATORY_INTERFACE (rtld,
- NACL_IRT_MEMORY_v0_3, nacl_irt_memory)
+ NACL_IRT_MEMORY_v0_3, nacl_irt_memory)
NACL_MANDATORY_INTERFACE (libc,
- NACL_IRT_THREAD_v0_1, nacl_irt_thread)
+ NACL_IRT_THREAD_v0_1, nacl_irt_thread)
NACL_MANDATORY_INTERFACE (rtld,
- NACL_IRT_FUTEX_v0_1, nacl_irt_futex)
+ NACL_IRT_FUTEX_v0_1, nacl_irt_futex)
NACL_MANDATORY_INTERFACE (rtld,
- NACL_IRT_TLS_v0_1, nacl_irt_tls)
+ NACL_IRT_TLS_v0_1, nacl_irt_tls)
NACL_MANDATORY_INTERFACE (libc,
- NACL_IRT_RESOURCE_OPEN_v0_1, nacl_irt_resource_open)
+ 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_IRT_CODE_DATA_ALLOC_v0_1,
+ nacl_irt_code_data_alloc)
NACL_OPTIONAL_INTERFACE (libc,
- NACL_IRT_CLOCK_v0_1, nacl_irt_clock)
+ NACL_IRT_CLOCK_v0_1, nacl_irt_clock)
NACL_OPTIONAL_INTERFACE (rtld,
- NACL_IRT_DYNCODE_v0_1, nacl_irt_dyncode)
+ NACL_IRT_DYNCODE_v0_1, nacl_irt_dyncode)
NACL_OPTIONAL_INTERFACE (rtld,
- NACL_IRT_DEV_GETPID_v0_1, nacl_irt_dev_getpid)
+ 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_IRT_DEV_FILENAME_v0_3, nacl_irt_dev_filename)
NACL_OPTIONAL_INTERFACE (libc,
- NACL_IRT_DEV_FDIO_v0_3, nacl_irt_dev_fdio)
+ NACL_IRT_DEV_FDIO_v0_3, nacl_irt_dev_fdio)
diff --git a/sysdeps/nacl/nacl-interfaces.c b/sysdeps/nacl/nacl-interfaces.c
index 469ee6581b..cb0dcd0bc8 100644
--- a/sysdeps/nacl/nacl-interfaces.c
+++ b/sysdeps/nacl/nacl-interfaces.c
@@ -48,8 +48,7 @@ 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)
+next_nacl_table (uintptr_t *t, const struct nacl_interface *i)
{
return (void *) t + i->table_size;
}
@@ -84,7 +83,7 @@ initialize_mandatory_interfaces (void)
while (i < __stop_nacl_mandatory_interface_names)
{
if (__nacl_irt_query (i->name, t, i->table_size) != i->table_size)
- missing_mandatory_interface (i);
+ missing_mandatory_interface (i);
t = next_nacl_table (t, i);
i = next_nacl_interface (i);
@@ -106,9 +105,9 @@ initialize_optional_interfaces (void)
while (i < __stop_nacl_optional_interface_names)
{
size_t filled = __nacl_irt_query (i->name, t, i->table_size);
- if (filled == 0)
- for (size_t slot = 0; slot < i->table_size / sizeof *t; ++slot)
- t[slot] = (uintptr_t) &nacl_missing_optional_interface;
+ 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);
diff --git a/sysdeps/nacl/rename.c b/sysdeps/nacl/rename.c
index a968eaf969..8cf1b2f218 100644
--- a/sysdeps/nacl/rename.c
+++ b/sysdeps/nacl/rename.c
@@ -1,4 +1,4 @@
-/* Make a hard link. NaCl version.
+/* Rename a file. NaCl version.
Copyright (C) 2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
diff --git a/sysdeps/nacl/shlib-versions b/sysdeps/nacl/shlib-versions
index 2658047209..c146d31b96 100644
--- a/sysdeps/nacl/shlib-versions
+++ b/sysdeps/nacl/shlib-versions
@@ -1,9 +1,9 @@
# DEFAULT Earliest symbol set
# ------- -------------------
-DEFAULT GLIBC_2.21
+DEFAULT GLIBC_2.22
# Library=version Earliest symbol set (optional)
# --------------- ------------------------------
-libc=1
-libm=1
+libc=0.1
+libm=0.1