Merge "[mips] Add missing linker shdr tests"
diff --git a/libc/Android.bp b/libc/Android.bp
index c706935..5bfc930 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -7,7 +7,6 @@
"bionic/getpriority.c",
"bionic/initgroups.c",
"bionic/isatty.c",
- "bionic/memmem.c",
"bionic/pututline.c",
"bionic/sched_cpualloc.c",
"bionic/sched_cpucount.c",
@@ -40,6 +39,7 @@
"-Wextra",
"-Wunused",
"-Wno-deprecated-declarations",
+ "-Wframe-larger-than=2048",
// Try to catch typical 32-bit assumptions that break with 64-bit pointers.
"-Werror=pointer-to-int-cast",
@@ -176,6 +176,7 @@
"-DINET6",
"-Wno-unused-parameter",
"-include netbsd-compat.h",
+ "-Wframe-larger-than=66000",
],
local_include_dirs: [
@@ -204,7 +205,6 @@
"upstream-freebsd/lib/libc/stdlib/getopt_long.c",
"upstream-freebsd/lib/libc/stdlib/qsort.c",
"upstream-freebsd/lib/libc/stdlib/quick_exit.c",
- "upstream-freebsd/lib/libc/stdlib/realpath.c",
"upstream-freebsd/lib/libc/string/wcpcpy.c",
"upstream-freebsd/lib/libc/string/wcpncpy.c",
"upstream-freebsd/lib/libc/string/wcscasecmp.c",
@@ -275,6 +275,25 @@
name: "libc_freebsd",
}
+cc_library_static {
+ defaults: ["libc_defaults"],
+ srcs: [
+ "upstream-freebsd/lib/libc/stdlib/realpath.c",
+ ],
+
+ cflags: [
+ "-Wno-sign-compare",
+ "-include freebsd-compat.h",
+ "-Wframe-larger-than=15000",
+ ],
+
+ local_include_dirs: [
+ "upstream-freebsd/android/include",
+ ],
+
+ name: "libc_freebsd_large_stack",
+}
+
// ========================================================
// libc_netbsd.a - upstream NetBSD C library code
// ========================================================
@@ -359,7 +378,6 @@
"upstream-openbsd/lib/libc/gen/daemon.c",
"upstream-openbsd/lib/libc/gen/err.c",
"upstream-openbsd/lib/libc/gen/errx.c",
- "upstream-openbsd/lib/libc/gen/exec.c",
"upstream-openbsd/lib/libc/gen/fnmatch.c",
"upstream-openbsd/lib/libc/gen/ftok.c",
"upstream-openbsd/lib/libc/gen/getprogname.c",
@@ -435,10 +453,7 @@
"upstream-openbsd/lib/libc/stdio/ungetwc.c",
"upstream-openbsd/lib/libc/stdio/vasprintf.c",
"upstream-openbsd/lib/libc/stdio/vdprintf.c",
- "upstream-openbsd/lib/libc/stdio/vfprintf.c",
"upstream-openbsd/lib/libc/stdio/vfscanf.c",
- "upstream-openbsd/lib/libc/stdio/vfwprintf.c",
- "upstream-openbsd/lib/libc/stdio/vfwscanf.c",
"upstream-openbsd/lib/libc/stdio/vsscanf.c",
"upstream-openbsd/lib/libc/stdio/vswprintf.c",
"upstream-openbsd/lib/libc/stdio/vswscanf.c",
@@ -499,6 +514,29 @@
],
}
+cc_library_static {
+ name: "libc_openbsd_large_stack",
+ defaults: ["libc_defaults"],
+ srcs: [
+ "upstream-openbsd/lib/libc/gen/exec.c",
+ "upstream-openbsd/lib/libc/stdio/vfprintf.c",
+ "upstream-openbsd/lib/libc/stdio/vfwprintf.c",
+ "upstream-openbsd/lib/libc/stdio/vfwscanf.c",
+ ],
+ cflags: [
+ "-include openbsd-compat.h",
+ "-Wno-sign-compare",
+ "-Wframe-larger-than=5000",
+ ],
+
+ local_include_dirs: [
+ "stdio",
+ "upstream-openbsd/android/include",
+ "upstream-openbsd/lib/libc/include",
+ "upstream-openbsd/lib/libc/gdtoa/",
+ ],
+}
+
// ========================================================
// libc_openbsd.a - upstream OpenBSD C library code
// ========================================================
@@ -645,10 +683,7 @@
local_include_dirs: [
"private",
- "stdio",
"upstream-openbsd/android/include",
- "upstream-openbsd/lib/libc/include",
- "upstream-openbsd/lib/libc/gdtoa/",
],
name: "libc_openbsd",
@@ -736,7 +771,6 @@
"bionic/strnlen.c",
"bionic/strrchr.cpp",
],
- cflags: ["-Wframe-larger-than=2048"],
arch: {
arm: {
@@ -1245,6 +1279,7 @@
"bionic/mbrtoc16.cpp",
"bionic/mbrtoc32.cpp",
"bionic/mbstate.cpp",
+ "bionic/memmem.cpp",
"bionic/mempcpy.cpp",
"bionic/mkdir.cpp",
"bionic/mkfifo.cpp",
@@ -1330,7 +1365,6 @@
"bionic/wctype.cpp",
"bionic/wmempcpy.cpp",
],
- cflags: ["-Wframe-larger-than=2048"],
multilib: {
lib32: {
@@ -1380,7 +1414,6 @@
"bionic/pthread_sigmask.cpp",
"bionic/pthread_spinlock.cpp",
],
- cflags: ["-Wframe-larger-than=2048"],
cppflags: ["-Wold-style-cast"],
include_dirs: ["bionic/libstdc++/include"],
@@ -1475,9 +1508,11 @@
whole_static_libs: [
"libc_bionic_ndk",
"libc_freebsd",
+ "libc_freebsd_large_stack",
"libc_gdtoa",
"libc_malloc",
"libc_netbsd",
+ "libc_openbsd_large_stack",
"libc_openbsd_ndk",
"libc_stack_protector",
"libc_syscalls",
@@ -1507,10 +1542,12 @@
"libc_bionic_ndk",
"libc_dns",
"libc_freebsd",
+ "libc_freebsd_large_stack",
"libc_gdtoa",
"libc_malloc",
"libc_netbsd",
"libc_openbsd",
+ "libc_openbsd_large_stack",
"libc_openbsd_ndk",
"libc_pthread",
"libc_stack_protector",
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 5188b6d..42c8f01 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -239,7 +239,7 @@
# sockets
int __socket:socket(int, int, int) arm,arm64,mips,mips64,x86_64
int socketpair(int, int, int, int*) arm,arm64,mips,mips64,x86_64
-int bind(int, struct sockaddr*, int) arm,arm64,mips,mips64,x86_64
+int bind(int, struct sockaddr*, socklen_t) arm,arm64,mips,mips64,x86_64
int __connect:connect(int, struct sockaddr*, socklen_t) arm,arm64,mips,mips64,x86_64
int listen(int, int) arm,arm64,mips,mips64,x86_64
int __accept4:accept4(int, struct sockaddr*, socklen_t*, int) arm,arm64,mips,mips64,x86_64
@@ -250,8 +250,8 @@
int shutdown(int, int) arm,arm64,mips,mips64,x86_64
int setsockopt(int, int, int, const void*, socklen_t) arm,arm64,mips,mips64,x86_64
int getsockopt(int, int, int, void*, socklen_t*) arm,arm64,mips,mips64,x86_64
-int sendmsg(int, const struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64
-int recvmsg(int, struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64
+ssize_t recvmsg(int, struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64
+ssize_t sendmsg(int, const struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64
int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*) arm,arm64,mips,mips64,x86_64
int sendmmsg(int, struct mmsghdr*, unsigned int, int) arm,arm64,mips,mips64,x86_64
diff --git a/libc/bionic/memmem.c b/libc/bionic/memmem.c
deleted file mode 100644
index e72501b..0000000
--- a/libc/bionic/memmem.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT OWNER 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.
- */
-/*
- * This uses the "Not So Naive" algorithm, a very simple but
- * usually effective algorithm, see:
- * http://www-igm.univ-mlv.fr/~lecroq/string/
- */
-#include <string.h>
-
-void *memmem(const void *haystack, size_t n, const void *needle, size_t m)
-{
- if (m > n || !m || !n)
- return NULL;
-
- if (__builtin_expect((m > 1), 1)) {
- const unsigned char* y = (const unsigned char*) haystack;
- const unsigned char* x = (const unsigned char*) needle;
- size_t j = 0;
- size_t k = 1, l = 2;
-
- if (x[0] == x[1]) {
- k = 2;
- l = 1;
- }
- while (j <= n-m) {
- if (x[1] != y[j+1]) {
- j += k;
- } else {
- if (!memcmp(x+2, y+j+2, m-2) && x[0] == y[j])
- return (void*) &y[j];
- j += l;
- }
- }
- } else {
- /* degenerate case */
- return memchr(haystack, ((unsigned char*)needle)[0], n);
- }
- return NULL;
-}
diff --git a/libc/bionic/memmem.cpp b/libc/bionic/memmem.cpp
new file mode 100644
index 0000000..61d681f
--- /dev/null
+++ b/libc/bionic/memmem.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT OWNER 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.
+ */
+
+#include <string.h>
+
+void* memmem(const void* void_haystack, size_t n, const void* void_needle, size_t m) {
+ const unsigned char* haystack = reinterpret_cast<const unsigned char*>(void_haystack);
+ const unsigned char* needle = reinterpret_cast<const unsigned char*>(void_needle);
+
+ if (n < m) return nullptr;
+
+ if (m == 0) return const_cast<void*>(void_haystack);
+ if (m == 1) return memchr(haystack, needle[0], n);
+
+ // This uses the "Not So Naive" algorithm, a very simple but usually effective algorithm.
+ // http://www-igm.univ-mlv.fr/~lecroq/string/
+ const unsigned char* y = haystack;
+ const unsigned char* x = needle;
+ size_t j = 0;
+ size_t k = 1, l = 2;
+
+ if (x[0] == x[1]) {
+ k = 2;
+ l = 1;
+ }
+ while (j <= n-m) {
+ if (x[1] != y[j+1]) {
+ j += k;
+ } else {
+ if (!memcmp(x+2, y+j+2, m-2) && x[0] == y[j]) return const_cast<unsigned char*>(&y[j]);
+ j += l;
+ }
+ }
+ return nullptr;
+}
diff --git a/libc/include/netdb.h b/libc/include/netdb.h
index 95f0986..816acc5 100644
--- a/libc/include/netdb.h
+++ b/libc/include/netdb.h
@@ -220,10 +220,11 @@
void herror(const char*);
const char* hstrerror(int);
-int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **);
-int getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int);
-void freeaddrinfo(struct addrinfo *);
-const char *gai_strerror(int);
+int getaddrinfo(const char*, const char*, const struct addrinfo*, struct addrinfo**);
+/* POSIX getnameinfo uses socklen_t, not size_t, but LP64 sizeof(socklen_t) != sizeof(size_t). */
+int getnameinfo(const struct sockaddr*, socklen_t, char*, size_t, char*, size_t, int);
+void freeaddrinfo(struct addrinfo*);
+const char* gai_strerror(int);
void setservent(int);
__END_DECLS
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 934963f..79f1faf 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -57,8 +57,8 @@
void* mmap64(void*, size_t, int, int, int, off64_t) __INTRODUCED_IN(21);
int munmap(void*, size_t);
-int msync(const void*, size_t, int);
-int mprotect(const void*, size_t, int);
+int msync(void*, size_t, int);
+int mprotect(void*, size_t, int);
void* mremap(void*, size_t, size_t, int, ...);
int mlockall(int) __INTRODUCED_IN(17);
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 6a275e4..910fee1 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -271,7 +271,7 @@
__socketcall int accept(int, struct sockaddr*, socklen_t*);
__socketcall int accept4(int, struct sockaddr*, socklen_t*, int) __INTRODUCED_IN(21);
-__socketcall int bind(int, const struct sockaddr*, int);
+__socketcall int bind(int, const struct sockaddr*, socklen_t);
__socketcall int connect(int, const struct sockaddr*, socklen_t);
__socketcall int getpeername(int, struct sockaddr*, socklen_t*);
__socketcall int getsockname(int, struct sockaddr*, socklen_t*);
@@ -279,16 +279,16 @@
__socketcall int listen(int, int);
__socketcall int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*)
__INTRODUCED_IN(21);
-__socketcall int recvmsg(int, struct msghdr*, int);
+__socketcall ssize_t recvmsg(int, struct msghdr*, int);
__socketcall int sendmmsg(int, const struct mmsghdr*, unsigned int, int) __INTRODUCED_IN(21);
-__socketcall int sendmsg(int, const struct msghdr*, int);
+__socketcall ssize_t sendmsg(int, const struct msghdr*, int);
__socketcall int setsockopt(int, int, int, const void*, socklen_t);
__socketcall int shutdown(int, int);
__socketcall int socket(int, int, int);
__socketcall int socketpair(int, int, int, int*);
-ssize_t send(int, const void*, size_t, int);
ssize_t recv(int, void*, size_t, int);
+ssize_t send(int, const void*, size_t, int);
__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t);
__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*, socklen_t*);
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 775fb08..cc9dd91 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -141,6 +141,12 @@
#define S_IEXEC S_IXUSR
#endif
+/* POSIX mandates these, but Linux doesn't implement them as distinct file types. */
+#define S_TYPEISMQ(__sb) 0
+#define S_TYPEISSEM(__sb) 0
+#define S_TYPEISSHM(__sb) 0
+#define S_TYPEISTMO(__sb) 0
+
int chmod(const char*, mode_t);
int fchmod(int, mode_t);
int mkdir(const char*, mode_t);
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 763d65c..385fe33 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -1455,3 +1455,32 @@
}
RunSingleBufferAlignTest(MEDIUM, DoMemcpySameTest);
}
+
+TEST(STRING_TEST, memmem_strstr_empty_needle) {
+ const char* some_haystack = "haystack";
+ const char* empty_haystack = "";
+
+ ASSERT_EQ(some_haystack, memmem(some_haystack, 8, "", 0));
+ ASSERT_EQ(empty_haystack, memmem(empty_haystack, 0, "", 0));
+
+ ASSERT_EQ(some_haystack, strstr(some_haystack, ""));
+ ASSERT_EQ(empty_haystack, strstr(empty_haystack, ""));
+}
+
+TEST(STRING_TEST, memmem_smoke) {
+ const char haystack[] = "big\0daddy\0giant\0haystacks";
+ ASSERT_EQ(haystack, memmem(haystack, sizeof(haystack), "", 0));
+ ASSERT_EQ(haystack + 3, memmem(haystack, sizeof(haystack), "", 1));
+ ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "b", 1));
+ ASSERT_EQ(haystack + 1, memmem(haystack, sizeof(haystack), "i", 1));
+ ASSERT_EQ(haystack + 4, memmem(haystack, sizeof(haystack), "da", 2));
+ ASSERT_EQ(haystack + 8, memmem(haystack, sizeof(haystack), "y\0g", 3));
+}
+
+TEST(STRING_TEST, strstr_smoke) {
+ const char* haystack = "big daddy/giant haystacks";
+ ASSERT_EQ(haystack, strstr(haystack, ""));
+ ASSERT_EQ(haystack + 0, strstr(haystack, "b"));
+ ASSERT_EQ(haystack + 1, strstr(haystack, "i"));
+ ASSERT_EQ(haystack + 4, strstr(haystack, "da"));
+}