Merge "Add support of architecture specific ld.configs"
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 2ab7264..0e7f668 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -19,14 +19,25 @@
#include <stdio_ext.h>
#include <stdlib.h>
+#include <android-base/test_utils.h>
#include <benchmark/benchmark.h>
#include "util.h"
+static void FillFile(TemporaryFile& tf) {
+ char line[256];
+ memset(line, 'x', sizeof(line));
+ line[sizeof(line) - 1] = '\0';
+
+ FILE* fp = fopen(tf.path, "w");
+ for (size_t i = 0; i < 4096; ++i) fputs(line, fp);
+ fclose(fp);
+}
+
template <typename Fn>
void ReadWriteTest(benchmark::State& state, Fn f, bool buffered) {
size_t chunk_size = state.range(0);
- FILE* fp = fopen("/dev/zero", "rw");
+ FILE* fp = fopen("/dev/zero", "r+e");
__fsetlocking(fp, FSETLOCKING_BYCALLER);
char* buf = new char[chunk_size];
@@ -35,7 +46,9 @@
}
while (state.KeepRunning()) {
- f(buf, chunk_size, 1, fp);
+ if (f(buf, chunk_size, 1, fp) != 1) {
+ errx(1, "ERROR: op of %zu bytes failed.", chunk_size);
+ }
}
state.SetBytesProcessed(int64_t(state.iterations()) * int64_t(chunk_size));
@@ -63,14 +76,39 @@
}
BIONIC_BENCHMARK(BM_stdio_fwrite_unbuffered);
-static void FopenFgetsFclose(benchmark::State& state, bool no_locking) {
- size_t nbytes = state.range(0);
- char buf[nbytes];
+#if !defined(__GLIBC__)
+static void FopenFgetlnFclose(benchmark::State& state, bool no_locking) {
+ TemporaryFile tf;
+ FillFile(tf);
while (state.KeepRunning()) {
- FILE* fp = fopen("/dev/zero", "re");
+ FILE* fp = fopen(tf.path, "re");
if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
- if (fgets(buf, sizeof(buf), fp) == nullptr) {
- errx(1, "ERROR: fgets of %zu bytes failed.", nbytes);
+ size_t length;
+ while (fgetln(fp, &length) != nullptr) {
+ }
+ fclose(fp);
+ }
+}
+
+static void BM_stdio_fopen_fgetln_fclose_locking(benchmark::State& state) {
+ FopenFgetlnFclose(state, false);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetln_fclose_locking);
+
+void BM_stdio_fopen_fgetln_fclose_no_locking(benchmark::State& state) {
+ FopenFgetlnFclose(state, true);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetln_fclose_no_locking);
+#endif
+
+static void FopenFgetsFclose(benchmark::State& state, bool no_locking) {
+ TemporaryFile tf;
+ FillFile(tf);
+ char buf[BUFSIZ];
+ while (state.KeepRunning()) {
+ FILE* fp = fopen(tf.path, "re");
+ if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ while (fgets(buf, sizeof(buf), fp) != nullptr) {
}
fclose(fp);
}
@@ -86,6 +124,31 @@
}
BIONIC_BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
+static void FopenGetlineFclose(benchmark::State& state, bool no_locking) {
+ TemporaryFile tf;
+ FillFile(tf);
+ while (state.KeepRunning()) {
+ FILE* fp = fopen(tf.path, "re");
+ if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ char* line = nullptr;
+ size_t n = 0;
+ while (getline(&line, &n, fp) != -1) {
+ }
+ free(line);
+ fclose(fp);
+ }
+}
+
+static void BM_stdio_fopen_getline_fclose_locking(benchmark::State& state) {
+ FopenGetlineFclose(state, false);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_getline_fclose_locking);
+
+void BM_stdio_fopen_getline_fclose_no_locking(benchmark::State& state) {
+ FopenGetlineFclose(state, true);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_getline_fclose_no_locking);
+
static void FopenFgetcFclose(benchmark::State& state, bool no_locking) {
size_t nbytes = state.range(0);
while (state.KeepRunning()) {
@@ -108,4 +171,3 @@
FopenFgetcFclose(state, true);
}
BIONIC_BENCHMARK(BM_stdio_fopen_fgetc_fclose_no_locking);
-
diff --git a/benchmarks/suites/full.xml b/benchmarks/suites/full.xml
index 8c9aef6..fc58914 100644
--- a/benchmarks/suites/full.xml
+++ b/benchmarks/suites/full.xml
@@ -179,12 +179,16 @@
<args>AT_COMMON_SIZES</args>
</fn>
<fn>
+ <name>BM_stdio_fopen_fgetln_fclose_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetln_fclose_no_locking</name>
+</fn>
+<fn>
<name>BM_stdio_fopen_fgets_fclose_locking</name>
- <args>1024</args>
</fn>
<fn>
<name>BM_stdio_fopen_fgets_fclose_no_locking</name>
- <args>1024</args>
</fn>
<fn>
<name>BM_stdio_fopen_fgetc_fclose_locking</name>
@@ -195,6 +199,12 @@
<args>1024</args>
</fn>
<fn>
+ <name>BM_stdio_fopen_getline_fclose_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_getline_fclose_no_locking</name>
+</fn>
+<fn>
<name>BM_string_memcmp</name>
<args>AT_ALIGNED_TWOBUF</args>
</fn>
diff --git a/libc/bionic/assert.cpp b/libc/bionic/assert.cpp
index 41831cb..0f4ee97 100644
--- a/libc/bionic/assert.cpp
+++ b/libc/bionic/assert.cpp
@@ -39,7 +39,3 @@
void __assert2(const char* file, int line, const char* function, const char* failed_expression) {
async_safe_fatal("%s:%d: %s: assertion \"%s\" failed", file, line, function, failed_expression);
}
-
-extern "C" __LIBC_HIDDEN__ void longjmperror() {
- async_safe_fatal("longjmp botch");
-}
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index cbcc976..4b7b776 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -147,7 +147,7 @@
void* __memrchr_chk(const void* s, int c, size_t n, size_t actual_size) {
__check_buffer_access("memrchr", "read from", n, actual_size);
- return memrchr(s, c, n);
+ return memrchr(const_cast<void *>(s), c, n);
}
// memset is performance-critical enough that we have assembler __memset_chk implementations.
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index 667e21d..f994e3e 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -38,6 +38,8 @@
size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
#if defined(__BIONIC_FORTIFY)
+extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+
// These can share their implementation between gcc and clang with minimal
// trickery...
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
@@ -116,11 +118,11 @@
}
__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
+void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
size_t bos = __bos(s);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(memrchr)(s, c, n);
+ return __memrchr_real(s, c, n);
}
return __memrchr_chk(s, c, n, bos);
@@ -231,7 +233,6 @@
#else // defined(__clang__)
extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
-extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
extern size_t __strlcpy_real(char*, const char*, size_t)
__RENAME(strlcpy);
extern size_t __strlcat_real(char*, const char*, size_t)
@@ -261,7 +262,7 @@
}
__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* s, int c, size_t n) {
+void* __memrchr_fortify(const void* s, int c, size_t n) {
size_t bos = __bos(s);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
@@ -415,4 +416,26 @@
}
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
#endif /* defined(__clang__) */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+#if defined(__cplusplus)
+extern "C++" {
+__BIONIC_FORTIFY_INLINE
+void* memrchr(void* const __pass_object_size s, int c, size_t n) {
+ return __memrchr_fortify(s, c, n);
+}
+
+__BIONIC_FORTIFY_INLINE
+const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
+ return __memrchr_fortify(s, c, n);
+}
+}
+#else
+__BIONIC_FORTIFY_INLINE
+void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
+ return __memrchr_fortify(s, c, n);
+}
+#endif
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/string.h b/libc/include/string.h
index 33ef468..d409ba8 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -43,7 +43,12 @@
void* memccpy(void* __dst, const void* __src, int __stop_char, size_t __n);
void* memchr(const void* __s, int __ch, size_t __n) __attribute_pure__ __overloadable __RENAME_CLANG(memchr);
+#if defined(__cplusplus)
+extern "C++" void* memrchr(void* __s, int __ch, size_t __n) __RENAME(memrchr) __attribute_pure__;
+extern "C++" const void* memrchr(const void* __s, int __ch, size_t __n) __RENAME(memrchr) __attribute_pure__;
+#else
void* memrchr(const void* __s, int __ch, size_t __n) __attribute_pure__ __overloadable __RENAME_CLANG(memrchr);
+#endif
int memcmp(const void* __lhs, const void* __rhs, size_t __n) __attribute_pure__;
void* memcpy(void*, const void*, size_t)
__overloadable __RENAME_CLANG(memcpy);
@@ -81,7 +86,12 @@
char* strdup(const char* __s);
char* strstr(const char* __haystack, const char* __needle) __attribute_pure__;
+#if defined(__cplusplus)
+extern "C++" char* strcasestr(char*, const char*) __RENAME(strcasestr) __attribute_pure__;
+extern "C++" const char* strcasestr(const char*, const char*) __RENAME(strcasestr) __attribute_pure__;
+#else
char* strcasestr(const char* __haystack, const char* __needle) __attribute_pure__;
+#endif
char* strtok(char* __s, const char* __delimiter);
char* strtok_r(char* __s, const char* __delimiter, char** __pos_ptr);