Merge "Pass around struct android_net_context for better behaviour"
diff --git a/libc/include/sysexits.h b/libc/include/sysexits.h
new file mode 100644
index 0000000..e244836
--- /dev/null
+++ b/libc/include/sysexits.h
@@ -0,0 +1,119 @@
+/* $OpenBSD: sysexits.h,v 1.5 2003/06/02 19:34:12 millert Exp $ */
+/* $NetBSD: sysexits.h,v 1.4 1994/10/26 00:56:33 cgd Exp $ */
+
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sysexits.h 4.8 (Berkeley) 4/3/91
+ */
+
+#ifndef _SYSEXITS_H_
+#define _SYSEXITS_H_
+
+/*
+ * SYSEXITS.H -- Exit status codes for system programs.
+ *
+ * This include file attempts to categorize possible error
+ * exit statuses for system programs, notably delivermail
+ * and the Berkeley network.
+ *
+ * Error numbers begin at EX__BASE to reduce the possibility of
+ * clashing with other exit statuses that random programs may
+ * already return. The meaning of the codes is approximately
+ * as follows:
+ *
+ * EX_USAGE -- The command was used incorrectly, e.g., with
+ * the wrong number of arguments, a bad flag, a bad
+ * syntax in a parameter, or whatever.
+ * EX_DATAERR -- The input data was incorrect in some way.
+ * This should only be used for user's data & not
+ * system files.
+ * EX_NOINPUT -- An input file (not a system file) did not
+ * exist or was not readable. This could also include
+ * errors like "No message" to a mailer (if it cared
+ * to catch it).
+ * EX_NOUSER -- The user specified did not exist. This might
+ * be used for mail addresses or remote logins.
+ * EX_NOHOST -- The host specified did not exist. This is used
+ * in mail addresses or network requests.
+ * EX_UNAVAILABLE -- A service is unavailable. This can occur
+ * if a support program or file does not exist. This
+ * can also be used as a catchall message when something
+ * you wanted to do doesn't work, but you don't know
+ * why.
+ * EX_SOFTWARE -- An internal software error has been detected.
+ * This should be limited to non-operating system related
+ * errors as possible.
+ * EX_OSERR -- An operating system error has been detected.
+ * This is intended to be used for such things as "cannot
+ * fork", "cannot create pipe", or the like. It includes
+ * things like getuid returning a user that does not
+ * exist in the passwd file.
+ * EX_OSFILE -- Some system file (e.g., /etc/passwd, /var/run/utmp,
+ * etc.) does not exist, cannot be opened, or has some
+ * sort of error (e.g., syntax error).
+ * EX_CANTCREAT -- A (user specified) output file cannot be
+ * created.
+ * EX_IOERR -- An error occurred while doing I/O on some file.
+ * EX_TEMPFAIL -- temporary failure, indicating something that
+ * is not really an error. In sendmail, this means
+ * that a mailer (e.g.) could not create a connection,
+ * and the request should be reattempted later.
+ * EX_PROTOCOL -- the remote system returned something that
+ * was "not possible" during a protocol exchange.
+ * EX_NOPERM -- You did not have sufficient permission to
+ * perform the operation. This is not intended for
+ * file system problems, which should use EX_NOINPUT or
+ * EX_CANTCREAT, but rather for higher level permissions.
+ * EX_CONFIG -- Something was found in an unconfigured or
+ * misconfigured state.
+ */
+
+#define EX_OK 0 /* successful termination */
+
+#define EX__BASE 64 /* base value for error messages */
+
+#define EX_USAGE 64 /* command line usage error */
+#define EX_DATAERR 65 /* data format error */
+#define EX_NOINPUT 66 /* cannot open input */
+#define EX_NOUSER 67 /* addressee unknown */
+#define EX_NOHOST 68 /* host name unknown */
+#define EX_UNAVAILABLE 69 /* service unavailable */
+#define EX_SOFTWARE 70 /* internal software error */
+#define EX_OSERR 71 /* system error (e.g., can't fork) */
+#define EX_OSFILE 72 /* critical OS file missing */
+#define EX_CANTCREAT 73 /* can't create (user) output file */
+#define EX_IOERR 74 /* input/output error */
+#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
+#define EX_PROTOCOL 76 /* remote error in protocol */
+#define EX_NOPERM 77 /* permission denied */
+#define EX_CONFIG 78 /* configuration error */
+
+#define EX__MAX 78 /* maximum listed value */
+
+#endif /* !_SYSEXITS_H_ */
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index a70abf5..ef454ab 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -158,6 +158,11 @@
return 0;
}
+int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ return do_dl_iterate_phdr(cb, data);
+}
+
void android_set_application_target_sdk_version(uint32_t target) {
// lock to avoid modification in the middle of dlopen.
ScopedPthreadMutexLocker locker(&g_dl_mutex);
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b9a8f9d..c6e569a 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -393,7 +393,7 @@
// Here, we only have to provide a callback to iterate across all the
// loaded libraries. gcc_eh does the rest.
-int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
int rv = 0;
for (soinfo* si = solist; si != nullptr; si = si->next) {
dl_phdr_info dl_info;
@@ -1159,7 +1159,7 @@
ZipEntry entry;
- if (FindEntry(handle, ZipEntryName(file_path), &entry) != 0) {
+ if (FindEntry(handle, ZipString(file_path), &entry) != 0) {
// Entry was not found.
close(fd);
return -1;
diff --git a/linker/linker.h b/linker/linker.h
index 43b1e07..9bca7f3 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -428,6 +428,8 @@
soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo);
void do_dlclose(soinfo* si);
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
+
const ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle);
soinfo* find_containing_library(const void* addr);
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 1c01c62..92e3287 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -51,12 +51,12 @@
TEST(dlfcn, dlsym_in_executable) {
dlerror(); // Clear any pending errors.
- void* self = dlopen(NULL, RTLD_NOW);
- ASSERT_TRUE(self != NULL);
- ASSERT_TRUE(dlerror() == NULL);
+ void* self = dlopen(nullptr, RTLD_NOW);
+ ASSERT_TRUE(self != nullptr);
+ ASSERT_TRUE(dlerror() == nullptr);
void* sym = dlsym(self, "DlSymTestFunction");
- ASSERT_TRUE(sym != NULL);
+ ASSERT_TRUE(sym != nullptr);
void (*function)() = reinterpret_cast<void(*)()>(sym);
@@ -175,11 +175,11 @@
TEST(dlfcn, dlopen_noload) {
void* handle = dlopen("libtest_simple.so", RTLD_NOW | RTLD_NOLOAD);
- ASSERT_TRUE(handle == NULL);
+ ASSERT_TRUE(handle == nullptr);
handle = dlopen("libtest_simple.so", RTLD_NOW);
void* handle2 = dlopen("libtest_simple.so", RTLD_NOW | RTLD_NOLOAD);
- ASSERT_TRUE(handle != NULL);
- ASSERT_TRUE(handle2 != NULL);
+ ASSERT_TRUE(handle != nullptr);
+ ASSERT_TRUE(handle2 != nullptr);
ASSERT_TRUE(handle == handle2);
ASSERT_EQ(0, dlclose(handle));
ASSERT_EQ(0, dlclose(handle2));
@@ -220,11 +220,11 @@
// first check the set case
setenv("IFUNC_CHOICE", "set", 1);
void* handle = dlopen("libtest_ifunc.so", RTLD_NOW);
- ASSERT_TRUE(handle != NULL);
+ ASSERT_TRUE(handle != nullptr);
fn_ptr foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo"));
fn_ptr foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library"));
- ASSERT_TRUE(foo_ptr != NULL);
- ASSERT_TRUE(foo_library_ptr != NULL);
+ ASSERT_TRUE(foo_ptr != nullptr);
+ ASSERT_TRUE(foo_library_ptr != nullptr);
ASSERT_EQ(strncmp("set", foo_ptr(), 3), 0);
ASSERT_EQ(strncmp("set", foo_library_ptr(), 3), 0);
dlclose(handle);
@@ -232,11 +232,11 @@
// then check the unset case
unsetenv("IFUNC_CHOICE");
handle = dlopen("libtest_ifunc.so", RTLD_NOW);
- ASSERT_TRUE(handle != NULL);
+ ASSERT_TRUE(handle != nullptr);
foo_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo"));
foo_library_ptr = reinterpret_cast<fn_ptr>(dlsym(handle, "foo_library"));
- ASSERT_TRUE(foo_ptr != NULL);
- ASSERT_TRUE(foo_library_ptr != NULL);
+ ASSERT_TRUE(foo_ptr != nullptr);
+ ASSERT_TRUE(foo_library_ptr != nullptr);
ASSERT_EQ(strncmp("unset", foo_ptr(), 5), 0);
ASSERT_EQ(strncmp("unset", foo_library_ptr(), 3), 0);
dlclose(handle);
@@ -315,9 +315,9 @@
typedef int (*fn_t) (void);
fn_t fn, fn2;
fn = reinterpret_cast<fn_t>(dlsym(RTLD_DEFAULT, "check_order_dlsym_get_answer"));
- ASSERT_TRUE(fn != NULL) << dlerror();
+ ASSERT_TRUE(fn != nullptr) << dlerror();
fn2 = reinterpret_cast<fn_t>(dlsym(RTLD_DEFAULT, "check_order_dlsym_get_answer2"));
- ASSERT_TRUE(fn2 != NULL) << dlerror();
+ ASSERT_TRUE(fn2 != nullptr) << dlerror();
ASSERT_EQ(42, fn());
ASSERT_EQ(43, fn2());
@@ -718,7 +718,7 @@
TEST(dlfcn, dlopen_failure) {
void* self = dlopen("/does/not/exist", RTLD_NOW);
- ASSERT_TRUE(self == NULL);
+ ASSERT_TRUE(self == nullptr);
#if defined(__BIONIC__)
ASSERT_STREQ("dlopen failed: library \"/does/not/exist\" not found", dlerror());
#else
@@ -737,7 +737,7 @@
ASSERT_SUBSTR("/main/thread", main_thread_error);
pthread_t t;
- ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentDlErrorFn, NULL));
+ ASSERT_EQ(0, pthread_create(&t, nullptr, ConcurrentDlErrorFn, nullptr));
void* result;
ASSERT_EQ(0, pthread_join(t, &result));
char* child_thread_error = static_cast<char*>(result);
@@ -749,31 +749,31 @@
TEST(dlfcn, dlsym_failures) {
dlerror(); // Clear any pending errors.
- void* self = dlopen(NULL, RTLD_NOW);
- ASSERT_TRUE(self != NULL);
- ASSERT_TRUE(dlerror() == NULL);
+ void* self = dlopen(nullptr, RTLD_NOW);
+ ASSERT_TRUE(self != nullptr);
+ ASSERT_TRUE(dlerror() == nullptr);
void* sym;
#if defined(__BIONIC__) && !defined(__LP64__)
// RTLD_DEFAULT in lp32 bionic is not (void*)0
// so it can be distinguished from the NULL handle.
- sym = dlsym(NULL, "test");
- ASSERT_TRUE(sym == NULL);
+ sym = dlsym(nullptr, "test");
+ ASSERT_TRUE(sym == nullptr);
ASSERT_SUBSTR("dlsym library handle is null", dlerror());
#endif
// NULL symbol name.
#if defined(__BIONIC__)
// glibc marks this parameter non-null and SEGVs if you cheat.
- sym = dlsym(self, NULL);
- ASSERT_TRUE(sym == NULL);
+ sym = dlsym(self, nullptr);
+ ASSERT_TRUE(sym == nullptr);
ASSERT_SUBSTR("", dlerror());
#endif
// Symbol that doesn't exist.
sym = dlsym(self, "ThisSymbolDoesNotExist");
- ASSERT_TRUE(sym == NULL);
+ ASSERT_TRUE(sym == nullptr);
ASSERT_SUBSTR("undefined symbol: ThisSymbolDoesNotExist", dlerror());
ASSERT_EQ(0, dlclose(self));
@@ -781,12 +781,12 @@
TEST(dlfcn, dladdr_executable) {
dlerror(); // Clear any pending errors.
- void* self = dlopen(NULL, RTLD_NOW);
- ASSERT_TRUE(self != NULL);
- ASSERT_TRUE(dlerror() == NULL);
+ void* self = dlopen(nullptr, RTLD_NOW);
+ ASSERT_TRUE(self != nullptr);
+ ASSERT_TRUE(dlerror() == nullptr);
void* sym = dlsym(self, "DlSymTestFunction");
- ASSERT_TRUE(sym != NULL);
+ ASSERT_TRUE(sym != nullptr);
// Deliberately ask dladdr for an address inside a symbol, rather than the symbol base address.
void* addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(sym) + 2);
@@ -861,12 +861,12 @@
dlerror(); // Clear any pending errors.
// No symbol corresponding to NULL.
- ASSERT_EQ(dladdr(NULL, &info), 0); // Zero on error, non-zero on success.
- ASSERT_TRUE(dlerror() == NULL); // dladdr(3) doesn't set dlerror(3).
+ ASSERT_EQ(dladdr(nullptr, &info), 0); // Zero on error, non-zero on success.
+ ASSERT_TRUE(dlerror() == nullptr); // dladdr(3) doesn't set dlerror(3).
// No symbol corresponding to a stack address.
ASSERT_EQ(dladdr(&info, &info), 0); // Zero on error, non-zero on success.
- ASSERT_TRUE(dlerror() == NULL); // dladdr(3) doesn't set dlerror(3).
+ ASSERT_TRUE(dlerror() == nullptr); // dladdr(3) doesn't set dlerror(3).
}
// GNU-style ELF hash tables are incompatible with the MIPS ABI.
@@ -922,49 +922,49 @@
#if defined(__GLIBC__)
// glibc was smart enough not to define RTLD_NOW as 0, so it can detect missing flags.
- handle = dlopen(NULL, 0);
- ASSERT_TRUE(handle == NULL);
+ handle = dlopen(nullptr, 0);
+ ASSERT_TRUE(handle == nullptr);
ASSERT_SUBSTR("invalid", dlerror());
#endif
- handle = dlopen(NULL, 0xffffffff);
- ASSERT_TRUE(handle == NULL);
+ handle = dlopen(nullptr, 0xffffffff);
+ ASSERT_TRUE(handle == nullptr);
ASSERT_SUBSTR("invalid", dlerror());
// glibc actually allows you to choose both RTLD_NOW and RTLD_LAZY at the same time, and so do we.
- handle = dlopen(NULL, RTLD_NOW|RTLD_LAZY);
- ASSERT_TRUE(handle != NULL);
- ASSERT_SUBSTR(NULL, dlerror());
+ handle = dlopen(nullptr, RTLD_NOW|RTLD_LAZY);
+ ASSERT_TRUE(handle != nullptr);
+ ASSERT_SUBSTR(nullptr, dlerror());
}
TEST(dlfcn, rtld_default_unknown_symbol) {
void* addr = dlsym(RTLD_DEFAULT, "ANY_UNKNOWN_SYMBOL_NAME");
- ASSERT_TRUE(addr == NULL);
+ ASSERT_TRUE(addr == nullptr);
}
TEST(dlfcn, rtld_default_known_symbol) {
void* addr = dlsym(RTLD_DEFAULT, "fopen");
- ASSERT_TRUE(addr != NULL);
+ ASSERT_TRUE(addr != nullptr);
}
TEST(dlfcn, rtld_next_unknown_symbol) {
void* addr = dlsym(RTLD_NEXT, "ANY_UNKNOWN_SYMBOL_NAME");
- ASSERT_TRUE(addr == NULL);
+ ASSERT_TRUE(addr == nullptr);
}
TEST(dlfcn, rtld_next_known_symbol) {
void* addr = dlsym(RTLD_NEXT, "fopen");
- ASSERT_TRUE(addr != NULL);
+ ASSERT_TRUE(addr != nullptr);
}
TEST(dlfcn, dlsym_weak_func) {
dlerror();
void* handle = dlopen("libtest_dlsym_weak_func.so", RTLD_NOW);
- ASSERT_TRUE(handle != NULL);
+ ASSERT_TRUE(handle != nullptr);
int (*weak_func)();
weak_func = reinterpret_cast<int (*)()>(dlsym(handle, "weak_func"));
- ASSERT_TRUE(weak_func != NULL) << "dlerror: " << dlerror();
+ ASSERT_TRUE(weak_func != nullptr) << "dlerror: " << dlerror();
EXPECT_EQ(42, weak_func());
dlclose(handle);
}
@@ -982,8 +982,8 @@
TEST(dlfcn, dlopen_symlink) {
void* handle1 = dlopen("libdlext_test.so", RTLD_NOW);
void* handle2 = dlopen("libdlext_test_v2.so", RTLD_NOW);
- ASSERT_TRUE(handle1 != NULL);
- ASSERT_TRUE(handle2 != NULL);
+ ASSERT_TRUE(handle1 != nullptr);
+ ASSERT_TRUE(handle2 != nullptr);
ASSERT_EQ(handle1, handle2);
dlclose(handle1);
dlclose(handle2);