Merge "Add monotonic logging for bionic"
diff --git a/benchmarks/Benchmark.cpp b/benchmarks/Benchmark.cpp
index ea6000f..a7ab682 100644
--- a/benchmarks/Benchmark.cpp
+++ b/benchmarks/Benchmark.cpp
@@ -24,7 +24,7 @@
#include <string>
#include <vector>
-#include <base/stringprintf.h>
+#include <android-base/stringprintf.h>
#include <benchmark/Benchmark.h>
diff --git a/benchmarks/utils.cpp b/benchmarks/utils.cpp
index cf17edb..8bbd20a 100644
--- a/benchmarks/utils.cpp
+++ b/benchmarks/utils.cpp
@@ -23,7 +23,7 @@
#include <string>
-#include <base/stringprintf.h>
+#include <android-base/stringprintf.h>
int Round(int n) {
int base = 1;
diff --git a/libc/bionic/flockfile.cpp b/libc/bionic/flockfile.cpp
index db68801..db53828 100644
--- a/libc/bionic/flockfile.cpp
+++ b/libc/bionic/flockfile.cpp
@@ -36,20 +36,12 @@
// struct __sfileext (see fileext.h).
void flockfile(FILE* fp) {
- if (!__sdidinit) {
- __sinit();
- }
-
if (fp != nullptr) {
pthread_mutex_lock(&_FLOCK(fp));
}
}
int ftrylockfile(FILE* fp) {
- if (!__sdidinit) {
- __sinit();
- }
-
// The specification for ftrylockfile() says it returns 0 on success,
// or non-zero on error. So return an errno code directly on error.
if (fp == nullptr) {
@@ -60,10 +52,6 @@
}
void funlockfile(FILE* fp) {
- if (!__sdidinit) {
- __sinit();
- }
-
if (fp != nullptr) {
pthread_mutex_unlock(&_FLOCK(fp));
}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 91e210e..8f1ee95 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -54,7 +54,6 @@
extern "C" int __system_properties_init(void);
extern "C" int __set_tls(void* ptr);
extern "C" int __set_tid_address(int* tid_address);
-extern "C" int __sinit(void);
__LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
@@ -134,9 +133,6 @@
__pthread_internal_add(main_thread);
__system_properties_init(); // Requires 'environ'.
- // Initialize stdio here to get rid of data races caused by lazy initialization.
- // TODO: Remove other calls to __sinit().
- __sinit();
}
__noreturn static void __early_abort(int line) {
diff --git a/libc/bionic/ndk_cruft.cpp b/libc/bionic/ndk_cruft.cpp
index d6b8e8f..0429430 100644
--- a/libc/bionic/ndk_cruft.cpp
+++ b/libc/bionic/ndk_cruft.cpp
@@ -47,6 +47,8 @@
#include "private/libc_logging.h"
+extern "C" {
+
// Brillo doesn't need to support any legacy cruft.
#if !defined(__BRILLO__)
@@ -55,29 +57,27 @@
// These were accidentally declared in <unistd.h> because we stupidly used to inline
// getpagesize() and __getpageshift(). Needed for backwards compatibility with old NDK apps.
-extern "C" {
- unsigned int __page_size = PAGE_SIZE;
- unsigned int __page_shift = 12;
-}
+unsigned int __page_size = PAGE_SIZE;
+unsigned int __page_shift = 12;
// TODO: remove this backward compatibility hack (for jb-mr1 strace binaries).
-extern "C" pid_t __wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
+pid_t __wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
return wait4(pid, status, options, rusage);
}
// TODO: does anything still need this?
-extern "C" int __open() {
+int __open() {
abort();
}
// TODO: does anything still need this?
-extern "C" void** __get_tls() {
+void** __get_tls() {
#include "private/__get_tls.h"
return __get_tls();
}
// This non-standard function was in our <string.h> for some reason.
-extern "C" void memswap(void* m1, void* m2, size_t n) {
+void memswap(void* m1, void* m2, size_t n) {
char* p = reinterpret_cast<char*>(m1);
char* p_end = p + n;
char* q = reinterpret_cast<char*>(m2);
@@ -90,13 +90,13 @@
}
}
-extern "C" int pthread_attr_setstackaddr(pthread_attr_t*, void*) {
+int pthread_attr_setstackaddr(pthread_attr_t*, void*) {
// This was removed from POSIX.1-2008, and is not implemented on bionic.
// Needed for ABI compatibility with the NDK.
return ENOSYS;
}
-extern "C" int pthread_attr_getstackaddr(const pthread_attr_t* attr, void** stack_addr) {
+int pthread_attr_getstackaddr(const pthread_attr_t* attr, void** stack_addr) {
// This was removed from POSIX.1-2008.
// Needed for ABI compatibility with the NDK.
*stack_addr = (char*)attr->stack_base + attr->stack_size;
@@ -104,7 +104,7 @@
}
// Non-standard cruft that should only ever have been in system/core/toolbox.
-extern "C" char* strtotimeval(const char* str, struct timeval* ts) {
+char* strtotimeval(const char* str, struct timeval* ts) {
char* s;
ts->tv_sec = strtoumax(str, &s, 10);
@@ -146,7 +146,7 @@
}
// This non-standard function was in our <inttypes.h> for some reason.
-extern "C" uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) {
+uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) {
const unsigned char* p = (const unsigned char *)nptr;
const unsigned char* end = p + n;
int minus = 0;
@@ -194,12 +194,12 @@
}
// This non-standard function was in our <inttypes.h> for some reason.
-extern "C" intmax_t strntoimax(const char* nptr, char** endptr, int base, size_t n) {
+intmax_t strntoimax(const char* nptr, char** endptr, int base, size_t n) {
return (intmax_t) strntoumax(nptr, endptr, base, n);
}
// POSIX calls this dprintf, but LP32 Android had fdprintf instead.
-extern "C" int fdprintf(int fd, const char* fmt, ...) {
+int fdprintf(int fd, const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
int rc = vdprintf(fd, fmt, ap);
@@ -208,7 +208,7 @@
}
// POSIX calls this vdprintf, but LP32 Android had fdprintf instead.
-extern "C" int vfdprintf(int fd, const char* fmt, va_list ap) {
+int vfdprintf(int fd, const char* fmt, va_list ap) {
return vdprintf(fd, fmt, ap);
}
@@ -219,64 +219,64 @@
#undef __futex_wait
// This used to be in <sys/atomics.h>.
-extern "C" int __futex_wake(volatile void* ftx, int count) {
+int __futex_wake(volatile void* ftx, int count) {
return __real_futex_wake(ftx, count);
}
// This used to be in <sys/atomics.h>.
-extern "C" int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
+int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
return __real_futex_wait(ftx, value, timeout);
}
// Unity's libmono uses this.
-extern "C" int tkill(pid_t tid, int sig) {
+int tkill(pid_t tid, int sig) {
return syscall(__NR_tkill, tid, sig);
}
// This was removed from POSIX 2008.
-extern "C" wchar_t* wcswcs(wchar_t* haystack, wchar_t* needle) {
+wchar_t* wcswcs(wchar_t* haystack, wchar_t* needle) {
return wcsstr(haystack, needle);
}
// This was removed from POSIX 2008.
-extern "C" sighandler_t bsd_signal(int signum, sighandler_t handler) {
+sighandler_t bsd_signal(int signum, sighandler_t handler) {
return signal(signum, handler);
}
#if !defined(__i386__)
// This was removed from POSIX 2008.
#undef bcopy
-extern "C" void bcopy(const void* src, void* dst, size_t n) {
- memcpy(dst, src, n);
+void bcopy(const void* src, void* dst, size_t n) {
+ memmove(dst, src, n);
}
#else
// x86 has an assembler implementation.
#endif
// sysv_signal() was never in POSIX.
-extern sighandler_t _signal(int signum, sighandler_t handler, int flags);
-extern "C" sighandler_t sysv_signal(int signum, sighandler_t handler) {
+extern "C++" sighandler_t _signal(int signum, sighandler_t handler, int flags);
+sighandler_t sysv_signal(int signum, sighandler_t handler) {
return _signal(signum, handler, SA_RESETHAND);
}
// This is a system call that was never in POSIX. Use readdir(3) instead.
-extern "C" int __getdents64(unsigned int, dirent*, unsigned int);
-extern "C" int getdents(unsigned int fd, dirent* dirp, unsigned int count) {
+int __getdents64(unsigned int, dirent*, unsigned int);
+int getdents(unsigned int fd, dirent* dirp, unsigned int count) {
return __getdents64(fd, dirp, count);
}
// This is a BSDism that we never implemented correctly. Used by Firefox.
-extern "C" int issetugid() {
+int issetugid() {
return 0;
}
// This was removed from POSIX 2004.
-extern "C" pid_t wait3(int* status, int options, struct rusage* rusage) {
+pid_t wait3(int* status, int options, struct rusage* rusage) {
return wait4(-1, status, options, rusage);
}
// This was removed from POSIX 2004.
-extern "C" int getdtablesize() {
+int getdtablesize() {
struct rlimit r;
if (getrlimit(RLIMIT_NOFILE, &r) < 0) {
@@ -286,6 +286,10 @@
return r.rlim_cur;
}
+// A leaked BSD stdio implementation detail that's now a no-op.
+void __sinit() {}
+int __sdidinit = 1;
+
// Only used by ftime, which was removed from POSIX 2008.
struct timeb {
time_t time;
@@ -295,7 +299,7 @@
};
// This was removed from POSIX 2008.
-extern "C" int ftime(struct timeb* tb) {
+int ftime(struct timeb* tb) {
struct timeval tv;
struct timezone tz;
@@ -317,35 +321,35 @@
}
// This was removed from POSIX 2008.
-extern "C" char* index(const char* str, int ch) {
+char* index(const char* str, int ch) {
return strchr(str, ch);
}
// This was removed from BSD.
-extern "C" void arc4random_stir(void) {
+void arc4random_stir(void) {
// The current implementation stirs itself as needed.
}
// This was removed from BSD.
-extern "C" void arc4random_addrandom(unsigned char*, int) {
+void arc4random_addrandom(unsigned char*, int) {
// The current implementation adds randomness as needed.
}
// Old versions of the NDK did not export malloc_usable_size, but did
// export dlmalloc_usable_size. We are moving away from dlmalloc in L
// so make this call malloc_usable_size.
-extern "C" size_t dlmalloc_usable_size(void* ptr) {
+size_t dlmalloc_usable_size(void* ptr) {
return malloc_usable_size(ptr);
}
// In L we added a public pthread_gettid_np, but some apps were using the private API.
-extern "C" pid_t __pthread_gettid(pthread_t t) {
+pid_t __pthread_gettid(pthread_t t) {
return pthread_gettid_np(t);
}
// Older versions of apportable used dlmalloc directly instead of malloc,
// so export this compatibility shim that simply calls malloc.
-extern "C" void* dlmalloc(size_t size) {
+void* dlmalloc(size_t size) {
return malloc(size);
}
@@ -353,13 +357,13 @@
#include "pthread_internal.h"
#undef __get_thread
// Various third-party apps contain a backport of our pthread_rwlock implementation that uses this.
-extern "C" pthread_internal_t* __get_thread() {
+pthread_internal_t* __get_thread() {
return __real_get_thread();
}
// This one exists only for the LP32 NDK and is not present anywhere else.
-extern "C" long __set_errno_internal(int);
-extern "C" long __set_errno(int n) {
+extern long __set_errno_internal(int);
+long __set_errno(int n) {
return __set_errno_internal(n);
}
@@ -367,25 +371,27 @@
// This was never implemented in bionic, only needed for ABI compatibility with the NDK.
// In the M time frame, over 1000 apps have a reference to this!
-extern "C" void endpwent() { }
+void endpwent() { }
// Since dlmalloc_inspect_all and dlmalloc_trim are exported for systems
// that use dlmalloc, be consistent and export them everywhere.
#if defined(USE_JEMALLOC)
-extern "C" void dlmalloc_inspect_all(void (*)(void*, void*, size_t, void*), void*) {
+void dlmalloc_inspect_all(void (*)(void*, void*, size_t, void*), void*) {
}
-extern "C" int dlmalloc_trim(size_t) {
+int dlmalloc_trim(size_t) {
return 0;
}
#else
-extern "C" void dlmalloc_inspect_all_real(void (*)(void*, void*, size_t, void*), void*);
-extern "C" void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg) {
+void dlmalloc_inspect_all_real(void (*)(void*, void*, size_t, void*), void*);
+void dlmalloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg) {
dlmalloc_inspect_all_real(handler, arg);
}
-extern "C" int dlmalloc_trim_real(size_t);
-extern "C" int dlmalloc_trim(size_t pad) {
+int dlmalloc_trim_real(size_t);
+int dlmalloc_trim(size_t pad) {
return dlmalloc_trim_real(pad);
}
#endif
#endif // !defined(__BRILLO__)
+
+} // extern "C"
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index 3fd41d7..b9a373e 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -915,6 +915,16 @@
free(prop_prefix);
continue;
}
+ /*
+ * init uses ctl.* properties as an IPC mechanism and does not write them
+ * to a property file, therefore we do not need to create property files
+ * to store them.
+ */
+ if (!strncmp(prop_prefix, "ctl.", 4)) {
+ free(prop_prefix);
+ free(context);
+ continue;
+ }
auto old_context = list_find(
contexts, [context](context_node* l) { return !strcmp(l->context, context); });
@@ -1006,6 +1016,10 @@
const prop_info *__system_property_find(const char *name)
{
+ if (!__system_property_area__) {
+ return nullptr;
+ }
+
if (__predict_false(compat_mode)) {
return __system_property_find_compat(name);
}
@@ -1091,11 +1105,15 @@
int __system_property_update(prop_info *pi, const char *value, unsigned int len)
{
- prop_area *pa = __system_property_area__;
-
if (len >= PROP_VALUE_MAX)
return -1;
+ prop_area* pa = __system_property_area__;
+
+ if (!pa) {
+ return -1;
+ }
+
uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed);
serial |= 1;
atomic_store_explicit(&pi->serial, serial, memory_order_relaxed);
@@ -1129,6 +1147,10 @@
if (namelen < 1)
return -1;
+ if (!__system_property_area__) {
+ return -1;
+ }
+
prop_area* pa = get_prop_area_for_name(name);
if (!pa) {
@@ -1168,6 +1190,10 @@
prop_area *pa = __system_property_area__;
uint32_t my_serial;
+ if (!pa) {
+ return 0;
+ }
+
do {
__futex_wait(pa->serial(), serial, NULL);
my_serial = atomic_load_explicit(pa->serial(), memory_order_acquire);
@@ -1191,6 +1217,10 @@
int __system_property_foreach(void (*propfn)(const prop_info *pi, void *cookie),
void *cookie)
{
+ if (!__system_property_area__) {
+ return -1;
+ }
+
if (__predict_false(compat_mode)) {
return __system_property_foreach_compat(propfn, cookie);
}
diff --git a/libc/stdio/findfp.c b/libc/stdio/findfp.c
index 2696cfd..6e20562 100644
--- a/libc/stdio/findfp.c
+++ b/libc/stdio/findfp.c
@@ -44,37 +44,44 @@
#define ALIGNBYTES (sizeof(uintptr_t) - 1)
#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
-int __sdidinit;
-
#define NDYNAMIC 10 /* add ten more whenever necessary */
#define std(flags, file) \
{0,0,0,flags,file,{0,0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \
{(unsigned char *)(__sFext+file), 0},NULL,0,{0},{0},{0,0},0,0}
- /* the usual - (stdin + stdout + stderr) */
-static FILE usual[FOPEN_MAX - 3];
-static struct __sfileext usualext[FOPEN_MAX - 3];
-static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
-static struct glue *lastglue = &uglue;
_THREAD_PRIVATE_MUTEX(__sfp_mutex);
-static struct __sfileext __sFext[3];
+// TODO: when we no longer have to support both clang and GCC, we can simplify all this.
+#define SBUF_INIT {0,0}
+#if defined(__LP64__)
+#define MBSTATE_T_INIT {{0},{0}}
+#else
+#define MBSTATE_T_INIT {{0}}
+#endif
+#define WCHAR_IO_DATA_INIT {MBSTATE_T_INIT,MBSTATE_T_INIT,{0},0,0}
+
+static struct __sfileext __sFext[3] = {
+ { SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false },
+ { SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false },
+ { SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false },
+};
// __sF is exported for backwards compatibility. Until M, we didn't have symbols
// for stdin/stdout/stderr; they were macros accessing __sF.
FILE __sF[3] = {
- std(__SRD, STDIN_FILENO), /* stdin */
- std(__SWR, STDOUT_FILENO), /* stdout */
- std(__SWR|__SNBF, STDERR_FILENO) /* stderr */
+ std(__SRD, STDIN_FILENO),
+ std(__SWR, STDOUT_FILENO),
+ std(__SWR|__SNBF, STDERR_FILENO),
};
-struct glue __sglue = { &uglue, 3, __sF };
-
FILE* stdin = &__sF[0];
FILE* stdout = &__sF[1];
FILE* stderr = &__sF[2];
+struct glue __sglue = { NULL, 3, __sF };
+static struct glue* lastglue = &__sglue;
+
static struct glue *
moreglue(int n)
{
@@ -114,9 +121,6 @@
int n;
struct glue *g;
- if (!__sdidinit)
- __sinit();
-
_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
for (g = &__sglue; g != NULL; g = g->next) {
for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
@@ -149,48 +153,7 @@
return (fp);
}
-/*
- * exit() and abort() call _cleanup() through the callback registered
- * with __atexit_register_cleanup(), set whenever we open or buffer a
- * file. This chicanery is done so that programs that do not use stdio
- * need not link it all in.
- *
- * The name `_cleanup' is, alas, fairly well known outside stdio.
- */
-void
-_cleanup(void)
-{
+__LIBC_HIDDEN__ void __libc_stdio_cleanup(void) {
/* (void) _fwalk(fclose); */
(void) _fwalk(__sflush); /* `cheating' */
}
-
-/*
- * __sinit() is called whenever stdio's internal variables must be set up.
- */
-void
-__sinit(void)
-{
- _THREAD_PRIVATE_MUTEX(__sinit_mutex);
-
- _THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex);
- if (__sdidinit) {
- /* bail out if caller lost the race */
- _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
- return;
- }
-
- /* Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. */
- for (size_t i = 0; i < 3; ++i) {
- _FILEEXT_SETUP(__sF+i, __sFext+i);
- }
- /* Initialize the pre-allocated (but initially unused) streams. */
- for (size_t i = 0; i < FOPEN_MAX - 3; ++i) {
- _FILEEXT_SETUP(usual+i, usualext+i);
- }
-
- /* make sure we clean up on exit */
- __atexit_register_cleanup(_cleanup); /* conservative */
- __sdidinit = 1;
-
- _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
-}
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 3ae7059..6dcd3ae 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -153,10 +153,8 @@
__LIBC32_LEGACY_PUBLIC__ int __swsetup(FILE*);
/* These were referenced by a couple of different pieces of middleware and the Crystax NDK. */
-__LIBC32_LEGACY_PUBLIC__ extern int __sdidinit;
__LIBC32_LEGACY_PUBLIC__ int __sflags(const char*, int*);
__LIBC32_LEGACY_PUBLIC__ FILE* __sfp(void);
-__LIBC32_LEGACY_PUBLIC__ void __sinit(void);
__LIBC32_LEGACY_PUBLIC__ void __smakebuf(FILE*);
/* These are referenced by the Greed for Glory franchise. */
@@ -170,7 +168,6 @@
#pragma GCC visibility push(hidden)
int __sflush_locked(FILE *);
-void _cleanup(void);
int __swhatbuf(FILE *, size_t *, int *);
wint_t __fgetwc_unlock(FILE *);
wint_t __ungetwc(wint_t, FILE *);
@@ -179,8 +176,6 @@
int __vfwprintf(FILE * __restrict, const wchar_t * __restrict, __va_list);
int __vfwscanf(FILE * __restrict, const wchar_t * __restrict, __va_list);
-extern void __atexit_register_cleanup(void (*)(void));
-
/*
* Return true if the given FILE cannot be written now.
*/
@@ -237,6 +232,10 @@
extern int __sfvwrite(FILE *, struct __suio *);
wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
+/* Remove the if (!__sdidinit) __sinit() idiom from untouched upstream stdio code. */
+extern void __sinit(void); // Not actually implemented.
+#define __sdidinit 1
+
#pragma GCC visibility pop
__END_DECLS
diff --git a/libc/stdio/refill.c b/libc/stdio/refill.c
index e87c7b9..5b0811f 100644
--- a/libc/stdio/refill.c
+++ b/libc/stdio/refill.c
@@ -51,11 +51,6 @@
int
__srefill(FILE *fp)
{
-
- /* make sure stdio is set up */
- if (!__sdidinit)
- __sinit();
-
fp->_r = 0; /* largely a convenience for callers */
#if !defined(__ANDROID__)
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index 34a4db1..c817b63 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -185,51 +185,12 @@
}
_ATEXIT_UNLOCK();
+ extern void __libc_stdio_cleanup(void);
+ __libc_stdio_cleanup();
+
/* BEGIN android-changed: call __unregister_atfork if dso is not null */
if (dso != NULL) {
__unregister_atfork(dso);
}
/* END android-changed */
}
-
-/*
- * Register the cleanup function
- */
-void
-__atexit_register_cleanup(void (*func)(void))
-{
- struct atexit *p;
- size_t pgsize = getpagesize();
-
- if (pgsize < sizeof(*p))
- return;
- _ATEXIT_LOCK();
- p = __atexit;
- while (p != NULL && p->next != NULL)
- p = p->next;
- if (p == NULL) {
- p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
- MAP_ANON | MAP_PRIVATE, -1, 0);
- if (p == MAP_FAILED)
- goto unlock;
-/* BEGIN android-changed */
- prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, pgsize,
- "atexit handlers");
-/* END android-changed */
- p->ind = 1;
- p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
- sizeof(p->fns[0]);
- p->next = NULL;
- __atexit = p;
- } else {
- if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
- goto unlock;
- }
- p->fns[0].fn_ptr = (void (*)(void *))func;
- p->fns[0].fn_arg = NULL;
- p->fns[0].fn_dso = NULL;
- mprotect(p, pgsize, PROT_READ);
- restartloop = 1;
-unlock:
- _ATEXIT_UNLOCK();
-}
diff --git a/libc/upstream-netbsd/android/include/netbsd-compat.h b/libc/upstream-netbsd/android/include/netbsd-compat.h
index 0212d16..8d1c46b 100644
--- a/libc/upstream-netbsd/android/include/netbsd-compat.h
+++ b/libc/upstream-netbsd/android/include/netbsd-compat.h
@@ -32,6 +32,6 @@
#define __unlockenv() 0
#include <stddef.h>
-int reallocarr(void*, size_t, size_t);
+__LIBC_HIDDEN__ int reallocarr(void*, size_t, size_t);
#endif
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 9780231..82d0d9e 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -60,7 +60,7 @@
#include "linker_reloc_iterators.h"
#include "linker_utils.h"
-#include "base/strings.h"
+#include "android-base/strings.h"
#include "ziparchive/zip_archive.h"
extern void __libc_init_globals(KernelArgumentBlock&);
@@ -1582,9 +1582,6 @@
}
}
- if (fd != -1 && !ns->is_accessible(*realpath)) {
- fd = -1;
- }
return fd;
}
@@ -1701,6 +1698,13 @@
return false;
}
+ if (!ns->is_accessible(realpath)) {
+ // do not load libraries if they are not accessible for the specified namespace.
+ DL_ERR("library \"%s\" is not accessible for the namespace \"%s\"",
+ name, ns->get_name());
+ return false;
+ }
+
soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags);
if (si == nullptr) {
return false;
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 83791eb..97b5208 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -617,7 +617,8 @@
const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
- void* handle_public = dlopen((lib_path + "/public_namespace_libs/" + g_public_lib).c_str(), RTLD_NOW);
+ const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+ void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
ASSERT_TRUE(handle_public != nullptr) << dlerror();
ASSERT_TRUE(android_init_namespaces(path.c_str(), nullptr)) << dlerror();
@@ -652,6 +653,14 @@
ASSERT_TRUE(handle1 != handle2);
+ // dlopen for a public library using an absolute path should work for isolated namespaces
+ extinfo.library_namespace = ns2;
+ handle = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo);
+ ASSERT_TRUE(handle != nullptr) << dlerror();
+ ASSERT_TRUE(handle == handle_public);
+
+ dlclose(handle);
+
typedef const char* (*fn_t)();
fn_t ns_get_local_string1 = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_local_string"));
@@ -715,7 +724,8 @@
std::string path = std::string("libc.so:libc++.so:libdl.so:libm.so:") + g_public_lib;
const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
- void* handle_public = dlopen((lib_path + "/public_namespace_libs/" + g_public_lib).c_str(), RTLD_NOW);
+ const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+ void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
ASSERT_TRUE(handle_public != nullptr) << dlerror();
android_set_application_target_sdk_version(42U); // something > 23
@@ -758,7 +768,7 @@
// Check dlopen by absolute path
handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
ASSERT_TRUE(handle2 == nullptr);
- ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" not found", dlerror());
+ ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" is not accessible for the namespace \"private_isolated1\"", dlerror());
extinfo.library_namespace = ns_isolated2;
@@ -769,7 +779,7 @@
// Check dlopen by absolute path
handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
ASSERT_TRUE(handle2 == nullptr);
- ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" not found", dlerror());
+ ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" is not accessible for the namespace \"private_isolated2\"", dlerror());
typedef const char* (*fn_t)();
fn_t ns_get_local_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_local_string"));
@@ -803,8 +813,9 @@
const std::string lib_path = std::string(getenv("ANDROID_DATA")) + NATIVE_TESTS_PATH;
- void* handle_public = dlopen((lib_path + "/public_namespace_libs/" + g_public_lib).c_str(),
- RTLD_NOW);
+ const std::string lib_public_path = lib_path + "/public_namespace_libs/" + g_public_lib;
+ void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
+
ASSERT_TRUE(handle_public != nullptr) << dlerror();
ASSERT_TRUE(android_init_namespaces(path.c_str(), (lib_path + "/private_namespace_libs").c_str()))
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 0a97abc..5e06b1f 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -30,8 +30,8 @@
#include <sys/wait.h>
#include <unistd.h>
-#include <base/file.h>
-#include <base/strings.h>
+#include <android-base/file.h>
+#include <android-base/strings.h>
#include "private/get_cpu_count_from_string.h"
diff --git a/tests/utils.h b/tests/utils.h
index 9e77f24..a8f3441 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -24,8 +24,8 @@
#include <string>
#include <regex>
-#include <base/file.h>
-#include <base/stringprintf.h>
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
#include "private/ScopeGuard.h"