Merge "Always return /vendor/bin/sh as shell for OEM ids in getpwnam() etc."
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index 842f7cb..bf8b10d 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -40,11 +40,13 @@
"time_benchmark.cpp",
"unistd_benchmark.cpp",
],
- shared_libs: ["libtinyxml2"],
+ shared_libs: ["liblog"],
static_libs: [
"libbase",
"libBionicBenchmarksUtils",
+ "libtinyxml2",
],
+ stl: "libc++_static",
}
cc_defaults {
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
index 880bc1d..7330dc4 100644
--- a/benchmarks/stdlib_benchmark.cpp
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -18,17 +18,24 @@
#include <langinfo.h>
#include <locale.h>
#include <stdlib.h>
+#include <unistd.h>
#include <benchmark/benchmark.h>
#include "util.h"
static void BM_stdlib_malloc_free(benchmark::State& state) {
const size_t nbytes = state.range(0);
+ int pagesize = getpagesize();
- void* c;
- while (state.KeepRunning()) {
- c = malloc(nbytes);
- free(c);
+ void* ptr;
+ for (auto _ : state) {
+ ptr = malloc(nbytes);
+ // Make the entire allocation resident.
+ uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
+ for (size_t i = 0; i < nbytes; i += pagesize) {
+ data[i] = 1;
+ }
+ free(ptr);
}
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
@@ -70,7 +77,7 @@
buf[l++] = 0;
volatile size_t c __attribute__((unused)) = 0;
- while (state.KeepRunning()) {
+ for (auto _ : state) {
c = mbstowcs(widebuf_aligned, buf_aligned, 500000);
}
@@ -110,7 +117,7 @@
buf[l++] = 0;
wchar_t wc = 0;
- while (state.KeepRunning()) {
+ for (auto _ : state) {
for (j = 0; buf_aligned[j]; j+=mbrtowc(&wc, buf_aligned + j, 4, nullptr)) {
}
}
@@ -120,42 +127,42 @@
BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc, "0");
void BM_stdlib_atoi(benchmark::State& state) {
- while (state.KeepRunning()) {
+ for (auto _ : state) {
benchmark::DoNotOptimize(atoi(" -123"));
}
}
BIONIC_BENCHMARK(BM_stdlib_atoi);
void BM_stdlib_atol(benchmark::State& state) {
- while (state.KeepRunning()) {
+ for (auto _ : state) {
benchmark::DoNotOptimize(atol(" -123"));
}
}
BIONIC_BENCHMARK(BM_stdlib_atol);
void BM_stdlib_strtol(benchmark::State& state) {
- while (state.KeepRunning()) {
+ for (auto _ : state) {
benchmark::DoNotOptimize(strtol(" -123", nullptr, 0));
}
}
BIONIC_BENCHMARK(BM_stdlib_strtol);
void BM_stdlib_strtoll(benchmark::State& state) {
- while (state.KeepRunning()) {
+ for (auto _ : state) {
benchmark::DoNotOptimize(strtoll(" -123", nullptr, 0));
}
}
BIONIC_BENCHMARK(BM_stdlib_strtoll);
void BM_stdlib_strtoul(benchmark::State& state) {
- while (state.KeepRunning()) {
+ for (auto _ : state) {
benchmark::DoNotOptimize(strtoul(" -123", nullptr, 0));
}
}
BIONIC_BENCHMARK(BM_stdlib_strtoul);
void BM_stdlib_strtoull(benchmark::State& state) {
- while (state.KeepRunning()) {
+ for (auto _ : state) {
benchmark::DoNotOptimize(strtoull(" -123", nullptr, 0));
}
}
diff --git a/docs/status.md b/docs/status.md
index b6439a0..0106ccd 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -39,6 +39,7 @@
New libc functions in Q (API level 29):
* `timespec_get` (C11 `<time.h>` addition)
+ * `reallocarray` (BSD/GNU extension in `<malloc.h>` and `<stdlib.h>`)
* `res_randomid` (in `<resolv.h>`)
* `pthread_sigqueue` (GNU extension)
diff --git a/libc/Android.bp b/libc/Android.bp
index 57173d1..cc0a2bb 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -479,7 +479,6 @@
"upstream-openbsd/lib/libc/stdlib/labs.c",
"upstream-openbsd/lib/libc/stdlib/llabs.c",
"upstream-openbsd/lib/libc/stdlib/lsearch.c",
- "upstream-openbsd/lib/libc/stdlib/reallocarray.c",
"upstream-openbsd/lib/libc/stdlib/remque.c",
"upstream-openbsd/lib/libc/stdlib/setenv.c",
"upstream-openbsd/lib/libc/stdlib/tfind.c",
@@ -1858,6 +1857,7 @@
cflags: ["-fPIC"],
},
},
+ stl: "none",
}
// crt obj files
diff --git a/libc/NOTICE b/libc/NOTICE
index 486c615..5cce4d4 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -4738,22 +4738,6 @@
-------------------------------------------------------------------
-Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
Permission to use, copy, modify, and distribute this software for any
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 5a5ec76..8bf44a1 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -184,6 +184,15 @@
return Malloc(realloc)(old_mem, bytes);
}
+extern "C" void* reallocarray(void* old_mem, size_t item_count, size_t item_size) {
+ size_t new_size;
+ if (__builtin_mul_overflow(item_count, item_size, &new_size)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+ return realloc(old_mem, new_size);
+}
+
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
extern "C" void* pvalloc(size_t bytes) {
auto _pvalloc = __libc_globals->malloc_dispatch.pvalloc;
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index 7144224..f5fbedf 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -66,6 +66,18 @@
void* realloc(void* __ptr, size_t __byte_count) __BIONIC_ALLOC_SIZE(2) __wur;
/**
+ * [reallocarray(3)](http://man7.org/linux/man-pages/man3/realloc.3.html) resizes
+ * allocated memory on the heap.
+ *
+ * Equivalent to `realloc(__ptr, __item_count * __item_size)` but fails if the
+ * multiplication overflows.
+ *
+ * Returns a pointer (which may be different from `__ptr`) to the resized
+ * memory on success and returns a null pointer and sets `errno` on failure.
+ */
+void* reallocarray(void* __ptr, size_t __item_count, size_t __item_size) __BIONIC_ALLOC_SIZE(2, 3) __wur __INTRODUCED_IN(29);
+
+/**
* [free(3)](http://man7.org/linux/man-pages/man3/free.3.html) deallocates
* memory on the heap.
*/
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 2891925..a22a8df 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1433,6 +1433,7 @@
android_fdsan_set_error_level;
android_get_device_api_level;
pthread_sigqueue;
+ reallocarray;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 3e8cea2..55fd587 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1354,6 +1354,7 @@
android_fdsan_set_error_level;
android_get_device_api_level;
pthread_sigqueue;
+ reallocarray;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 2770f21..304dbb7 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1458,6 +1458,7 @@
android_fdsan_set_error_level;
android_get_device_api_level;
pthread_sigqueue;
+ reallocarray;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 456e35c..397ff72 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1417,6 +1417,7 @@
android_fdsan_set_error_level;
android_get_device_api_level;
pthread_sigqueue;
+ reallocarray;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 3e8cea2..55fd587 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1354,6 +1354,7 @@
android_fdsan_set_error_level;
android_get_device_api_level;
pthread_sigqueue;
+ reallocarray;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 4cbef13..a18657c 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1415,6 +1415,7 @@
android_fdsan_set_error_level;
android_get_device_api_level;
pthread_sigqueue;
+ reallocarray;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 3e8cea2..55fd587 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1354,6 +1354,7 @@
android_fdsan_set_error_level;
android_get_device_api_level;
pthread_sigqueue;
+ reallocarray;
timespec_get;
} LIBC_P;
diff --git a/libc/upstream-freebsd/android/include/freebsd-compat.h b/libc/upstream-freebsd/android/include/freebsd-compat.h
index e646e23..6f7a3f0 100644
--- a/libc/upstream-freebsd/android/include/freebsd-compat.h
+++ b/libc/upstream-freebsd/android/include/freebsd-compat.h
@@ -44,9 +44,6 @@
/* Redirect internal C library calls to the public function. */
#define _nanosleep nanosleep
-/* FreeBSD has this as API, but we just use it internally. */
-void* reallocarray(void*, size_t, size_t);
-
/* FreeBSD has this, but we can't really implement it correctly on Linux. */
#define issetugid() 0
diff --git a/libc/upstream-netbsd/android/include/reentrant.h b/libc/upstream-netbsd/android/include/reentrant.h
index 3ca8fd6..e27a87b 100644
--- a/libc/upstream-netbsd/android/include/reentrant.h
+++ b/libc/upstream-netbsd/android/include/reentrant.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef _BIONIC_NETBSD_REENTRANT_H_included
-#define _BIONIC_NETBSD_REENTRANT_H_included
+#pragma once
#define _REENTRANT
@@ -23,18 +22,10 @@
#include <signal.h>
//
-// Map NetBSD libc internal locking to pthread locking.
+// Map NetBSD libc internal locking onto regular pthread locking.
//
#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define mutex_t pthread_mutex_t
#define mutex_lock(x) pthread_mutex_lock(x)
#define mutex_unlock(x) pthread_mutex_unlock(x)
-
-#define RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
-#define rwlock_t pthread_rwlock_t
-#define rwlock_rdlock pthread_rwlock_rdlock
-#define rwlock_unlock pthread_rwlock_unlock
-#define rwlock_wrlock pthread_rwlock_wrlock
-
-#endif
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index f178149..c99e2ce 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -80,9 +80,6 @@
__LIBC_HIDDEN__ extern const char* __bionic_get_shell_path();
#define _PATH_BSHELL __bionic_get_shell_path()
-/* OpenBSD has this as API, but we just use it internally. */
-__LIBC_HIDDEN__ void* reallocarray(void*, size_t, size_t);
-
/* LP32 NDK ctype.h contained references to these. */
__LIBC32_LEGACY_PUBLIC__ extern const short* _tolower_tab_;
__LIBC32_LEGACY_PUBLIC__ extern const short* _toupper_tab_;
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c b/libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c
deleted file mode 100644
index baea252..0000000
--- a/libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $ */
-/*
- * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-/*
- * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
- * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
- */
-#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
-
-void *
-reallocarray(void *optr, size_t nmemb, size_t size)
-{
- if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
- nmemb > 0 && SIZE_MAX / nmemb < size) {
- errno = ENOMEM;
- return NULL;
- }
- return realloc(optr, size * nmemb);
-}
-DEF_WEAK(reallocarray);
diff --git a/libm/Android.bp b/libm/Android.bp
index 3b88fa3..6d55967 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -290,13 +290,9 @@
arm64: {
srcs: [
- "arm64/ceil.S",
"arm64/fenv.c",
- "arm64/floor.S",
"arm64/lrint.S",
- "arm64/rint.S",
"arm64/sqrt.S",
- "arm64/trunc.S",
],
exclude_srcs: [
"upstream-freebsd/lib/msun/src/e_sqrt.c",
diff --git a/libm/arm64/ceil.S b/libm/arm64/ceil.S
deleted file mode 100644
index 7217d57..0000000
--- a/libm/arm64/ceil.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY(ceil)
- frintP d0, d0
- ret
-END(ceil)
-
-ENTRY(ceilf)
- frintP s0, s0
- ret
-END(ceilf)
diff --git a/libm/arm64/floor.S b/libm/arm64/floor.S
deleted file mode 100644
index ca106bd..0000000
--- a/libm/arm64/floor.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY(floor)
- frintM d0, d0
- ret
-END(floor)
-
-ENTRY(floorf)
- frintM s0, s0
- ret
-END(floorf)
diff --git a/libm/arm64/rint.S b/libm/arm64/rint.S
deleted file mode 100644
index bf49f5b..0000000
--- a/libm/arm64/rint.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY(rint)
- frintX d0, d0
- ret
-END(rint)
-
-ENTRY(rintf)
- frintX s0, s0
- ret
-END(rintf)
diff --git a/libm/arm64/trunc.S b/libm/arm64/trunc.S
deleted file mode 100644
index aa0d4bd..0000000
--- a/libm/arm64/trunc.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY(trunc)
- frintZ d0, d0
- ret
-END(trunc)
-
-ENTRY(truncf)
- frintZ s0, s0
- ret
-END(truncf)
diff --git a/libm/builtins.cpp b/libm/builtins.cpp
index 2ea6305..3b9228c 100644
--- a/libm/builtins.cpp
+++ b/libm/builtins.cpp
@@ -46,6 +46,12 @@
#endif
#if defined(__aarch64__)
+float ceilf(float x) { return __builtin_ceilf(x); }
+double ceil(double x) { return __builtin_ceil(x); }
+
+float floorf(float x) { return __builtin_floorf(x); }
+double floor(double x) { return __builtin_floor(x); }
+
float fmaf(float x, float y, float z) { return __builtin_fmaf(x, y, z); }
double fma(double x, double y, double z) { return __builtin_fma(x, y, z); }
@@ -55,6 +61,12 @@
float fminf(float x, float y) { return __builtin_fminf(x, y); }
double fmin(double x, double y) { return __builtin_fmin(x, y); }
+float rintf(float x) { return __builtin_rintf(x); }
+double rint(double x) { return __builtin_rint(x); }
+
float roundf(float x) { return __builtin_roundf(x); }
double round(double x) { return __builtin_round(x); }
+
+float truncf(float x) { return __builtin_truncf(x); }
+double trunc(double x) { return __builtin_trunc(x); }
#endif
diff --git a/linker/Android.bp b/linker/Android.bp
index b809f76..1e14ee3 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -66,8 +66,8 @@
include_dirs: ["bionic/libc"],
}
-cc_binary {
- defaults: ["linux_bionic_supported"],
+filegroup {
+ name: "linker_sources",
srcs: [
"dlfcn.cpp",
"linker.cpp",
@@ -89,49 +89,74 @@
"linker_utils.cpp",
"rt.cpp",
],
+}
+filegroup {
+ name: "linker_sources_arm",
+ srcs: [
+ "arch/arm/begin.S",
+ "linker_exidx_static.c",
+ ],
+}
+
+filegroup {
+ name: "linker_sources_arm64",
+ srcs: [
+ "arch/arm64/begin.S",
+ ],
+}
+
+filegroup {
+ name: "linker_sources_x86",
+ srcs: [
+ "arch/x86/begin.S",
+ ],
+}
+
+filegroup {
+ name: "linker_sources_x86_64",
+ srcs: [
+ "arch/x86_64/begin.S",
+ ],
+}
+
+filegroup {
+ name: "linker_sources_mips",
+ srcs: [
+ "arch/mips/begin.S",
+ "linker_mips.cpp",
+ ],
+}
+
+filegroup {
+ name: "linker_sources_mips64",
+ srcs: [
+ "arch/mips64/begin.S",
+ "linker_mips.cpp",
+ ],
+}
+
+filegroup {
+ name: "linker_version_script",
+ srcs: ["linker.generic.map"],
+}
+
+filegroup {
+ name: "linker_version_script_arm",
+ srcs: ["linker.arm.map"],
+}
+
+cc_defaults {
+ name: "linker_defaults",
arch: {
arm: {
- srcs: [
- "arch/arm/begin.S",
- "linker_exidx_static.c",
- ],
-
cflags: ["-D__work_around_b_24465209__"],
- version_script: "linker.arm.map",
- },
- arm64: {
- srcs: ["arch/arm64/begin.S"],
- version_script: "linker.generic.map",
},
x86: {
- srcs: ["arch/x86/begin.S"],
cflags: ["-D__work_around_b_24465209__"],
- version_script: "linker.generic.map",
- },
- x86_64: {
- srcs: ["arch/x86_64/begin.S"],
- version_script: "linker.generic.map",
- },
- mips: {
- srcs: [
- "arch/mips/begin.S",
- "linker_mips.cpp",
- ],
- version_script: "linker.generic.map",
- },
- mips64: {
- srcs: [
- "arch/mips64/begin.S",
- "linker_mips.cpp",
- ],
- version_script: "linker.generic.map",
},
},
- // We need to access Bionic private headers in the linker.
- include_dirs: ["bionic/libc"],
-
// -shared is used to overwrite the -Bstatic and -static
// flags triggered by LOCAL_FORCE_STATIC_EXECUTABLE.
// This dynamic linker is actually a shared object linked with static libraries.
@@ -185,6 +210,57 @@
// just for this module
nocrt: true,
+ static_executable: true,
+
+ // Leave the symbols in the shared library so that stack unwinders can produce
+ // meaningful name resolution.
+ strip: {
+ keep_symbols: true,
+ },
+
+ // Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb
+ // looking up symbols in the linker by mistake.
+ prefix_symbols: "__dl_",
+
+ sanitize: {
+ hwaddress: false,
+ },
+}
+
+cc_binary {
+ defaults: ["linux_bionic_supported", "linker_defaults"],
+ srcs: [ ":linker_sources" ],
+
+ arch: {
+ arm: {
+ srcs: [ ":linker_sources_arm" ],
+ version_script: ":linker_version_script_arm",
+ },
+ arm64: {
+ srcs: [":linker_sources_arm64"],
+ version_script: ":linker_version_script",
+ },
+ x86: {
+ srcs: [":linker_sources_x86"],
+ version_script: ":linker_version_script",
+ },
+ x86_64: {
+ srcs: [":linker_sources_x86_64"],
+ version_script: ":linker_version_script",
+ },
+ mips: {
+ srcs: [":linker_sources_mips"],
+ version_script: ":linker_version_script",
+ },
+ mips64: {
+ srcs: [":linker_sources_mips64"],
+ version_script: ":linker_version_script",
+ },
+ },
+
+ // We need to access Bionic private headers in the linker.
+ include_dirs: ["bionic/libc"],
+
static_libs: [
"libc_nomalloc",
"libm",
@@ -202,7 +278,6 @@
// to overwrite any other malloc implementations by other static libraries.
"liblinker_malloc",
],
- static_executable: true,
name: "linker",
symlinks: ["linker_asan"],
@@ -218,20 +293,6 @@
},
},
compile_multilib: "both",
-
- // Leave the symbols in the shared library so that stack unwinders can produce
- // meaningful name resolution.
- strip: {
- keep_symbols: true,
- },
-
- // Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb
- // looking up symbols in the linker by mistake.
- prefix_symbols: "__dl_",
-
- sanitize: {
- hwaddress: false,
- },
}
cc_library {
diff --git a/linker/linked_list.h b/linker/linked_list.h
index 048ea4d..7f70a2c 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -84,7 +84,7 @@
clear();
}
- LinkedList(LinkedList&& that) {
+ LinkedList(LinkedList&& that) noexcept {
this->head_ = that.head_;
this->tail_ = that.tail_;
that.head_ = that.tail_ = nullptr;
diff --git a/linker/linker_memory.cpp b/linker/linker_memory.cpp
index 6a54c13..f2cce01 100644
--- a/linker/linker_memory.cpp
+++ b/linker/linker_memory.cpp
@@ -80,7 +80,15 @@
return get_allocator().realloc(p, byte_count);
}
+void* reallocarray(void* p, size_t item_count, size_t item_size) {
+ size_t byte_count;
+ if (__builtin_mul_overflow(item_count, item_size, &byte_count)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+ return get_allocator().realloc(p, byte_count);
+}
+
void free(void* ptr) {
get_allocator().free(ptr);
}
-
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 4161c90..c4f13f6 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -26,6 +26,12 @@
#include "private/bionic_config.h"
+#if defined(__BIONIC__)
+#define HAVE_REALLOCARRAY 1
+#else
+#define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
+#endif
+
TEST(malloc, malloc_std) {
// Simple malloc test.
void *ptr = malloc(100);
@@ -497,3 +503,31 @@
// mallopt doesn't set errno.
ASSERT_EQ(0, errno);
}
+
+TEST(malloc, reallocarray_overflow) {
+#if HAVE_REALLOCARRAY
+ // Values that cause overflow to a result small enough (8 on LP64) that malloc would "succeed".
+ size_t a = static_cast<size_t>(INTPTR_MIN + 4);
+ size_t b = 2;
+
+ errno = 0;
+ ASSERT_TRUE(reallocarray(nullptr, a, b) == nullptr);
+ ASSERT_EQ(ENOMEM, errno);
+
+ errno = 0;
+ ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
+ ASSERT_EQ(ENOMEM, errno);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
+#endif
+}
+
+TEST(malloc, reallocarray) {
+#if HAVE_REALLOCARRAY
+ void* p = reallocarray(nullptr, 2, 32);
+ ASSERT_TRUE(p != nullptr);
+ ASSERT_GE(malloc_usable_size(p), 64U);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
+#endif
+}