X-Git-Url: http://git.pld-linux.org/?a=blobdiff_plain;f=glibc-git.patch;h=c78b864dc66a188267467db5945ac69ef7f5d1e1;hb=7b40edb0991fe5fe13aa36cd109d9052cb65abc6;hp=bd86ae7e1e099e88d0918a96464bd7e47e9801c3;hpb=bc0b4a5c6246621e9b7946253252b0682b0f9d1e;p=packages%2Fglibc.git diff --git a/glibc-git.patch b/glibc-git.patch index bd86ae7..c78b864 100644 --- a/glibc-git.patch +++ b/glibc-git.patch @@ -1,8 +1,72 @@ diff --git a/ChangeLog b/ChangeLog -index cb9124e..b32cd09 100644 +index cb9124e..b1816c2 100644 --- a/ChangeLog +++ b/ChangeLog -@@ -1,3 +1,159 @@ +@@ -1,3 +1,223 @@ ++2015-11-20 Roland McGrath ++ ++ * sysdeps/nacl/dl-map-segments.h (_dl_map_segments): Use ++ __glibc_likely instead of __builtin_expect. After falling back to ++ dyncode_create in a non-ET_DYN case, use the allocate_code_data ++ system interface to register the code pages as occupied. ++ ++2015-11-14 H.J. Lu ++ ++ * config.make.in (have-glob-dat-reloc): New. ++ * configure.ac (libc_cv_has_glob_dat): New. Set to yes if ++ target supports GLOB_DAT relocaton. AC_SUBST. ++ * configure: Regenerated. ++ * elf/Makefile (tests): Add tst-prelink. ++ (tests-special): Add $(objpfx)tst-prelink-cmp.out. ++ (tst-prelink-ENV): New. ++ ($(objpfx)tst-prelink-conflict.out): Likewise. ++ ($(objpfx)tst-prelink-cmp.out): Likewise. ++ * sysdeps/x86/tst-prelink.c: Moved to ... ++ * elf/tst-prelink.c: Here. ++ * sysdeps/x86/tst-prelink.exp: Moved to ... ++ * elf/tst-prelink.exp: Here. ++ * sysdeps/x86/Makefile (tests): Don't add tst-prelink. ++ (tst-prelink-ENV): Removed. ++ ($(objpfx)tst-prelink-conflict.out): Likewise. ++ ($(objpfx)tst-prelink-cmp.out): Likewise. ++ (tests-special): Don't add $(objpfx)tst-prelink-cmp.out. ++ ++2015-11-10 Roland McGrath ++ ++ * elf/dl-load.c (open_verify): Take new argument FD. ++ Skip __open call if passed FD is not -1. ++ (_dl_map_object, open_path): Update callers. ++ * elf/dl-sysdep-open.h: New file. ++ * elf/dl-load.c: Include it. ++ (_dl_map_object): Try _dl_sysdep_open_object before ldconfig cache. ++ * sysdeps/nacl/dl-sysdep.c (_dl_sysdep_open_object): New function. ++ * sysdeps/nacl/dl-sysdep-open.h: New file. ++ * sysdeps/nacl/nacl-interface-list.h: Move nacl_irt_resource_open ++ from libc to rtld. ++ ++2015-11-10 H.J. Lu ++ ++ [BZ #19178] ++ * sysdeps/x86/Makefile (tests): Add tst-prelink. ++ (tst-prelink-ENV): New. ++ ($(objpfx)tst-prelink-conflict.out): Likewise. ++ ($(objpfx)tst-prelink-cmp.out): Likewise. ++ (tests-special): Add $(objpfx)tst-prelink-cmp.out. ++ * sysdeps/x86/tst-prelink.c: New file. ++ * sysdeps/x86/tst-prelink.exp: Likewise. ++ ++2015-11-07 H.J. Lu ++ ++ [BZ #19178] ++ * elf/dl-lookup.c (RTYPE_CLASS_VALID): New. ++ (RTYPE_CLASS_PLT): Likewise. ++ (RTYPE_CLASS_COPY): Likewise. ++ (RTYPE_CLASS_TLS): Likewise. ++ (_dl_debug_bindings): Use RTYPE_CLASS_TLS and RTYPE_CLASS_VALID ++ to set relocation type class for DL_DEBUG_PRELINK. Keep only ++ ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY bits for ++ DL_DEBUG_PRELINK. ++ +2015-10-20 Tulio Magno Quites Machado Filho + + [BZ #18743] @@ -163,7 +227,7 @@ index cb9124e..b32cd09 100644 * version.h (RELEASE): Set to "stable". diff --git a/NEWS b/NEWS -index 4c31de7..92037ce 100644 +index 4c31de7..30fe67c 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,16 @@ See the end for copying conditions. @@ -175,7 +239,7 @@ index 4c31de7..92037ce 100644 +* The following bugs are resolved with this release: + + 18589, 18743, 18778, 18781, 18787, 18796, 18870, 18887, 18921, 18928, -+ 18969, 19018. ++ 18969, 19018, 19178. + +* The LD_POINTER_GUARD environment variable can no longer be used to + disable the pointer guard feature. It is always enabled. @@ -192,8 +256,106 @@ index 4c31de7..92037ce 100644 removed from the standard in 2001. Also, the glibc implementation leaks memory. See BZ#18681 for more details. +diff --git a/config.make.in b/config.make.in +index a9f5696..46cd9bb 100644 +--- a/config.make.in ++++ b/config.make.in +@@ -51,6 +51,7 @@ have-z-combreloc = @libc_cv_z_combreloc@ + have-z-execstack = @libc_cv_z_execstack@ + have-Bgroup = @libc_cv_Bgroup@ + have-protected-data = @libc_cv_protected_data@ ++have-glob-dat-reloc = @libc_cv_has_glob_dat@ + with-fp = @with_fp@ + old-glibc-headers = @old_glibc_headers@ + unwind-find-fde = @libc_cv_gcc_unwind_find_fde@ +diff --git a/configure b/configure +index 45cc7cb..4f87b31 100755 +--- a/configure ++++ b/configure +@@ -628,6 +628,7 @@ gnu89_inline + libc_cv_ssp + fno_unit_at_a_time + libc_cv_output_format ++libc_cv_has_glob_dat + libc_cv_hashstyle + libc_cv_fpie + libc_cv_z_execstack +@@ -6335,6 +6336,39 @@ $as_echo "$libc_cv_use_default_link" >&6; } + use_default_link=$libc_cv_use_default_link + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5 ++$as_echo_n "checking for GLOB_DAT reloc... " >&6; } ++if ${libc_cv_has_glob_dat+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ++then ++ if $READELF -rW conftest.so | grep '_GLOB_DAT' > /dev/null; then ++ libc_cv_has_glob_dat=yes ++ else ++ libc_cv_has_glob_dat=no ++ fi ++else ++ libc_cv_has_glob_dat=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_has_glob_dat" >&5 ++$as_echo "$libc_cv_has_glob_dat" >&6; } ++ ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker output format" >&5 + $as_echo_n "checking linker output format... " >&6; } + if ${libc_cv_output_format+:} false; then : +diff --git a/configure.ac b/configure.ac +index 7e9383a..8be612d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1535,6 +1535,29 @@ $ac_try" + use_default_link=$libc_cv_use_default_link + fi + ++AC_CACHE_CHECK(for GLOB_DAT reloc, ++ libc_cv_has_glob_dat, [dnl ++cat > conftest.c <&AS_MESSAGE_LOG_FD]) ++then ++dnl look for GLOB_DAT relocation. ++ if $READELF -rW conftest.so | grep '_GLOB_DAT' > /dev/null; then ++ libc_cv_has_glob_dat=yes ++ else ++ libc_cv_has_glob_dat=no ++ fi ++else ++ libc_cv_has_glob_dat=no ++fi ++rm -f conftest*]) ++AC_SUBST(libc_cv_has_glob_dat) ++ + AC_CACHE_CHECK(linker output format, libc_cv_output_format, [dnl + if libc_cv_output_format=` + ${CC-cc} -nostartfiles -nostdlib -Wl,--print-output-format 2>&AS_MESSAGE_LOG_FD` diff --git a/elf/Makefile b/elf/Makefile -index 4ceeaf8..71a18a1 100644 +index 4ceeaf8..a2c43bc 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -148,7 +148,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ @@ -215,7 +377,21 @@ index 4ceeaf8..71a18a1 100644 ifeq (yes,$(have-protected-data)) modules-names += tst-protected1moda tst-protected1modb tests += tst-protected1a tst-protected1b -@@ -594,6 +595,7 @@ tst-auditmod9b.so-no-z-defs = yes +@@ -292,6 +293,13 @@ check-abi: $(objpfx)check-abi-ld.out + tests-special += $(objpfx)check-abi-ld.out + update-abi: update-abi-ld + ++ifeq ($(have-glob-dat-reloc),yes) ++tests += tst-prelink ++ifeq ($(run-built-tests),yes) ++tests-special += $(objpfx)tst-prelink-cmp.out ++endif ++endif ++ + include ../Rules + + ifeq (yes,$(build-shared)) +@@ -594,6 +602,7 @@ tst-auditmod9b.so-no-z-defs = yes tst-nodelete-uniquemod.so-no-z-defs = yes tst-nodelete-rtldmod.so-no-z-defs = yes tst-nodelete-zmod.so-no-z-defs = yes @@ -223,7 +399,7 @@ index 4ceeaf8..71a18a1 100644 ifeq ($(build-shared),yes) # Build all the modules even when not actually running test programs. -@@ -1164,6 +1166,11 @@ $(objpfx)tst-nodelete.out: $(objpfx)tst-nodelete-uniquemod.so \ +@@ -1164,6 +1173,11 @@ $(objpfx)tst-nodelete.out: $(objpfx)tst-nodelete-uniquemod.so \ LDFLAGS-tst-nodelete = -rdynamic LDFLAGS-tst-nodelete-zmod.so = -Wl,--enable-new-dtags,-z,nodelete @@ -235,6 +411,20 @@ index 4ceeaf8..71a18a1 100644 $(objpfx)tst-initorder-cmp.out: tst-initorder.exp $(objpfx)tst-initorder.out cmp $^ > $@; \ $(evaluate-test) +@@ -1205,3 +1219,13 @@ $(objpfx)tst-unused-dep.out: $(objpfx)testobj1.so + $(objpfx)tst-unused-dep-cmp.out: $(objpfx)tst-unused-dep.out + cmp $< /dev/null > $@; \ + $(evaluate-test) ++ ++tst-prelink-ENV = LD_TRACE_PRELINKING=1 ++ ++$(objpfx)tst-prelink-conflict.out: $(objpfx)tst-prelink.out ++ grep stdout $< | grep conflict | $(AWK) '{ print $$10, $$11 }' > $@ ++ ++$(objpfx)tst-prelink-cmp.out: tst-prelink.exp \ ++ $(objpfx)tst-prelink-conflict.out ++ cmp $^ > $@; \ ++ $(evaluate-test) diff --git a/elf/dl-close.c b/elf/dl-close.c index 9105277..c897247 100644 --- a/elf/dl-close.c @@ -268,6 +458,208 @@ index 9105277..c897247 100644 } assert (idx == nloaded); +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 0c052e4..7e6f4c5 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + + #include +@@ -1471,9 +1472,13 @@ print_search_path (struct r_search_path_elem **list, + ignore only ELF files for other architectures. Non-ELF files and + ELF files with different header information cause fatal errors since + this could mean there is something wrong in the installation and the +- user might want to know about this. */ ++ user might want to know about this. ++ ++ If FD is not -1, then the file is already open and FD refers to it. ++ In that case, FD is consumed for both successful and error returns. */ + static int +-open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, ++open_verify (const char *name, int fd, ++ struct filebuf *fbp, struct link_map *loader, + int whatcode, int mode, bool *found_other_class, bool free_name) + { + /* This is the expected ELF header. */ +@@ -1514,6 +1519,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, + if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0 + && loader->l_auditing == 0) + { ++ const char *original_name = name; + struct audit_ifaces *afct = GLRO(dl_audit); + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { +@@ -1528,11 +1534,21 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, + + afct = afct->next; + } ++ ++ if (fd != -1 && name != original_name && strcmp (name, original_name)) ++ { ++ /* An audit library changed what we're supposed to open, ++ so FD no longer matches it. */ ++ __close (fd); ++ fd = -1; ++ } + } + #endif + +- /* Open the file. We always open files read-only. */ +- int fd = __open (name, O_RDONLY | O_CLOEXEC); ++ if (fd == -1) ++ /* Open the file. We always open files read-only. */ ++ fd = __open (name, O_RDONLY | O_CLOEXEC); ++ + if (fd != -1) + { + ElfW(Ehdr) *ehdr; +@@ -1801,7 +1817,7 @@ open_path (const char *name, size_t namelen, int mode, + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) + _dl_debug_printf (" trying file=%s\n", buf); + +- fd = open_verify (buf, fbp, loader, whatcode, mode, ++ fd = open_verify (buf, -1, fbp, loader, whatcode, mode, + found_other_class, false); + if (this_dir->status[cnt] == unknown) + { +@@ -2041,6 +2057,20 @@ _dl_map_object (struct link_map *loader, const char *name, + &loader->l_runpath_dirs, &realname, &fb, loader, + LA_SER_RUNPATH, &found_other_class); + ++ if (fd == -1) ++ { ++ realname = _dl_sysdep_open_object (name, namelen, &fd); ++ if (realname != NULL) ++ { ++ fd = open_verify (realname, fd, ++ &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, ++ LA_SER_CONFIG, mode, &found_other_class, ++ false); ++ if (fd == -1) ++ free (realname); ++ } ++ } ++ + #ifdef USE_LDCONFIG + if (fd == -1 + && (__glibc_likely ((mode & __RTLD_SECURE) == 0) +@@ -2086,7 +2116,7 @@ _dl_map_object (struct link_map *loader, const char *name, + + if (cached != NULL) + { +- fd = open_verify (cached, ++ fd = open_verify (cached, -1, + &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, + LA_SER_CONFIG, mode, &found_other_class, + false); +@@ -2121,7 +2151,7 @@ _dl_map_object (struct link_map *loader, const char *name, + fd = -1; + else + { +- fd = open_verify (realname, &fb, ++ fd = open_verify (realname, -1, &fb, + loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode, + &found_other_class, true); + if (__glibc_unlikely (fd == -1)) +diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c +index 11cb44b..acf5280 100644 +--- a/elf/dl-lookup.c ++++ b/elf/dl-lookup.c +@@ -1016,6 +1016,18 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, + #ifdef SHARED + if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) + { ++/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with ++ LD_TRACE_PRELINKING. */ ++#define RTYPE_CLASS_VALID 8 ++#define RTYPE_CLASS_PLT (8|1) ++#define RTYPE_CLASS_COPY (8|2) ++#define RTYPE_CLASS_TLS (8|4) ++#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1 ++# error ELF_RTYPE_CLASS_PLT must be 0 or 1! ++#endif ++#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2 ++# error ELF_RTYPE_CLASS_COPY must be 0 or 2! ++#endif + int conflict = 0; + struct sym_val val = { NULL, NULL }; + +@@ -1071,12 +1083,17 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, + + if (value->s) + { ++ /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY ++ bits since since prelink only uses them. */ ++ type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY; + if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) + == STT_TLS)) +- type_class = 4; ++ /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS. */ ++ type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID; + else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) + == STT_GNU_IFUNC)) +- type_class |= 8; ++ /* Set the RTYPE_CLASS_VALID bit. */ ++ type_class |= RTYPE_CLASS_VALID; + } + + if (conflict +diff --git a/elf/dl-sysdep-open.h b/elf/dl-sysdep-open.h +new file mode 100644 +index 0000000..a63d9f5 +--- /dev/null ++++ b/elf/dl-sysdep-open.h +@@ -0,0 +1,45 @@ ++/* System-specific call to open a shared object by name. 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 ++ . */ ++ ++#ifndef _DL_SYSDEP_OPEN_H ++#define _DL_SYSDEP_OPEN_H 1 ++ ++#include ++#include ++ ++/* NAME is a name without slashes, as it appears in a DT_NEEDED entry ++ or a dlopen call's argument or suchlike. NAMELEN is (strlen (NAME) + 1). ++ ++ Find NAME in an OS-dependent fashion, and return its "real" name. ++ Optionally fill in *FD with a file descriptor open on that file (or ++ else leave its initial value of -1). The return value is a new ++ malloc'd string, which will be free'd by the caller. If NAME is ++ resolved to an actual file that can be opened, then the return ++ value should name that file (and if *FD was not set, then a normal ++ __open call on that string will be made). If *FD was set by some ++ other means than a normal open and there is no "real" name to use, ++ then __strdup (NAME) is fine (modulo error checking). */ ++ ++static inline char * ++_dl_sysdep_open_object (const char *name, size_t namelen, int *fd) ++{ ++ assert (*fd == -1); ++ return NULL; ++} ++ ++#endif /* dl-sysdep-open.h */ diff --git a/elf/rtld.c b/elf/rtld.c index 69873c2..07e741c 100644 --- a/elf/rtld.c @@ -366,6 +758,49 @@ index 0000000..e88c756 +{ + return not_exist (); +} +diff --git a/elf/tst-prelink.c b/elf/tst-prelink.c +new file mode 100644 +index 0000000..ab61c4e +--- /dev/null ++++ b/elf/tst-prelink.c +@@ -0,0 +1,30 @@ ++/* Test the output from the environment variable, LD_TRACE_PRELINKING, ++ for prelink. ++ 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 ++ . */ ++ ++#include ++ ++static int ++do_test (void) ++{ ++ fprintf (stdout, "hello\n"); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-prelink.exp b/elf/tst-prelink.exp +new file mode 100644 +index 0000000..b35b4c9 +--- /dev/null ++++ b/elf/tst-prelink.exp +@@ -0,0 +1 @@ ++/0 stdout diff --git a/elf/tst-znodelete-zlib.cc b/elf/tst-znodelete-zlib.cc deleted file mode 100644 index 1e8f368..0000000 @@ -1050,6 +1485,142 @@ index 6749a44..1748886 100644 +# this coming up seems unlikely. +override sysdep_headers := $(sysdep_headers) endif +diff --git a/sysdeps/nacl/dl-map-segments.h b/sysdeps/nacl/dl-map-segments.h +index f305da3..f2d5d84 100644 +--- a/sysdeps/nacl/dl-map-segments.h ++++ b/sysdeps/nacl/dl-map-segments.h +@@ -53,7 +53,7 @@ _dl_map_segments (struct link_map *l, int fd, + const size_t maplength, bool has_holes, + struct link_map *loader) + { +- if (__builtin_expect (type, ET_DYN) == ET_DYN) ++ if (__glibc_likely (type == ET_DYN)) + { + /* This is a position-independent shared object. Let the system + choose where to place it. +@@ -165,6 +165,32 @@ _dl_map_segments (struct link_map *l, int fd, + errno = error; + return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; + } ++ if (__glibc_unlikely (type != ET_DYN)) ++ { ++ /* A successful PROT_EXEC mmap would have implicitly ++ updated the bookkeeping so that a future ++ allocate_code_data call would know that this range ++ of the address space is already occupied. That ++ doesn't happen implicitly with dyncode_create, so ++ it's necessary to do an explicit call to update the ++ bookkeeping. */ ++ uintptr_t allocated_address; ++ error = __nacl_irt_code_data_alloc.allocate_code_data ++ (l->l_addr + c->mapstart, len, 0, 0, &allocated_address); ++ if (__glibc_unlikely (error)) ++ { ++ errno = error; ++ return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; ++ } ++ if (__glibc_unlikely ++ (allocated_address != l->l_addr + c->mapstart)) ++ { ++ /* This is not a very helpful error for this case, ++ but there isn't really anything better to use. */ ++ errno = ENOMEM; ++ return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; ++ } ++ } + } + else + { +diff --git a/sysdeps/nacl/dl-sysdep-open.h b/sysdeps/nacl/dl-sysdep-open.h +new file mode 100644 +index 0000000..38b0f9e +--- /dev/null ++++ b/sysdeps/nacl/dl-sysdep-open.h +@@ -0,0 +1,40 @@ ++/* System-specific call to open a shared object 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 ++ . */ ++ ++#ifndef _DL_SYSDEP_OPEN_H ++#define _DL_SYSDEP_OPEN_H 1 ++ ++#include ++ ++/* NAME is a name without slashes, as it appears in a DT_NEEDED entry ++ or a dlopen call's argument or suchlike. NAMELEN is (strlen (NAME) + 1). ++ ++ Find NAME in an OS-dependent fashion, and return its "real" name. ++ Optionally fill in *FD with a file descriptor open on that file (or ++ else leave its initial value of -1). The return value is a new ++ malloc'd string, which will be free'd by the caller. If NAME is ++ resolved to an actual file that can be opened, then the return ++ value should name that file (and if *FD was not set, then a normal ++ __open call on that string will be made). If *FD was set by some ++ other means than a normal open and there is no "real" name to use, ++ then __strdup (NAME) is fine (modulo error checking). */ ++ ++extern char *_dl_sysdep_open_object (const char *name, size_t namelen, int *fd) ++ internal_function attribute_hidden; ++ ++#endif /* dl-sysdep-open.h */ +diff --git a/sysdeps/nacl/dl-sysdep.c b/sysdeps/nacl/dl-sysdep.c +index 3e902c2..3a04aa1 100644 +--- a/sysdeps/nacl/dl-sysdep.c ++++ b/sysdeps/nacl/dl-sysdep.c +@@ -87,3 +87,26 @@ _dl_start_user (void (*user_entry) (uint32_t info[]), uint32_t info[]) + #endif /* SHARED */ + + #include ++ ++#include ++#include ++#include ++#include ++#include ++ ++char * ++internal_function ++_dl_sysdep_open_object (const char *name, size_t namelen, int *fd) ++{ ++ int error = __nacl_irt_resource_open.open_resource (name, fd); ++ if (error) ++ return NULL; ++ assert (*fd != -1); ++ char *realname = __strdup (name); ++ if (__glibc_unlikely (realname == NULL)) ++ { ++ __close (*fd); ++ *fd = -1; ++ } ++ return realname; ++} +diff --git a/sysdeps/nacl/nacl-interface-list.h b/sysdeps/nacl/nacl-interface-list.h +index cb33751..c68faed 100644 +--- a/sysdeps/nacl/nacl-interface-list.h ++++ b/sysdeps/nacl/nacl-interface-list.h +@@ -28,7 +28,7 @@ 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_MANDATORY_INTERFACE (rtld, + NACL_IRT_RESOURCE_OPEN_v0_1, nacl_irt_resource_open) + NACL_MANDATORY_INTERFACE (rtld, + NACL_IRT_CODE_DATA_ALLOC_v0_1, diff --git a/sysdeps/nacl/start.c b/sysdeps/nacl/start.c index a4b6dd3..8e8bc1a 100644 --- a/sysdeps/nacl/start.c